Roberto Carrancio

Mi nombre es Roberto Carrancio y soy un DBA de SQL server con más de 10 años de experiencia en el sector. Soy el creador del blog soydba.es donde intento publicar varios artículos a la semana (de lunes a viernes que los fines de semana me gusta estar con mi gente y disfrutar de mi moto) Espero que disfrutes leyendo este blog tanto como yo disfruto escribiendo y que te sea de utilidad. Si tienes alguna sugerencia, pregunta o comentario, puedes dejarlo al final de cada entrada o enviarme un correo electrónico. Estaré encantado de leerte y responderte. ¡Gracias por tu visita! Mi principal interés es compartir mi conocimiento sobre bases de datos con todo el que quiera aprenderlo. Me parece un mundo tan apasionante como desconocido. Fuera de lo profesional me encanta la cocina, la moto y disfrutar de tomar una cervecita con amigos.
Mi nombre es Roberto Carrancio y soy un DBA de SQL server con más de 10 años de experiencia en el sector. Soy el creador del blog soydba.es donde intento publicar varios artículos a la semana (de lunes a viernes que los fines de semana me gusta estar con mi gente y disfrutar de mi moto) Espero que disfrutes leyendo este blog tanto como yo disfruto escribiendo y que te sea de utilidad. Si tienes alguna sugerencia, pregunta o comentario, puedes dejarlo al final de cada entrada o enviarme un correo electrónico. Estaré encantado de leerte y responderte. ¡Gracias por tu visita! Mi principal interés es compartir mi conocimiento sobre bases de datos con todo el que quiera aprenderlo. Me parece un mundo tan apasionante como desconocido. Fuera de lo profesional me encanta la cocina, la moto y disfrutar de tomar una cervecita con amigos.

Índices Clustered y Primary Keys (Índices parte 3)

En esta tercera entrega de nuestra serie de índices vamos a hablar de los índices clustered. Para entender lo que vamos a ver tenemos que tener claro de antemano lo que vimos en la primera y la segunda entrada de esta serie. Si aún no lo has leído es el momento, para aquí mismo y vuelve cuando lo hayas hecho. 

Bien, ahora que ya tenemos todos leídas la primera y la segunda entrega vamos a empezar. Analizaremos en profundidad las características de los índices clustered, buenas prácticas y veremos además lo que es una PK.

Índices Clustered en SQL Server

Recordemos lo que comentamos en la introducción, un índice clustered es en realidad toda la tabla ordenada por las columnas que componen el índice. Por este motivo solo puede haber un índice clustered por cada tabla. No tiene más restricciones que esa a menos que se las añadamos nosotros. Admite nulos y duplicados, aunque no es recomendable y luego veremos por qué. 

Comparemos con lo que vimos de las tablas HEAP que teníamos un IAM que nos decía dónde empezaba la información. En los índices clustered también tenemos una estructura por encima que nos dice dónde está la información aunque en este caso es una estructura por niveles llamada de árbol invertido o árbol B. En los árboles partimos de un tronco abajo que se va bifurcando en ramas hasta terminar en las hojas arriba, pues nuestro árbol invertido es igual, partimos de un nivel superior que se va separando por niveles hasta terminar en todas las páginas abajo. Sería algo similar a lo que podemos ver en la siguiente imagen:

En este caso tenemos una tabla con un índice clustered por un campo numérico. Nuestro índice entonces crea una estructura de árbol B desde un nivel raíz hasta ir bajando y llegar a las páginas con los datos. Aunque en el ejemplo lo he querido simplificar, lo normal será tener más de un registro en cada una de las páginas finales. Estas páginas son del tipo IN_ROW_DATA y los registros estarán ordenados por el campo numérico del índice. Además, igual que en las tablas HEAP, tendremos también páginas LOB_DATA y ROW_OVERFLOW_DATA para los datos grandes.

Ordenación de los datos

En el párrafo anterior os he mentido un poco, los que teneis un nivel más avanzado os habréis dado cuenta. No me dejéis todavía un comentario negativo por favor, vamos a verlo. Os he dicho que los datos se guardan en las páginas ordenados por el campo que forma parte del índice, esta es la teoría y es como debe de estar pero no siempre es así.
Cuando insertamos un dato SQL se va a posicionar en el sitio donde deberá escribirlo y va a verificar si hay o no espacio, si hay espacio perfecto pero, si no lo escribirá donde pueda. Lo mismo ocurre si actualizamos el campo indexado. Esto se llama fragmentación de los índices y es el motivo por el que nuestros índices necesitan mantenimiento. Podríamos hablar ahora del Fill Factor de los índices y de su mantenimiento pero ambas cosas llegarán más adelante en esta serie. De momento con saber esto nos vale.

Buenas prácticas en los índices clustered

Este problema de la fragmentación es por lo que al principio os decía que no es recomendable crear un índice clustered por campos que admiten nulos o duplicados. Pero además existen otras características que identifican un buen índice clustered, debe ser corto, estático e incremental. Es fácil de explicar, cuanto más corto sea menos nos costará buscar y ordenar. Dado que una actualización nos generará fragmentación también debe de ser algo que no cambie nunca, es decir estático. Que sea incremental se entiende también en clave de evitar la fragmentación pues si siempre aumenta siempre escribiremos después de lo que ya existe.

Índices Primary Key

Cuando hablamos de un índice clustered que no admite duplicados en un campo que no admite nulos muchos de vosotros pensaréis automáticamente en una PK (Primary Key o clave primaria). Esto no es del todo correcto, es cierto que una PK por defecto tiene un índice clustered y que no admite nulos, pero no es lo mismo. 

Una PK es el identificador único de los registros de nuestra tabla, por tanto es una restricción lógica en la que una columna no admite valores nulos ni duplicados. Que sea una restricción lógica significa que para poder implementarse a nivel físico necesita de un índice. Mientras no definamos nosotros lo contrario será un índice clustered. Pero puede que a nosotros nos interese que nuestra tabla se ordene por otro campo y crear la PK sobre un índice nonclustered. 

Índices Clustered vs Primary Keys

Ahora ya sabemos que un índice clustered no es lo mismo que una PK, la PK es una restricción lógica que debe reforzarse con un índice físico que puede ser clustered o nonclustered. Entonces, la pregunta sería: ¿Cuándo debo usar una PK clustered y cuándo una nonclustered? 

Imaginemos que estamos buscando la mejor manera de crear un índice clustered y una PK para nuestra tabla de personas. Tenemos unos datos como nombre, primer apellido, segundo apellido y NIE/DNI. Sabemos que una PK no admite valores nulos ni duplicados y conocemos las buenas prácticas sobre índices clustered. En base a esto decidimos que la PK de nuestra tabla sea el DNI ya que no puede estar vacío y es un valor único, pero ¿es un buen índice clustered? Es corto, una sola columna y de menos de 10 caracteres pero ni es incremental ni es estático (un número NIE cambiará a DNI durante el proceso de residencia de un ciudadano extranjero). Es por esto que no es un buen candidato a índice clustered y lo mejor será crear un campo ID incremental que identifique inequívocamente a las personas de nuestra tabla.

Conclusión

Hoy hemos aprendido aspectos importantísimos sobre los índices clustered y las primary keys. Hemos visto que no siempre son lo mismo y en ocasiones puede interesarnos más una PK con un índice nonclustered. Sin embargo, aún no hemos hablado en profundidad de los índices nonclustered. Eso será en el próximo artículo, estad atentos

Contenido de la serie

Introducción a los índices en SQL Server (Índices parte 1)

Estructura física de las tablas y HEAP (Índices parte 2)

Índices Nonclustered (Índices parte 4)

Índices Columnares (Índices parte 5)

Índices especiales (Índices parte 6)

Publicado por Roberto Carrancio en Índices, Rendimiento, SQL Server, 7 comentarios

Estructura física de las tablas y HEAP (Índices parte 2)

Seguimos con nuestra serie de índices en SQL Server y vamos a profundizar en la estructura de las tablas que vimos ayer. Además vamos a introducir conceptos nuevos como las particiones y las tablas HEAP. Antes de continuar, si aún no lo habéis hecho, os recomiendo leer la primera entrega de esta serie de índices donde hicimos una introducción y aclaramos los conceptos básicos sobre los que vamos a profundizar ahora. 

Estructura física de las tablas

Como vimos en la introducción las tablas son en realidad la representación de los datos almacenados en páginas de 8Kb de información. Pero por encima de estas páginas tenemos una estructura lógica que indica dónde se ubican los datos. Del mismo modo, podemos definir particiones, que son divisiones horizontales físicas en función de los valores de una columna. 

estructura indices

Como podéis ver en la imagen nuestra tabla, tenga o no particiones, sea HEAP o tenga un índice clustered se compone de páginas del tipo IN_ROW_DATA, LOB_DATA y ROW_OVERFLOW_DATA. 

IN_ROW_DATA almacena la mayoría de la información de nuestras filas. Hay tipos de datos especiales que por su gran tamaño no caben en las páginas de datos y se almacenan en LOB_DATA. Por último, cuando definimos una columna que de longitud variable se almacenará en IN_ROW_DATA siempre que sea posible y cuando por tamaño no se pueda irá a una página tipo ROW_OVERFLOW_DATA.

Tablas HEAP

Como vimos, cuando escribimos en una tabla HEAP los datos se escribirán en el primer hueco libre en las páginas ya asignadas. Si no hay hueco disponible se creará una nueva página. Además se asignará un identificador único a cada fila conocido como RID. Aunque no existan índices, SQL necesita localizar donde se encuentran las páginas de una tabla HEAP y para ello hace uso de un IAM o mapa de asignación de índices. El IAM almacena la ubicación de las páginas que componen la tabla pero, no identifica de ninguna manera los RID. Para buscar una fila SQL Server irá al IAM y recorrerá secuencialmente todos los registros de todas las páginas enlazadas al IAM. Como podéis adivinar, esto no es nada bueno en términos de rendimiento, sin embargo no es el peor de los problemas de las tablas HEAP. 

Redirección de Punteros

Cuando se modifica un registro de una tabla HEAP es posible que la nueva información no quepa en el espacio que tenía asignada esa fila. En este caso, no se mueve toda la fila a una nueva ubicación sino que ese registro se escribe en otro sitio y en su ubicación original se deja un puntero hacia la nueva ubicación.
Esto complica mucho la lectura, pues para buscar una fila, SQL Server leerá la primera página del IAM que le dirá donde está la primera página de datos. Leerá secuencialmente toda la página de datos hasta que se encuentre termine, irá al IAM a buscar las siguientes páginas y hará lo mismo. Cuando termine con las páginas de datos referenciadas en la primera página del IAM irá a la siguiente página del IAM y habrá lo mismo. Así todas las veces que sea necesario hasta leer completamente la tabla. Por el camino se encontrará punteros que apuntan a páginas LOB, Overflow o simplemente a otras páginas con datos que se han actualizado y no cabían en la ubicación original. 

Si esto os parece un problema pensad en los discos duros mecánicos donde una aguja se va moviendo físicamente para posicionarse en la posición correcta del disco y así leer los datos. Una locura, ¿verdad? Es mejor tener nuestras tablas ordenadas y para eso vamos a usar los índices clustered. Pero esto lo veremos en profundidad en el próximo artículo, mientras, podéis dejarme vuestras dudas y comentarios abajo, por Twitter o mail.

Contenido de la serie

Introducción a los índices en SQL Server (Índices parte 1)

Índices Clustered y Primary Keys (Índices parte 3)

Índices Nonclustered (Índices parte 4)

Índices Columnares (Índices parte 5)

Índices especiales (Índices parte 6)

Publicado por Roberto Carrancio en Índices, Rendimiento, SQL Server, 9 comentarios

Introducción a los índices en SQL Server (Índices parte 1)

Vamos a empezar con una serie de varios artículos sobre los índices en SQL Server, un aspecto fundamental en nuestra base de datos que marcará todo su funcionamiento. A lo largo de los próximos días vamos a profundizar en este tema partiendo desde lo más básico. Empezaremos viendo las estructuras fundamentales de las tablas, lo que nos llevará a adentrarnos en los principales tipos de índices. Esos conocimientos nos ayudarán a entender el resto de índices y cómo afectan al rendimiento de nuestra base de datos. La mejor parte es que al final de la serie habremos aprendido cómo mejorar y optimizar nuestros índices y por tanto, las consultas que leen datos de esas tablas.

Estructura de una tabla en SQL Server

Como a estas alturas ya sabréis, en SQL Server los datos se almacenan en tablas con columnas y filas. Lo que ya no todo el mundo sabe es que estas tablas a su vez se almacenan en páginas de 8 kb. Cada una de estas páginas es una unidad indivisible, son los átomos de nuestra base de datos. Todas nuestras tablas tendrán al menos una página y será exclusiva. Esto es importante, cada página sólo contendrá datos de un solo objeto (tabla o índice). A medida que nuestras tablas crezcan irán ocupando más y más páginas pero siempre con estos requisitos que hemos comentado. Cuando se borren datos ese espacio se quedará libre pero no se liberará, estará reservado para almacenar futuros datos de esa tabla. 

La tabla más básica que podemos crear se llama HEAP (montón traducido literalmente). Será una tabla donde los datos que escribimos se van añadiendo en el primer espacio libre que encuentre en las páginas sin ningún orden. Empezará llenando secuencialmente el espacio de las páginas pero cuando quede espacio libre por algún borrado se añadirá ahí.

Índices Clustered en SQL Server

Lo contrario a una tabla HEAP es una tabla con un índice clustered (agrupado). Los datos se escribirán en páginas, ordenados siempre por la columna (o las columnas) del índice clustered. Como si de un diccionario se tratase, SQL Server sabe cual es el primer y el último dato de cada página, lo que facilita en gran medida las búsquedas por estas columnas. Como se trata de la propia ordenación de los datos sólo puede haber un índice clustered por cada tabla.

Índices Nonclustered en SQL Server

Los índices nonclustered (no agrupados) son un objeto separado de la tabla, sólo incluyen algunas de las columnas y se almacenan en páginas separadas. Un índice nonclustered será por tanto una copia de la tabla original con solo parte de las columnas y ordenado de manera diferente. Tenga una tabla un índice clustered o sea un HEAP podremos crear tantos índices nonclustered como queramos.

¿Cómo lee los datos SQL Server?

Con lo que ya sabemos nos podemos hacer una idea de como SQL Server va a acceder a la información que tenemos almacenada y empezar a comprender la importancia de los índices. Vamos a empezar con una tabla HEAP como la que bajo estas líneas (podéis ampliar la imagen haciendo click en ella): 

Como veis tenemos una tabla de personas con un ID, nombre, apellido y una fecha de modificación. Supongamos que tenemos que buscar la fecha de modificación del usuario número 2, ¿cómo lo haríais vosotros?. Pensadlo un momento. Si habéis pensado en empezar a leer la columna id hasta llegar al 2 y después recorrer horizontalmente la tabla hasta la columna fecha de modificación, felicidades habéis pensado como SQL Server. Ahora bien, esta no parece la forma más efectiva de consultar información, ¿verdad?. ¿Y si la tabla en vez de 20 tuviera 20.000 registros? ¿Y 20.000.000? Lo mejor será crear un índice clustered por el campo ID para así tenerlo ordenado, ¿no creéis?

Como hemos comentado el índice clustered es la propia tabla ordenada por lo que tendremos todos los datos igual que en nuestra tabla HEAP pero ordenados por la columna ID en este caso.

Ahora es mucho más fácil buscar los datos de una persona si nos dan su ID, ¿a que si?. Pero, ¿qué pasaría si la pregunta ahora fuese por la fecha de modificación de los usuarios que se llaman Gigi? Tendríamos el mismo problema que antes, deberíamos recorrer la columna nombre hasta encontrar el que buscamos. Es incluso peor cuando estamos hablando de datos que no son únicos, aunque hayamos encontrado un Gigi puede ser que haya más, no lo sabremos hasta que no terminemos con toda la tabla. Es entonces el momento de crear un índice nonclustered por el nombre y el id para ayudarnos en esta tarea. Veámoslo:

Ahora si, podemos consultar nuestro índice nonclustered hasta ver que Gigi es el ID 9 y que el siguiente registro ya tiene otro valor por lo que solo hay una persona que se llama así. Usaremos nuestro índice nonclustered para encontrar el ID y luego en nuestro índice clustered iremos directamente al registro que necesitamos. 

Si en este punto pensáis que os lleva más trabajo mirar primero el índice nonclustered y después el clustered que directamente leer todo el índice clustered que solo tiene 20 registros no os preocupeis, SQL piensa igual. Los índices no se usan en tablas pequeñas, aunque existan. En esos casos siempre va a tardar menos en leer la tabla entera que en usar los índices. Pero esto lo veremos más adelante, queda mucha serie de índices, veremos cosas nuevas y profundizaremos en lo que hemos visto. Estad atentos. 

Contenido de la serie

Publicado por Roberto Carrancio en Índices, Rendimiento, SQL Server, 6 comentarios

Prevenir usuarios huérfanos

En el anterior post aprendimos lo que eran y cómo corregir el problema de usuarios huérfanos, sin embargo, como es mejor prevenir que curar, vamos a aprender cómo prevenir el problema.

A modo de resumen, un usuario huérfano es el que no está relacionado con un login. Esto es muy común cuando movemos bases de datos entre diferentes servidores o cuando tenemos un sistema de alta disponibilidad que replica las bases de datos como el Always On o el Log Shipping. Aunque tengamos logins con el mismo nombre en ambos servidores no tienen el mismo SID. Como ya habréis podido adivinar para no tener más este problema deberemos asignar al login el mismo SID, pero esto solo se puede hacer recreando el login.

Averiguar el SID de un usuario por script

Lo primero que haremos será crear el login normalmente en uno de los servidores. Si ya tenemos los logins creados en ambos servidores lo borraremos de uno de ellos. Con el login creado en solo uno de los servidores usaremos este script para ver el SID:

select name, sid from sys.sql_logins

Copiaremos el sid de nuestro login y cuando vayamos a crearlo en el otro servidor le indicaremos que use ese SID de la siguiente manera

CREATE LOGIN batman WITH PASSWORD = 'G0th@m', SID = 0x8FB57BD6DA61BA40ABAB2A41DDC91A41

Scriptar la contraseña

En el ejemplo anterior hemos creado un login con un SID concreto y una contraseña. Hemos podido hacer esto porque conocíamos la contraseña del usuario pero, en la vida real, esto no siempre es tan bonito. Con SQL no vamos a poder ver las contraseñas de los usuarios en texto plano pero, esto tampoco significa que no podamos hacer nada. Usando la misma vista de antes sys.sql_logins podemos obtener la contraseña cifrada.

select name, sid, password_hash from sys.sql_logins

Con el HASH de la contraseña y el SID recrearemos el login de la siguiente manera:

CREATE LOGIN batman WITH PASSWORD = 0x0200B240435023921FCBA909DCF2136C27F81D0A4BEADBFBB5286E0511C8CF490BFAB9002EE881A8E7423195571D933AB189A9CB3EB5109C78A0789436811F6C833D8233B8B6 HASHED , SID = 0x8FB57BD6DA61BA40ABAB2A41DDC91A41

Copia masiva de logins

Para recrear varios inicios de sesión de golpe podemos hacer uso del procedimiento almacenado sp_help_revlogin. Para poder usarlo primero copiaremos el código del procedimiento desde la web oficial de Microsoft y lo ejecutaremos en nuestra instalación. Con ejecutar el procedimiento tendremos el script para recrear todos los logins con el mismo SID y contraseña.

Conclusión

Hemos aprendido cómo saber el SID y la contraseña cifrada de nuestros logins para transferirlos a otros servidores sin miedo a generar usuarios huérfanos. Esto es muy útil cuando mueves bases de datos entre servidores de manera periódica, como cuando refrescas un servidor de preproducción pero es imprescindible en instalaciones de alta disponibilidad donde en caso de balanceo tiene que ser transparente para los usuarios.

Publicado por Roberto Carrancio en SQL Server, 1 comentario
Usuarios Huérfanos en SQL Server

Usuarios Huérfanos en SQL Server

Uno de los problemas más comunes cuando restauramos una base de datos de otro SQL es el de los usuarios huérfanos, vamos a ver por qué sucede y cómo solucionarlo. Antes de empezar quiero pedir perdón por el chiste malo de la foto de portada. Una vez hecho vamos a ver un poco de teoría para entender el por qué del problema y veamos como solucionarlo.

Usuarios y Logins en SQL Server

Tenemos que diferenciar los logins para acceder al servidor de los usuarios de bases de datos. Es un poco complicado, pero cuando nosotros creamos un login (inicio de sesión) sólo tendrá acceso a SQL Server sin acceder a las bases de datos. Para acceder a las bases de datos necesitaremos un usuario creado en esa base de datos y enlazado al login del servidor. 

En SQL Server tenemos dos tipos de usuarios, usuarios de windows y usuarios de SQL. Esos usuarios tienen un nombre que vemos y un identificador único con el que trabaja SQL Server. En el caso de los usuarios de windows se usa el identificador (SID) de windows (gestionado por el directorio activo o por el equipo). En el caso de los usuarios de SQL se creará un SID para el login y se usará ese mismo SID para crear un usuario en las bases de datos a las que se conceda acceso.

Usuarios huérfanos 

Sabiendo ya la diferencia entre usuarios y logins es sencillo entender el problema. Un usuario huérfano es un usuario sin login asociado. Como hemos comentado esto es muy común a la hora de mover bases de datos de un servidor a otro, pues aunque tengan los mismos usuarios lo normal es que no tengan los mismos SID. Puede pasar también en un mismo servidor, por ejemplo si borramos un login, lo volvemos a crear y no borramos los usuarios para recrearlos desde el nuevo login. 

Arreglar usuarios huérfanos

Cuando nos encontramos con este error, no podremos dar permisos al login sobre la base de datos porque aunque no tengan el mismo SID ya hay un usuario con ese nombre y los nombres de usuario deben ser únicos. La solución tampoco sería borrar el usuario para crearlo desde la ventana de logins porque perderíamos todos los permisos asignados en la base de datos y habría que volver a hacer ese trabajo. Para cuando esto pasa, SQL Server tiene una herramienta, en forma de procedimiento almacenado de sistema que localiza y corrige los usuarios huérfanos. 

Ejemplo

Como veréis en las siguientes capturas, en mi base de datos de pruebas tengo los usuarios Batman, Spiderman, Harry Potter y Superman pero en el servidor solo tengo el login Spiderman. Todos los usuarios de base de datos son huérfanos, los 3 primeros porque no existe su login padre y Superman porque, aunque existe, no están enlazados.

Localizar usuarios huérfanos

Usaremos el procedimiento almacenado con el parámetro report para localizar los usuarios huérfanos.

EXEC sp_change_users_login 'Report'

Como era de esperar el resultado del reporte nos muestra nuestros cuatro usuarios huérfanos.

Usuario y login existentes sin relación

Para corregir el problema usaremos el procedimiento almacenado con el parámetro Auto_Fix. En caso de que exista un login con el mismo nombre que nuestro usuario bastará con poner el nombre del usuario y se enlazarán.

EXEC sp_change_users_login 'Auto_fix', 'superman'

No existe el login

Cuando no exista un login con el mismo nombre podremos usar también el parámetro Auto_Fix, esta vez lo acompañaremos del nombre de usuario y la contraseña para el login que vamos a crear. 

EXEC sp_change_users_login 'Auto_fix', 'batman', NULL, 'BatContr@seña.123'

Conclusión

Hoy has aprendido qué son y por qué se producen los usuarios huérfanos y, lo más importante, como corregir este problema que es uno de los más comunes en bases de datos SQL Server. Como siempre para cualquier duda o sugerencia te emplazo dejarlo en los comentarios, mi email o nuestro twitter.

Publicado por Roberto Carrancio en SQL Server, 3 comentarios

Importar datos de Excel a SQL Server

Aunque como DBAs profesionales nos duela vamos a quitarnos la tirita de golpe desde el principio y acabemos con esto: Excel es uno de los software más usados para almacenar e intercambiar información. Lo sé, eso ha dolido, nos dedicamos a las bases de datos y tenemos un especial odio a las hojas de cálculo, pero es lo que hay. A lo largo de nuestra carrera nos encontraremos en muchas ocasiones con datos en Excel que tenemos que importar a la base de datos. Por suerte para nosotros, el SQL Server Management Studio (SSMS) incorpora un asistente de importación para hacernos la vida más fácil. 

Asistente de importación

A los que sois lectores del blog os sonará, pues ya lo hemos usado anteriormente para copiar datos entre tablas. Lo cierto es que el asistente de importación de datos es muy potente y nos permite tanto importar como exportar datos desde y hacia gran cantidad de sistemas. Realmente es una herramienta basada en SSIS (Integration Server) que simplifica en gran medida su uso para labores sencillas de movimiento de datos. Al estar basado en SSIS nos permitirá guardar el paquete dtsx para ejecutarlo en otro momento e incluso programarlo. Pero tranquilos, no nos va a exigir tener instalado ni corriendo el servicio de SSIS en nuestro servidor. Veamos cómo funciona

Importar datos de Excel

El asistente de importación nos permite importar datos de nuestro origen de datos a SQL Server, aunque hoy vamos a usarlo para importar desde excel tenéis que saber que se puede usar también para importar ficheros csv, todo tipo de archivos de texto plano y o de bases de datos. Si queréis reproducir este ejemplo en vuestra instalación de pruebas al final del artículo encontraréis un link de descarga al documento que he usado yo.

Abriremos el asistente de importación de datos haciendo click derecho sobre nuestra base de datos, tareas y a continuación importar datos. Una vez pasada la ventana de bienvenida al asistente seleccionaremos como origen de datos nuestro archivo Excel y como destino nuestra base de datos. Seleccionaremos copiar datos de una o varias tablas y continuaremos. En este momento podemos cambiar el esquema y el nombre de la tabla destino, podemos seleccionar una tabla existente o crear una tabla nueva. En el botón de editar mapeos podremos definir el tipo de datos de nuestra tabla en caso de que haya que crearla. Si existe tendremos otras opciones como borrar su contenido antes de cargar o añadir los datos a los existentes.Confirmaremos estos cambios y pasaremos a la siguiente ventana donde podremos elegir si ejecutar inmediatamente o guardar el paquete dtsx. Con todo esto estaremos listos para cargar los datos, podemos dar a finalizar y esperar a que termine.

Conclusiones

El asistente de importación y exportación de SSMS es muy potente. No te quedes solo con este ejemplo, prueba distintos tipos de importación, exporta tus tablas a excel o a ficheros de texto plano y gana soltura, cuando tengas que hacerlo lo agradecerás. Como siempre, si tienes cualquier duda puedes dejarla en los comentarios, mail o twitter.

Descarga el archivo de ejemplo: 

Publicado por Roberto Carrancio en SQL Server, 2 comentarios
Restaurar sólo una tabla en SQL Server

Restaurar sólo una tabla en SQL Server

Ayer vimos con detalle cómo restaurar una base de datos en SQL Server, sin embargo, en muchas ocasiones lo que necesitaremos es restaurar solo una tabla. El motivo más común para tener que restaurar una copia de seguridad es por un fallo humano a la hora de modificar datos, por lo que necesitaremos restaurar una o varias tablas pero no toda nuestra base de datos. Lamentablemente SQL Server no ha desarrollado aún (finales de 2023) ninguna funcionalidad para hacer esto de forma fácil y eficiente. Mientras esto no pase, vamos a ver paso a paso cómo podemos hacer para recuperar nuestra tabla a un momento anterior.

Preparación del entorno

Para las pruebas voy a usar la base de datos StackOverflow2013. Esta es una base de datos de ejemplo, pero podéis usar cualquier base de datos de pruebas que tengáis.

Tomaré como ejemplo esta tabla

Aplicaré estas 2 sentencias para cambiar los datos:

delete from [dbo].[VoteTypes] where id > 3
update [dbo].[VoteTypes] set Name = 'Closed'

Restaurar: Paso 1

Como hemos dicho lo primero que tenemos que hacer es restaurar una copia de la base de datos de antes de haber cometido el fallo. No sabemos que más operaciones legítimas se han hecho en la base de datos por lo que no podemos sobrescribir los datos. Restauraremos la base de datos con otro nombre para no pisar nada. Todo esto lo vimos en el post de ayer por lo que no nos vamos a detener más en este punto.

Restaurar: Paso 2

Una vez tengamos nuestra copia restaurada con otro nombre tendremos que mover los datos de la tabla a la base de datos original. Para eso podemos hacerlo con el asistente de copia de datos o mediante script, veámoslo.

Asistente de copia de datos

Nos situaremos sobre la base de datos original y abriremos el asistente desde el menú del botón derecho del ratón. Elegiremos como origen la base de datos restaurada, como destino la original y copiaremos los datos de la tabla borrando lo que contiene actualmente. Como la tabla del ejemplo contiene un campo IDENTITY nos aseguraremos de marcar el check para poder insertar en esos campos.

Script INSERT INTO

Para esta técnica también vamos a vaciar la tabla original. A continuación habilitaremos la inserción de campos IDENTITY para despues insertar los datos desde la tabla de la base de datos restaurada.

TRUNCATE TABLE [StackOverflow2013].[dbo].[VoteTypes]
GO

SET IDENTITY_INSERT [StackOverflow2013].[dbo].[VoteTypes] ON
GO

INSERT INTO [StackOverflow2013].[dbo].[VoteTypes] (id, name)
SELECT id, name FROM [StackOverflow2013_RESTORE].[dbo].[VoteTypes]
GO

Script MERGE

Muchas veces, solo unos pocos datos estarán mal y borrar y cargar la tabla entera no será una solución eficiente. En estos casos podremos usar MERGE para solo insertar los registros que faltan o actualizar solo los que no estén bien. Esta sería la sintaxis en nuestro caso:

SET IDENTITY_INSERT [StackOverflow2013].[dbo].[VoteTypes] ON
GO

MERGE [StackOverflow2013].[dbo].[VoteTypes] AS Destino
USING [StackOverflow2013_RESTORE].[dbo].[VoteTypes] AS Origen
ON Destino.ID = Origen.ID
WHEN NOT MATCHED BY Target THEN
INSERT (id, Name)
VALUES (Origen.ID, Origen.Name)
WHEN MATCHED AND Destino.Name <> Origen.Name THEN
UPDATE SET Destino.Name = Origen.Name ;
GO

Restaurar: Paso 3

Una vez que nuestra tabla vuelva a tener los datos correctos avisaremos a los usuarios para que lo confirmen. Si todo está ok, ya solo nos restaría borrar la base de datos restaurada para liberar ese espacio.

Conclusiones

Como hemos visto, restaurar una tabla es un proceso manual que tenemos que controlar.  Habrás notado que durante este artículo he sido bastante crítico con el hecho de que no haya una forma de restaurar una tabla de un archivo de copia de seguridad y seguramente vosotros estéis en la misma situación. Es normal, a día de hoy las restauraciones de tablas son la segunda petición a Microsoft más votada por los usuarios en la web de feedback de usuarios. Hace un año Microsoft confirmó tenerlo como una tarea pendiente para futuras versiones de SQL Server. Aun así, mientras esto no llegue, tenemos que conocer el procedimiento de memoria y estar familiarizados con él ya que es una labor crítica.

Cuando se pierden unos datos de producción, estamos sometidos a mucha presión y tenemos que dar una solución rápida y eficaz por lo que os recomiendo practicar esto que hemos visto en diferentes situaciones. De esta manera, el día que os toque lidiar con ello, será todo mucho más sencillo. 

Publicado por Roberto Carrancio en SQL Server, 2 comentarios