T-SQL BULK INSERT türü uyuşmazlığı
Büyük bir CSV dosyasından bir tabloya basit bir TOPLU INSERT yapmaya çalışıyorum. Tablo ve dosyanın eşleşen sütunları var. Bu benim kodum:
BULK INSERT myTable
FROM 'G:\Tests\mySource.csv'
WITH (
FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
-- ROWTERMINATOR = '0x0a',
BATCHSIZE = 1000,
MAXERRORS = 2
)
GO
Gördüğünüz gibi satır sonlandırıcıları denedim \nve 0x0a(ve bir sürü daha)
Sürekli bir tür uyuşmazlığı hatası alıyorum:
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)".
Sütun createdAttürü datetime:
CREATE TABLE [dbo].[myTable]
(
...
[createdAt] [datetime] NULL,
...
)
Bunlar createdAt, ilk üç satırdan alınan sütunun değerleridir :
2020-08-22 13:51:57
2020-08-22 14:13:13
2020-08-22 14:16:23
Ayrıca önerildiği gibi farklı bir sayı formatıyla da denedim. Ayrıca sütun türünü şu şekilde değiştirmeyi denedim DATETIME2(n):
2020-08-22T13:51:57
2020-08-22T14:13:13
2020-08-22T14:16:23
Başka ne gözden geçireceğim hakkında hiçbir fikrim yok.
Herhangi bir yardım için minnettar olurum.
Teşekkürler!
Yanıtlar
SQL Server tarafından desteklenen tarih ve saatlere dönüştürülecek pek çok değişmez dize biçimi vardır - CAST ve CONVERT'teki Çevrimiçi MSDN Kitaplarına bakın . Bu formatların çoğu, sahip olduğunuz ayarlara bağlıdır - bu nedenle, bu ayarlar bazen işe yarayabilir - ve bazen çalışmayabilir. Ve DATETIMEözellikle veri türü, dizge değişmezlerinin hangi formatlarının işe yaradığı ve diğerlerinin (çoğu) çalışmadığı konusunda herkesin bildiği gibi seçicidir ... DATETIME2(n)çok daha bağışlayıcı ve uğraşması daha az seçici!
Bunu çözmenin yolu, SQL Server tarafından desteklenen (biraz uyarlanmış) ISO-8601 tarih biçimini kullanmaktır - bu biçim her zaman çalışır - SQL Server diliniz ve tarih biçimi ayarlarınızdan bağımsız olarak.
ISO-8601 biçiminde SQL Server tarafından desteklenen iki şekilde sağlanır:
YYYYMMDDsadece tarihler için (zaman bölümü yok); buraya dikkat edin: tire yok! bu çok önemli!YYYY-MM-DDolduğu DEĞİL SQL Server dateformat ayarlarından bağımsız ve olacak DEĞİL her durumda çalışmayabilir!
veya:
YYYY-MM-DDTHH:MM:SStarihler ve saatler için - burada not: Bu biçim vardır tire (ama olabilir atlanabilir) ve sabitTaramalarınızdan tarih ve saat kısmı arasında ayırıcı olarakDATETIME.
Bu, SQL Server 2000 ve sonrası için geçerlidir.
SQL Server 2008 veya daha DATEyenisini ve veri türünü (yalnızca DATE- değil DATETIME !) Kullanıyorsanız , o zaman YYYY-MM-DDformatı da kullanabilirsiniz ve bu da SQL Server'ınızdaki herhangi bir ayar ile çalışacaktır.
Bana tüm bu konunun neden bu kadar zor ve biraz kafa karıştırıcı olduğunu sorma - bu tam olarak böyle. Ancak YYYYMMDDbiçimle, SQL Server'ın herhangi bir sürümü ve SQL Server'ınızdaki herhangi bir dil ve tarih biçimi ayarı için iyi olmalısınız.
SQL Server 2008 ve daha yeni sürümler için öneri, DATEyalnızca tarih kısmına ve DATETIME2(n)hem tarih hem de saate ihtiyacınız olduğunda kullanmanızdır. DATETIMEMümkünse veri türünü aşamalı olarak kaldırmaya başlamalısınız
Senin durumunda, iki şeyden birini denerim:
Eğer yapabiliyorsanız - sütununuzun veri türü
DATETIME2(n)yerine kullanınDATETIME- bu tek başına tüm sorunlarınızı çözebilirkullanamıyorsanız
DATETIME2(n)- CSV içe aktarma dosyasında tarih ve saatinizi belirtmek2020-08-22T13:51:57yerine kullanmayı deneyin2020-08-22 13:51:57.