Incompatibilidade de tipo T-SQL BULK INSERT
Estou tentando fazer um BULK INSERT simples de um grande arquivo CSV para uma tabela. A tabela e o arquivo possuem colunas correspondentes. Este é o meu código:
BULK INSERT myTable
FROM 'G:\Tests\mySource.csv'
WITH (
FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
-- ROWTERMINATOR = '0x0a',
BATCHSIZE = 1000,
MAXERRORS = 2
)
GO
Como você pode ver, tentei com terminadores de linha \ne 0x0a(e muitos outros)
Continuo recebendo um erro de incompatibilidade de tipo:
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)".
A coluna createdAté do tipo datetime:
CREATE TABLE [dbo].[myTable]
(
...
[createdAt] [datetime] NULL,
...
)
Estes são os valores da createdAtcoluna retirados das três primeiras linhas:
2020-08-22 13:51:57
2020-08-22 14:13:13
2020-08-22 14:16:23
Também tentei com um formato de número diferente, conforme sugerido. Também tentei alterar o tipo de coluna para DATETIME2(n):
2020-08-22T13:51:57
2020-08-22T14:13:13
2020-08-22T14:16:23
Não tenho ideia do que mais revisar.
Eu apreciaria qualquer ajuda.
Obrigado!
Respostas
Existem muitos formatos de literais de string a serem convertidos em datas e horas com suporte do SQL Server - consulte os Manuais Online do MSDN sobre CAST e CONVERT . A maioria desses formatos depende de quais configurações você tem - portanto, essas configurações podem funcionar algumas vezes - e às vezes não. E o DATETIMEtipo de dados em particular é notoriamente exigente sobre quais formatos de literais de string funcionam - e quais outros (a maioria) não ... DATETIME2(n)é muito mais indulgente e menos exigente de lidar!
A maneira de resolver isso é usar o formato de data ISO-8601 (ligeiramente adaptado) que é compatível com o SQL Server - esse formato funciona sempre - independentemente do idioma do SQL Server e das configurações de formato de data.
O formato ISO-8601 é compatível com o SQL Server e vem em dois tipos:
YYYYMMDDapenas para datas (sem parte do tempo); nota aqui: sem travessões! , isso é muito importante! NÃOYYYY-MM-DDé independente das configurações de formato de data em seu SQL Server e NÃO funcionará em todas as situações!
ou:
YYYY-MM-DDTHH:MM:SSpara datas e horas - observe aqui: este formato tem travessões (mas podem ser omitidos) e umTdelimitador fixo entre a data e a hora do seuDATETIME.
Isso é válido para SQL Server 2000 e mais recente.
Se você usar o SQL Server 2008 ou mais recente e o DATEtipo de dados (apenas DATE- não DATETIME !), Então você também pode usar o YYYY-MM-DDformato e isso também funcionará com quaisquer configurações em seu SQL Server.
Não me pergunte por que todo esse tópico é tão complicado e um tanto confuso - é assim que as coisas são. Mas com o YYYYMMDDformato, você deve estar bem para qualquer versão do SQL Server e para qualquer configuração de idioma e formato de data em seu SQL Server.
A recomendação para o SQL Server 2008 e mais recente é usar DATEse você precisar apenas da parte da data e DATETIME2(n)quando precisar de data e hora. Você deve tentar começar a eliminar o DATETIMEtipo de dados sempre que possível
No seu caso, eu tentaria uma de duas coisas:
se você puder - usar em
DATETIME2(n)vez deDATETIMEcomo o tipo de dados da sua coluna - isso por si só pode resolver todos os seus problemasse você não puder usar
DATETIME2(n)- tente usar em2020-08-22T13:51:57vez de2020-08-22 13:51:57para especificar sua data e hora no arquivo de importação CSV.