jueves, 14 de febrero de 2013

Extraer datos a csv desde Sql Server

Una manera bastante efectiva y muy rápida para enviar una gran cantidad de datos entre distintos sistemas de base de datos es utilizar ficheros csv.

La definición que da la Wikipedia de los ficheros csv es: 
Los ficheros CSV (del inglés comma-separated values) son un tipo de documento en formato abierto sencillo para representar datos en forma de tabla, en las que las columnas se separan por comas (o punto y coma en donde la coma es el separador decimal: España, Francia, Italia...) y las filas por saltos de línea. Los campos que contengan una coma, un salto de línea o una comilla doble deben ser encerrados entre comillas dobles.
Es decir, es un formato de fichero de texto plano en el que cada línea del fichero representa un registro de nuestra tabla o resultado de la consulta a exportar. Dentro de esa fila, cada campo está separada por una coma o punto y coma. Siendo en España más usado el ';'.

Tanto la exportación como la importación de datos en este tipo de fichero es extraordinariamente rápida. Además en caso de tener que transferirse por red, al ser ficheros de texto, permiten una gran compresión.

La exportación a estos ficheros se puede hacer directamente desde T-Sql, por lo que es posible, por ejemplo, hacer programaciones de exportaciones con un job de Sql Server.

La sentencia necesaria para hacer esta exportación sería la siguiente:

Declare @vchSql as nvarchar(4000)Declare @bcp as nvarchar(4000)
Set @vchSql = 'Select * From TABLA' 
Set @bcp = 'bcp "'+@vchSql+'" queryout D:\Exp\exp.csv -T -t; -c -C' 
exec master..xp_cmdshell @bcp 
Donde:

  • En la variable @vchSql se asigna la consulta a exportar
  • D:\Exp\Exp.csv es el fichero resultante. La ruta especificada debe ser local o accesible desde el servidor de Sql Server, ya que el proceso se ejecuta en el servidor.
  • En el parámetro -t se asigna el carácter de separación de campos, en este caso ;
  • El parámetro -C son necesarios para que exporte el contenido respetando tildes, eñes, etc.
Esta exportación se realiza sin cabecera. Para incluir  en el fichero una línea de cabecera con el nombre de los campos habría que realizar las siguientes acciones:
  1. Crear un fichero plantilla con la cabecera del fichero a generar.
    • Esta plantilla tendría que tener la línea de cabecera y una línea en blanco.
  2. Exportar el fichero con la sintaxis explicada arriba
  3. Copiar a la ruta final un fichero que sea la concatenación de la cabecera más el fichero exportado
Por tanto la sintaxis final sería:

Declare @vchSql as nvarchar(4000)Declare @bcp as nvarchar(4000)
Set @vchSql = 'Select * From TABLA' 
Set @bcp = 'bcp "'+@vchSql+'" queryout D:\Exp\exp.csv -T -t; -c' 
exec master..xp_cmdshell @bcp 
exec master..xp_cmdshell 'copy "D:\Exp\Template_header\template.csv" /B + "D:\Exp\exp.csv" /B \\serverDestino\carpetaDestino\export.csv'

NOTA: Es muy importante poner el parámetro /B en la copia/concatenación de los ficheros. Con este parámetro se fuerza a que la copia se haga en formato binario, de lo contrario lo copia en formato ASCII y por tanto incluye un salto de línea al final del fichero que hace que al importar el fichero generado con BULK INSERT falle.

2 comentarios:

  1. Amigo....!!! Esto me salvará el día puesto que mañana entra a producción y ya ... sabes REQUERIMIENTOS DE ÚLTIMA HORA!!! :\

    Voy a probarlo bro, muchas gracias.

    ResponderEliminar
  2. Me funciona de maravilla, pero cuando el fichero de datos es muy grande no realiza la fusión....a que se debe???? porque falla??? como soluciono eso????

    ResponderEliminar