带有损坏管道字段的UTF-8文件BULK INSERT返回错误

时间:2017-01-16 21:34:27

标签: sql-server utf-8 bulkinsert sql-server-2016

我正在尝试使用损坏的管道(|)分隔符加载UTF-8平面文件。

平面文件的内容非常简单,行以CRLF结束

AAA¦BBB¦CCC

代码是

create table l_testfile
(COL1 nvarchar(255),
COL2 nvarchar(255),
COL3 nvarchar(255)
)


BULK INSERT l_testfile
FROM 'C:\testfile.txt'
WITH (CODEPAGE = '65001', DATAFILETYPE = 'Char', FIELDTERMINATOR = '¦')

这会导致错误

  

Msg 4832,Level 16,State 1,Line 16批量加载:意外结束   在数据文件中遇到了文件。 Msg 7399,Level 16,State 1,   第16行报告链接服务器“(null)”的OLE DB提供程序“BULK”   一个错误。提供商未提供有关错误的任何信息。   消息7330,级别16,状态2,行16无法从OLE DB获取行   提供者“BULK”用于链接服务器“(null)”。

将断开的管道(|)更改为普通管道(|)时,BULK INSERT正常工作。另外,加载带有损坏管道的ANSI文件也不会产生任何错误。

我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

我无法访问SQL 2016实例,我现在可以对此进行测试,但我认为问题是由于¦字符在UTF-8和您之间编码的不同方式造成的本地varchar代码页。

FIELDTERMINATOR命令中指定BULK INSERT后,您将其指定为varchar - 但大多数单字节代码页中的encoding of ¦为{ {1}},而在UTF-8中它是0xA6 - 因此,终结器永远不会匹配,这会导致错误(我不确定,但我怀疑这是因为单字节值在内部转换为UCS2-LE表示0xC2A6)。

如果您使用UTF-8中组成0x00A6的字节作为¦,我认为批量插入应该可以正常工作:

FIELDTERMINATOR

(使用BULK INSERT l_testfile FROM 'C:\testfile.txt' WITH (CODEPAGE = '65001', DATAFILETYPE = 'Char', FIELDTERMINATOR = '0xC2A6') 作为分隔符是成功的,因为它已编码