Como realizar carga masiva de archivos con Sql Server 2008 R2 (Bulk Insert)

A continuación describiremos como realizar una carga masiva directamente desde sql server a través de un procedimiento almacenado (SP). Para este procedimiento utilizaremos una función de sql server llamada Bulk Insert cuya sintaxis es la siguiente:

BULK INSERT 
   [ database_name . [ schema_name ] . | schema_name . ] [ table_name | view_name ] 
      FROM 'data_file' 
     [ WITH 
    ( 
   [ [ , ] BATCHSIZE = batch_size ] 
   [ [ , ] CHECK_CONSTRAINTS ] 
   [ [ , ] CODEPAGE = { 'ACP' | 'OEM' | 'RAW' | 'code_page' } ] 
   [ [ , ] DATAFILETYPE = 
      { 'char' | 'native'| 'widechar' | 'widenative' } ] 
   [ [ , ] FIELDTERMINATOR = 'field_terminator' ] 
   [ [ , ] FIRSTROW = first_row ] 
   [ [ , ] FIRE_TRIGGERS ] 
   [ [ , ] FORMATFILE = 'format_file_path' ] 
   [ [ , ] KEEPIDENTITY ] 
   [ [ , ] KEEPNULLS ] 
   [ [ , ] KILOBYTES_PER_BATCH = kilobytes_per_batch ] 
   [ [ , ] LASTROW = last_row ] 
   [ [ , ] MAXERRORS = max_errors ] 
   [ [ , ] ORDER ( { column [ ASC | DESC ] } [ ,...n ] ) ] 
   [ [ , ] ROWS_PER_BATCH = rows_per_batch ] 
   [ [ , ] ROWTERMINATOR = 'row_terminator' ] 
   [ [ , ] TABLOCK ] 
   [ [ , ] ERRORFILE = 'file_name' ] 
    )]

Pero para efectos prácticos solo utilizaremos la siguiente estructura:


BULK INSERT 
   [ database_name . [ schema_name ] 
      FROM 'data_file' 
     [ WITH 
    ( 
      [ BATCHSIZE = batch_size ] 
      [ [ , ] FORMATFILE = 'format_file_path' ] 
    )]

Para este proceso debemos tener un archivo de formato, nuestro archivo de carga y obviamente nuestra tabla de destino. Para este ejemplo utilizaremos los siguiente:

Tabla cliente


CREATE TABLE [database_name].[cliente](
	[nombre] [varchar](30) NULL,
	[rut] [varchar](10) NULL,
	[telefono] [varchar](10) NULL
) ON [PRIMARY]

GO

Archivo Formato (cliente.ftm)

10.0
3
1    SQLCHAR  0 30   ""     1   nombre    SQL_Latin1_General_CP1_CI_AS
2    SQLCHAR  0 10   ""     2   rut       SQL_Latin1_General_CP1_CI_AS
3    SQLCHAR  0 10   "\r\n" 3   telefono  SQL_Latin1_General_CP1_CI_AS

Los nombres y largos de los campos deben coincidir con los de la base de datos.
Si lo dejamos así separara el archivo por cantidad de caracteres si lo quieren por delimitadores se deben agregar en » » (ejemplo «;»).
La ultima fila debe llevar siempre «\r\n»
10.0 Corresponde a la versión utilizada por sql server
3 Corresponde a la cantidad de filas

Archivo de Carga (cliente_masivo.txt)


Pedro Juan Lopez Ortega       11111111-80991234567    
Pedro Juan Lopez Ortega       11111111-80991234567
Pedro Juan Lopez Ortega       11111111-80991234567
Pedro Juan Lopez Ortega       11111111-80991234567
Pedro Juan Lopez Ortega       11111111-80991234567
.....

Bueno con estos datos estamos listos para realizar nuestra carga de datos masivos. Para no alargar mas este tutorial les dejo el procedimiento almacenado y la forma de uso:

USE [My DataBase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[SpCargaMasiva] 
	@Archivo varchar(255), 
	@Formato varchar(255),
	@Tabla varchar(150)
AS
BEGIN TRY
declare @Sql nvarchar(1000);
declare @FilasDevueltas bigint;

SET NOCOUNT OFF;

set @Sql='TRUNCATE TABLE ' + @Tabla
EXECUTE sp_executesql @Sql;

set @Sql = 'BULK INSERT ' + @Tabla +
		' FROM ' + CHAR(39) + @Archivo + CHAR(39) +
		' WITH (FORMATFILE = '  + CHAR(39) + @Formato + CHAR(39) +  
		',BATCHSIZE =1000)'
     
EXECUTE sp_executesql @Sql;

set @FilasDevueltas=@@ROWCOUNT;
select @FilasDevueltas as FilasDevueltas;

END TRY
BEGIN CATCH
	set @FilasDevueltas=-1;
	select @FilasDevueltas as FilasDevueltas;

END CATCH

Al comienzo limpia la tabla (en caso que no necesiten limpiar solo borran esa parte).
Controla algunos errores que puedan ocurrir retornando -1.

Modo de uso:


dbo.SpCargaMasiva 'C:\cliente.txt','C:\cliente.fmt','cliente'

Si están trabajando apuntando a algún servidor por ejemplo QUALITY deben cambiar la ruta C:\ por la correspondiente \\QUALITY\…

Espero sea de su utilidad.

No duden en dejar sus inquietudes o comentarios.

Saludos.

También te podría gustar...

10 Respuestas

  1. Leo dice:

    Hola gracias por el aporte, pero queria saber si tengo 20 archivos txt como puedo subirlos todos en unas sola tabla de forma automática.
    Gracias

    • solo debes ampliar el sp para que reciba todos los archivos por ejemplo mandarlos así ‘archivo1.txt,archivo2.txt’ y luego separarlos internamente y hacer un while con los resultados. Puedes separarlos utilizando Split Sql Server que encuentras en este mismo sitio.

  2. John Camargo dice:

    Buenas tardes,

    Ese BCP funciona excelente.

    Pero tengo una pregunta para que por favor me ayudes.

    Yo quiero traer muchos archivos de un directorio y los archivos son .txt, que tienen la misma estructura, pero los nombres de los archivos son diferentes. Como haria con esa instrucción para que cargue a la tabla de sql todos los archivos sin importar su nombre?. o como haria para traer solo los archivos que su nombre de archivo comienze por determinada letra?.

    Tal y como esta tu BCP funciona pero para un archivo .. que tiene un nombre especifico.

    Quedo muy atento a su grandiosa ayuda.

    Gracias

  3. Alex G dice:

    Gracias por la solución…
    Ya aplique las instrucciones pero mi archivo fuente (txt) tiene identificadores de texto «» los cuales tambien los sube a la tabla, es decir, en la tabla tengo el caracter » en cada registro subido.
    Por favor como puedo subir los registros sin este calificador de texto «».

    Gracias de antemano

    Alex G

  4. Fer dice:

    Una pregunta,

    Cómo creo el fmt?, o con qué aplicación… no logro generarlo

    Salduos!!!

  5. vianey dice:

    Que mas como estas buenas tardes muy agradecido con tu ejemplo genial
    de hecho me encuentro tratando de subir un archivo de excel a una tabla sql server que ya tengo y no me deja porfavor necesito ayuda quedo atento si en realidad me puedes ayudar te agradezco mucho yo le pago a cualquier nro de cuenta que me des por tu apoyo muchas gracias quedo atento.

    https://www.qis.cl/como-realizar-carga-masiva-de-archivos-con-sql-server-2008-r2-bulk-insert/

  6. Estimado según entiendo el bulk insert requiere un delimitador ya sea por , ; : tabuladores, etc. Te recomiendo utilizar la rutina que explico en este tutorial en donde defines un archivo de formato con la cantidad de caracteres que requiere cada campo.

    Quedo atento a tus comentarios

  7. SIO dice:

    necesito de vuestra ayuda con una carga masiva de datos que necesito implementar,

    Necesito cargar un archivo plano con campos de longitud fija a una base de datos Microsoft sql server 2008, el tema que lo estoy realizando a través de la instrucción Bulk Insert

    la instrucción es la siguiente:

    BULK INSERT TmpBulkTL5

    FROM ‘C:\FilesProvider\TL\TLC150324.txt’

    WITH (ROWTERMINATOR = ‘\n’,FIRSTROW = 2)

    Por el momento ambos archivos como el sql server se encuentran en el mismo equipo.

    El Archivo contiene lo siguiente:

    HDRTL20150324

    TLC001000077334224201503240000030001000001000010000000001MXP00000020003221588249064741

    TLC001000077334225201503240000050001000001000010000000001MXP00000050004521355282272910

    TLC001000077334226201503232359230001000001000010000000001MXP00000050003141249523162552

    TLC001000077334227201503232359270001000001000010000000001MXP00000020003121195325847942

    TLC001000077334230201503232359290001000001000010000000001MXP00000030003143387512981367

    Cuando ejecuto el bulk muestra el siguiente error:

    Msg 4866, Level 16, State 8, Line 1

    Error de carga masiva. Columna demasiado larga en el archivo de datos para la fila 1, columna 1. Compruebe que especificó correctamente los valores para el terminador de campo y el terminador de fila.

    Msg 7301, Level 16, State 2, Line 1

    No se puede obtener («IID_IColumnsInfo») del proveedor OLE DB «BULK» para el servidor vinculado «(null)».

Deja una respuesta

Tu dirección de correo electrónico no será publicada.