我正在对sqlserver进行BULK INSERT,并且没有正确地将UTF-8字符插入数据库。数据文件包含这些字符,但在批量插入执行后数据库行包含乱码。
我的第一个嫌疑人是格式文件的最后一行:
10.0
3
1 SQLCHAR 0 0 "{|}" 1 INSTANCEID ""
2 SQLCHAR 0 0 "{|}" 2 PROPERTYID ""
3 SQLCHAR 0 0 "[|]" 3 CONTENTTEXT "SQL_Latin1_General_CP1_CI_AS"
但是,在阅读this official page之后,在我看来,这实际上是SQL Server 2008版中的插入操作读取数据文件时的错误。我们使用的是版本2008 R2。
此问题的解决方案是什么或至少是解决方法?
答案 0 :(得分:31)
在找到批量插入特殊字符的解决方案之前,我来到这里。 不喜欢UTF-16的解决方法(这将使csv文件的大小加倍)。 我发现你绝对可以,而且非常简单,你不需要格式文件。 因此,我正在为其他正在寻找相同内容的人添加此评论,因为它似乎没有在任何地方记录得很好,我相信这对非英语国家的人来说是一个非常普遍的问题。解决方案是: 只需在批量插入的with语句中添加CODEPAGE ='65001'。 (65001 = UTF-8的代码页编号)。 可能不适合Michael O所建议的所有unicode角色,但至少它适用于拉丁语,希腊语和西里尔语,可能还有很多其他人。
注意:MSDN文档说不支持utf-8,不相信它,对我来说这在SQL Server 2008中是完美的,但是没有尝试其他版本。
e.g:
BULK INSERT #myTempTable
FROM 'D:\somefolder\myCSV.txt'+
WITH
(
CODEPAGE = '65001',
FIELDTERMINATOR = '|',
ROWTERMINATOR ='\n'
);
如果所有特殊字符都在160-255(iso-8859-1或windows-1252)中,您还可以使用:
BULK INSERT #myTempTable
FROM 'D:\somefolder\myCSV.txt'+
WITH
(
CODEPAGE = 'ACP',
FIELDTERMINATOR = '|',
ROWTERMINATOR ='\n'
);
答案 1 :(得分:27)
你做不到。您应该首先使用N类型数据字段,将文件转换为UTF-16然后导入它。该数据库不支持UTF-8。
答案 2 :(得分:7)
BULK INSERT #tmpData
FROM 'C:\Book2.csv' WITH ( FIRSTROW = 2, FIELDTERMINATOR = ';', --CSV field delimiter ROWTERMINATOR = '\n', --Use to shift the control to next row TABLOCK )
完成。
答案 3 :(得分:4)
您可以使用UTF-16重新编码数据文件。这就是我所做的。
答案 4 :(得分:4)
Microsoft刚刚向SQL Server 2014 SP2添加了UTF-8支持:
答案 5 :(得分:2)
使用这些选项 -
`https://graph.facebook.com/${matchedResult.username}/posts?access_token=${matchedResult.token}`
和DATAFILETYPE='char'
答案 6 :(得分:2)
请注意,自Microsoft SQL Server 2016起,bcp
,BULK_INSERT
(as was part of the original question)和OPENROWSET
支持UTF-8。
答案 7 :(得分:1)
你不应该使用SQLNCHAR
代替SQLCHAR
来获取unicode数据吗?
答案 8 :(得分:0)
我设法使用SSIS和ADO NET目的地而不是OLEDB。
答案 9 :(得分:0)
我的导出数据是来自DB的TSV格式,具有Latin-1编码。
这很容易检查:
SELECT DATABASEPROPERTYEX('DB', 'Collation') SQLCollation;
提取文件采用UTF-8格式。
BULK INSERT不使用UTF-8,因此我使用简单的Clojure脚本将UTF-8转换为ISO-8859-1(又名Latin-1):
(spit ".\\dump\\file1.txt"
(slurp ".\\dump\\file1_utf8.txt" :encoding "UTF-8")
:encoding "ISO-8859-1")
执行 - 纠正路径和
java.exe -cp clojure-1.6.0.jar clojure.main utf8_to_Latin1.clj
答案 10 :(得分:0)
我已使用UTF -8
格式测试了批量插入。它在Sql Server 2012中工作正常。
string bulkInsertQuery = @"DECLARE @BulkInsertQuery NVARCHAR(max) = 'bulk insert [dbo].[temp_Lz_Post_Obj_Lvl_0]
FROM ''C:\\Users\\suryan\\Desktop\\SIFT JOB\\New folder\\POSTdata_OBJ5.dat''
WITH ( FIELDTERMINATOR = '''+ CHAR(28) + ''', ROWTERMINATOR = ''' +CHAR(10) + ''')'
EXEC SP_EXECUTESQL @BulkInsertQuery";
我使用*.DAT
文件将FS作为列分隔符。
答案 11 :(得分:0)
以为我会加入我的想法。我们试图使用bcp将数据加载到SqlServer中并且遇到了很多麻烦。
在大多数版本中,bcp不支持任何类型的UTF-8文件。我们发现UTF-16可以工作,但它比这些帖子中显示的更复杂。使用Java我们使用以下代码编写文件:
PrintStream fileStream = new PrintStream(NEW_TABLE_DATA_FOLDER + fileName, "x-UTF-16LE-BOM");
这为我们提供了正确的数据插入。
我们尝试使用UTF16并不断出现EOF错误。这是因为我们错过了文件的BOM部分。来自维基百科:
UTF-16,BOM(U + FEFF)可以作为文件或字符流的第一个字符,以指示文件或流的所有16位代码单元的字节顺序(字节顺序)。
如果这些字节不存在,则该文件将不起作用。所以我们有了这个文件,但还有一个秘密需要解决。在构造命令行时,必须包含-w以告诉bcp它是什么类型的数据。仅使用英语数据时,可以使用-c(字符)。所以看起来像这样:
bcp dbo.blah在C:\ Users \ blah \ Desktop \ events \ blah.txt -S tcp:databaseurl,someport -d thedatabase -U username -P password -w
当这一切都完成后,你会得到一些甜美的数据!
答案 12 :(得分:0)
我只想分享一个问题,我在文件中添加了葡萄牙语的重音符号,并bcp导入了垃圾字符(例如À变成┴) 我尝试使用-C几乎所有代码页都没有成功。几个小时后,我在bcp MS帮助页面上找到了提示。
格式文件代码页的优先级高于-C属性
表示在格式文件中,我必须像姓氏中那样使用“”,更改代码页后,属性-C 65001导入了UTF8文件而没有任何问题
ListItemWriter.getWrittenItems