Discrepancia de tipo T-SQL BULK INSERT
Estoy tratando de hacer un INSERTAR A GRANEL simple desde un archivo CSV grande a una tabla. La tabla y el archivo tienen columnas coincidentes. Este es mi codigo:
BULK INSERT myTable
FROM 'G:\Tests\mySource.csv'
WITH (
FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
-- ROWTERMINATOR = '0x0a',
BATCHSIZE = 1000,
MAXERRORS = 2
)
GO
Como puede ver, lo he intentado con terminadores de fila \ny 0x0a(y muchos más)
Sigo recibiendo un error de falta de coincidencia de tipos:
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 2, column 18 (createdAt).
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 3, column 18 (createdAt).
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 4, column 18 (createdAt).
Msg 4865, Level 16, State 1, Line 1
Cannot bulk load because the maximum number of errors (2) was exceeded.
Msg 7399, Level 16, State 1, Line 1
The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.
Msg 7330, Level 16, State 2, Line 1
Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".
La columna createdAtes de tipo datetime:
CREATE TABLE [dbo].[myTable]
(
...
[createdAt] [datetime] NULL,
...
)
Estos son los valores de la createdAtcolumna tomados de las tres primeras filas:
2020-08-22 13:51:57
2020-08-22 14:13:13
2020-08-22 14:16:23
También probé con un formato de número diferente como se sugiere. También intenté cambiar el tipo de columna a DATETIME2(n):
2020-08-22T13:51:57
2020-08-22T14:13:13
2020-08-22T14:16:23
No tengo idea de qué más revisar.
Apreciaría cualquier ayuda.
¡Gracias!
Respuestas
Hay muchos formatos de cadenas literales para convertir a fechas y horas compatibles con SQL Server; consulte los Libros en pantalla de MSDN sobre CAST y CONVERT . La mayoría de esos formatos dependen de la configuración que tenga; por lo tanto, estas configuraciones pueden funcionar algunas veces, y otras no. Y el DATETIMEtipo de datos en particular es notoriamente exigente sobre qué formatos de cadenas literales funcionan, y cuáles otros (la mayoría) no ... ¡ DATETIME2(n)es mucho más indulgente y menos exigente de manejar!
La forma de resolver esto es utilizar el formato de fecha ISO-8601 (ligeramente adaptado) que es compatible con SQL Server; este formato siempre funciona , independientemente de la configuración de idioma y formato de fecha de SQL Server.
El formato ISO-8601 es compatible con SQL Server y viene en dos versiones:
YYYYMMDDsolo por fechas (sin porción de tiempo); nota aquí: ¡ sin guiones! , eso es muy importante! NOYYYY-MM-DDes independiente de la configuración de formato de fecha en su servidor SQL y NO funcionará en todas las situaciones.
o:
YYYY-MM-DDTHH:MM:SSpara fechas y horas: tenga en cuenta aquí: este formato tiene guiones (pero se pueden omitir) y unTdelimitador fijo entre la parte de fecha y hora de suDATETIME.
Esto es válido para SQL Server 2000 y versiones posteriores.
Si usa SQL Server 2008 o más reciente y el DATEtipo de datos (¡solo DATE, no DATETIME !), Entonces de hecho también puede usar el YYYY-MM-DDformato y eso también funcionará con cualquier configuración en su SQL Server.
No me pregunte por qué todo este tema es tan complicado y algo confuso, así es como es. Pero con el YYYYMMDDformato, debería estar bien para cualquier versión de SQL Server y para cualquier idioma y configuración de formato de fecha en su SQL Server.
La recomendación para SQL Server 2008 y versiones posteriores es usarlo DATEsi solo necesita la parte de la fecha y DATETIME2(n)cuando necesita tanto la fecha como la hora. Debería intentar comenzar a eliminar gradualmente el DATETIMEtipo de datos si es posible
En su caso, probaría una de dos cosas:
si puede, use en
DATETIME2(n)lugar deDATETIMEcomo tipo de datos de su columna, eso por sí solo podría resolver todos sus problemassi no puede usar
DATETIME2(n), intente usar en2020-08-22T13:51:57lugar de2020-08-22 13:51:57especificar su fecha y hora en el archivo de importación CSV.