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.
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.
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
Estimado si revisas el procedimiento te darás cuenta que el nombre no es fijo de echo se pasa por parámetro.
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
Una pregunta,
Cómo creo el fmt?, o con qué aplicación… no logro generarlo
Salduos!!!
Disculpa la demora los archivos fmt son archivos de texto solo debes cambiar la extensión .txt por .fmt
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/
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
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)».