关于在SQL Server BULK INSERT
文件中转义字符的文档很少。
BULK INSERT
的文档说该语句只有两种格式选项:FIELDTERMINATOR
和ROWTERMINATOR
,但它没有说明如果出现这些字符,你是如何逃避它们的连续的字段值。
例如,如果我有这个表:
CREATE TABLE People ( name varchar(MAX), notes varchar(MAX) )
和这一行数据:
"Foo, \Bar", "he has a\r\nvery strange name\r\nlol"
...它的相应批量插入文件将如何显示,因为这显然不起作用:
Foo,\Bar,he has a
very strange name
lol
SQL Server表示它支持\r
和\n
,但没有说反斜杠是否会自行转义,也没有提到字段值分隔(例如使用双引号或转义双重引号)引用)所以我在这方面有点困惑。
答案 0 :(得分:4)
我通过使用\ 0作为行分隔符和\ t作为字段分隔符解决了这个问题,因为这两个字符都没有作为字段值显示,并且都被BULK INSERT支持为分隔符。
我很惊讶MSSQL在导入/导出时没有提供更多的灵活性。构建一流的CSV / TSV解析器不需要太多精力。
答案 1 :(得分:1)
为下一个搜索的人:
我使用“\ 0 \ t”作为字段分隔符,并使用“\ 0 \ n”作为最后一个字段的行尾分隔符。如果您希望假装文件具有DOS EOL约定,则也可以使用“\ 0 \ r \ n”。
对于不熟悉\ x表示法的人,\ 0是CHAR(0),\ t是CHAR(9),\ n是CHAR(10),\ r是CHAR(13)。将CHAR()函数替换为您提供的任何语言,以将数字转换为指定字符。
使用此组合,\ t和\ n(和\ r)的所有实例都将成为数据文件中的可接受字符。毕竟,批量上传系统的弱点是标签和换行符通常是文本字符串中的合法字符,而其他低ASCII字符(如CHAR(0),CHAR(1)和CHAR(2))不是合法文本 - 不是甚至出现在UTF-8中。
你的数据中唯一没有的字符是\ 0 - 除非你可以保证它永远不会被\ t或\ n(或\ r)
所跟随如果你的语言在字符串中使用\ 0时遇到问题(但取决于你如何编码,你仍然可以避免这个问题) - 如果你知道你的数据不会有CHAR(1)或其中的CHAR(2)(即没有二进制)然后使用这些字符。当您尝试在字符串中存储任意二进制数据时,只能找到那些低字符。
另请注意,您将在UTF-16,UCS-2和UTF-32(又名UCS-4)中找到字节0,1,2 - BUT - CHAR的0或4字节宽表示(0,1或2)仍然可以接受并且不同于任何合法的unicode文本。只需确保在格式文件中选择正确的代码页设置,以适合您选择的UTF或UCS变体。
答案 2 :(得分:0)
批量插入需要为每一行提供相应的字段和字段数。你的例子有点粗糙,因为它不是结构化数据。至于字符,它将按字面解释它们,而不是使用转义字符(您的字符串将在文件中看到。
对于包含每个字段的双引号,您只需将它们用作字段和行终止符。所以现在你应该有:
Fieldterminator ='“,”', Rowterminator ='“\ n'
这有意义吗?然后在批量插入之后,你需要用以下内容取出前缀双引号:
更新yourtable 设置yourfirstcolumn = right(yourfirstcolumn,len(yourfirstcolumn) - 1)