Twitter Facebook RSS Feed

lunes, 07 de septiembre de 2009 a las 16:42hs por Dario Krapp

En más de una ocasión nos fue necesario importar datos en formato CSV a una tabla en nuestro servidor de base de datos SQL Server, después de esta última vez me pareció una buena idea hacer un muy breve comentario de una de las posibilidades disponibles, así es que presento al comando BULK INSERT, el cual permite llevar a cabo esta operación.
Antes que nada debemos suponer que poseemos la siguiente tabla:

Tabla de ejemplo
El siguiente archivo CSV:

1,Cabecera1,20001211,20001211 22:10:30,41422.66, 22.22
2,Cabecera2,20001212,20001212 22:10:32,1234567.123456, 22.4444

Y la clara intención de copiar la información desde el archivo CSV hacia la tabla en cuestión. Deberemos entonces utilizar el siguiente comando:

BULK INSERT
	Cabecera
FROM
	'C:\....\archivo.csv'
WITH (
    FIELDTERMINATOR= ',',
    ROWTERMINATOR = '\n'
);

Donde hemos especificado origen (el path al archivo CSV) destino (la tabla Cabecera) y los separadores de filas y columnas en los argumentos ROWTERMINATOR y FIELDTERMINATOR.

El resultado de la operación generará el siguiente resultado:

Ejecución del comando SELECT luego del BULK INSERT
Donde puede verse que los datos han sido agregados aunque algunos de ellos (IngresoAnual y Numero) han quedado truncados en la tabla Cabecera al no poder ser representados en forma completa en los tipos de datos destino. Si se produce algún error de conversión de datos durante la importación la fila será omitida, el mismo comportamiento utilizará el comando si se viola la constraint NOT NULL.
En otros tipos de errores, como por ejemplo, violación de la constraint UNIQUE, la importación fallará, cabe mencionar que para el caso particular de las constraints CHECK y FOREIGN KEY, las mismas serán por defecto omitidas, al menos que se utilice el parámetro CHECK_CONSTRAINTS en la sentencia BULK INSERT para especificar lo contrario.
El comando BULK INSERT posee además de los pocos parámetros que hemos visto una diversa cantidad de los mismos, como por ejemplo FIRSTROW y LASTROW que permite especificar la fila inicial y final de copia, FIRE_TRIGGERS que permite indicar si se dispararán los triggers de las tablas durante la importación de datos, KEEPIDENTITY que permite especificar de qué manera se manejarán la columnas identity durante la importación y KEEPNULLS que indica si las columnas vacías deberán conservar el valor NULL.
Dejo para quien este interesado el siguiente link donde podrán obtener más información del comando, de todos los argumentos disponibles (que son muchos más que los que hemos mencionado) y de su uso:

http://technet.microsoft.com/es-es/library/ms188365.aspx

Espero que esta pequeña contribución haya servido para quienes no conocieran la existencia de este comando.

25 comentarios »

  1. Rikku dice:

    Buenas,
    Gracias por facilitar información sobre la sentencia BULK INSERT aunque me surge la siguiente duda:

    Imagina que mi tabla no tiene la misma estructura que el fichero del que quiero realizar la importación, por ejemplo que tenga muchos menos campos y en otro orden.

    ¿Cómo podría especificarle al BULK INSERT qué columna del fichero corresponde a qué campo de la tabla en la base de datos?

    Un saludo y muchas gracias de antemano

  2. […] Importación de archivos CSV con el comando Bulk Insert […]

  3. Pedro dice:

    Hola muy buena la info, tengo una consulta en mi archivo csv tengo un campo descripción el cual posee el siguiente texto «luces, lamparas». Forman parte de la misma columna pero como en el medio tiene una coma me lo transforma en 2 columnas. Como puedo salvar este problemas

    Muchas gracias!

  4. Gus dice:

    Excelente y muy claro!

  5. Juan dice:

    Cómo se utiliza o se dice para q importe desde la segunda fila. El txt a cargar tiene cabeceras

  6. Marcelo Arancibia Pinto dice:

    FIRSTROW =2

  7. carlos linares dice:

    hola, estoy intentando usar el FIRSTROW =2 ya que mi primera fila del txt es mi encabezado y luego vienen los registro, utilizo el FIRSTROW =2 y me omite la pirmera fila (encabezado) y la segunda fila que es mi primer registro por lo que se empieza a cargar la tabla desde el segundo registro, como hago para que salga bien?. esto se debe a que mi primera fila no cumple con los campos de la tabla de los registros entonces no la toma en cuenta a la hora de saltar la fila. Como puedo hacer para que funcione bien lo que quiero?

  8. Bryan Edgar dice:

    Excelente informacion.. Una duda .. si mi archivo de texto tiene como separadores un espacio en blanco (Tab) la sentencia de FIELDTERMINATOR como seria ?
    FIELDTERMINATOR= ‘ ‘ … solo se dejaria un espacio en blanco

    • Hola Bryan.
      Estoy «casi» seguro que funciona con FIELDTERMINATOR = '\t'.
      Después comentame si te funcionó.
      ¡Suerte!

      • Bryan Edgar dice:

        Si sirvió Amigo muchas gracias. Ahora tengo un problema .. tengo un poco mas de un millon de registros y una linea del registro tiene información errónea .. Existe alguna forma de saltarse esa linea y que continué la carga ?

  9. Erika Echeverri dice:

    Como hago si son varios archivos de cvs para que se me carguen diariamente automáticamente al sql?

  10. Esteban Nano dice:

    Favor re-acomodar las dimensiones de su página web, el contenido esta perfecto, pero es una molestia para los ojos al leerlo. Agradezco su atención.

  11. CABRARO MARIA LAURA dice:

    Hola, buen dia. Si tengo un CSV delimitado por ; (punto y coma) y dentro del texto de un campo tengo datos como «hola; chau» y no tengo posibilidad de modificar el delimitador de campos, podrìa especificar de alguna forma que lo que està dentro de » » no se debe tomar como tal?
    Estoy trabajando con Sql Server 2014 (Vi que para versiones mas nuevas si hay opciones)

  12. freyder ortega dice:

    Buen dia
    Una pregunta,estoy tratando de pasar la ruta del archivo por medio de parametro pero no ha sido posible, saca el error de que el archivo no existe, ejemplo, donde dice from, le coloco »+@ruta+», no me da pasandole la ruta por parametro, como hago?

  13. Carina dice:

    Mucha gracias por la información. Tengo una consulta: Si quisiera cargar solamente la primer fila (ya que en esa fila me indica ciertos datos que corresponden a la cantidad de registros del archivo), como puedo hacer para cargar solamente ese registro e ignorar el resto. Aclaro que la primer fila solo tiene 2 campos y el resto 6.

    Gracias.

  14. Lizzie dice:

    Hola! Yo intento hacer la carga de mi txt delimitado por | pero al llegar la siguiente fila la carga en la misma columan:(

    INSERT #test1 
    FROM 'C:\Excel\xX\Prueba\rh_cat_empleado.txt'
    WITH
    (
    FIELDTERMINATOR = '|',
    ROWTERMINATOR =  '\n'
    )
  15. Alejandro Quintero dice:

    Quiero hacer un bulk insert pero quiero obviar la primera columna ya que es una columna que no esta en el archivo csv alguien que me ayude por favor.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Buscar