2009-06-22 31 views
6

Me parece que no puede averiguar cómo ocurre esto.SQL inserción masiva con el parámetro FIRSTROW se salta la siguiente línea

He aquí un ejemplo del archivo que estoy tratando de inserción masiva en el servidor SQL 2005:

***A NICE HEADER HERE*** 
00000|SSNV|00013893-03JUN09 
0000005678|ABCD|00013893-03JUN09 
0000009112|0000|00013893-03JUN09 
0000009112|0000|00013893-03JUN09 

Aquí es mi instrucción de inserción a granel:

BULK INSERT sometable 
FROM 'E:\filefromabove.txt 
WITH 
(
FIRSTROW = 2, 
FIELDTERMINATOR= '|', 
ROWTERMINATOR = '\n' 
) 

Pero, por alguna razón el único La salida que puedo obtener es:

0000005678|ABCD|00013893-03JUN09 
0000009112|0000|00013893-03JUN09 
0000009112|0000|00013893-03JUN09 

El primer registro siempre se omite, a menos que elimine el encabezado por completo y no use el parámetro FIRSTROW. ¿Cómo es esto posible?

¡Gracias de antemano!

Respuesta

12

no creo que se puede omitir filas en un formato diferente con BULK INSERT/BCP.

Cuando ejecuto esto:

TRUNCATE TABLE so1029384 

BULK INSERT so1029384 
FROM 'C:\Data\test\so1029384.txt' 
WITH 
(
--FIRSTROW = 2, 
FIELDTERMINATOR= '|', 
ROWTERMINATOR = '\n' 
) 

SELECT * FROM so1029384 

me sale:

col1            col2            col3 
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- 
***A NICE HEADER HERE*** 
00000SSNV            00013893-03JUN09 
0000005678           ABCD            00013893-03JUN09 
0000009112           0000            00013893-03JUN09 
0000009112           0000            00013893-03JUN09 

Parece que requiere el carácter '|' incluso en los datos del encabezado, porque se lee hasta eso en la primera columna, tragándose una nueva línea en la primera columna. Obviamente si incluye un parámetro de campo terminador, se espera que cada fila MUST tiene uno.

Usted podría despojar a la fila con una etapa de pre-procesamiento. Otra posibilidad es seleccionar solo las filas completas, luego procesarlas (excluyendo el encabezado). O use una herramienta que pueda manejar esto, como SSIS.

+0

¡Estás en lo correcto! Cuando agrego '||' hasta el final del encabezado, funciona bien. Creo que voy a intentar quitar el encabezado de cada archivo que estoy insertando. ¡Gracias! – gibbo

6

Tal comprobar que la cabecera tiene la misma línea interminable como las filas de datos reales (como se especifica en ROWTERMINATOR)?

Actualización: desde MSDN:

El atributo FIRSTROW no pretende para saltar títulos de las columnas. Saltarse cabeceras no es compatible con la instrucción BULK INSERT . Al omitir filas, , el Motor de base de datos de SQL Server se ve solo en los terminadores de campo, y no valida los datos en los campos de filas omitidas.

+0

Hola Marcar, sí, lamentablemente cada una de las filas tiene un CRLF. Gracias por la entrada, sin embargo. – gibbo

4

me pareció más fácil de simplemente leer toda la línea en una columna y luego analizar los datos usando XML.

IF (OBJECT_ID('tempdb..#data') IS NOT NULL) DROP TABLE #data 
CREATE TABLE #data (data VARCHAR(MAX)) 

BULK INSERT #data FROM 'E:\filefromabove.txt' WITH (FIRSTROW = 2, ROWTERMINATOR = '\n') 

IF (OBJECT_ID('tempdb..#dataXml') IS NOT NULL) DROP TABLE #dataXml 
CREATE TABLE #dataXml (ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED, data XML) 

INSERT #dataXml (data) 
SELECT CAST('<r><d>' + REPLACE(data, '|', '</d><d>') + '</d></r>' AS XML) 
FROM #data 

SELECT d.data.value('(/r//d)[1]', 'varchar(max)') AS col1, 
     d.data.value('(/r//d)[2]', 'varchar(max)') AS col2, 
     d.data.value('(/r//d)[3]', 'varchar(max)') AS col3 
FROM #dataXml d 
+0

Este es un script increíble para evitar hacer SSIS. Me permitió importar solo la primera fila, verificar si coincide con las filas de destino y luego proceder a importar todos los datos excepto los encabezados. ¡Gracias! – lwall

-1

Dado lo destrozado algunos datos pueden cuidar BCP importar a SQL Server desde fuentes de datos no SQL, sugeriría hacer toda la importación BCP en algunas mesas de rasca y gana en primer lugar.

Por ejemplo

tabla truncado Address_Import_tbl

inserción masiva dbo.Address_Import_tbl DE 'E: \ externa \ SomeDataSource \ Address.csv' CON ( FIELDTERMINATOR = '|', ROWTERMINATOR = '\ n ', MAXERRORS = 10 )

Asegúrese de que todas las columnas en Address_Import_tbl sean nvarchar(), para que sea lo más agnóstico posible, y evite los errores de conversión de tipo.

Luego aplique las correcciones que necesite para Address_Import_tbl. Como eliminar el encabezado no deseado.

A continuación, ejecute una consulta INSERT SELECT, para copiar de Address_Import_tbl a Address_tbl, junto con las conversiones de tipo de datos que necesite. Por ejemplo, para convertir fechas importadas en SQL DATETIME.

Cuestiones relacionadas