我正在尝试使用Unix换行符将一个.csv文件插入到数据库中。我运行的命令是:
BULK INSERT table_name
FROM 'C:\file.csv'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)
如果我将文件转换为Windows格式,则可以加载,但如果可以避免这个额外的步骤,我不想这样做。 有什么建议吗?我正在尝试使用Unix换行符将一个.csv文件插入到数据库中。我运行的命令是:
BULK INSERT table_name
FROM 'C:\file.csv'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)
如果我将文件转换为Windows格式,则可以加载,但如果可以避免这个额外的步骤,我不想这样做。 有什么建议吗?我觉得有必要做出贡献,因为我也遇到了同样的问题,我每天至少需要阅读两个来自SAP的UNIX文件。因此,我不想使用unix2dos,而是需要通过编程自动化地减少手动干预。
如前所述,Char(10)可在sql语句中使用。我不想使用sql语句,所以我使用了''''+Char(10)+'''',但由于某种原因,这无法编译。
非常顺利的解决方法是:使用 (ROWTERMINATOR = '0x0a')
通过十六进制解决了问题!
感谢所有回答过我的人,但我已经找到了我想要的解决方案。
如果您告诉 SQL Server ROWTERMINATOR='\n',它将把它解释为 Windows 下的默认行终止符,实际上是 "\r\n"(使用 C/C++ 表示法)。如果您的行终止符确实只是 "\n",则必须使用下面显示的动态 SQL。
DECLARE @bulk_cmd varchar(1000)
SET @bulk_cmd = 'BULK INSERT table_name
FROM ''C:\file.csv''
WITH (FIELDTERMINATOR = '','', ROWTERMINATOR = '''+CHAR(10)+''')'
EXEC (@bulk_cmd)
为什么不能说BULK INSERT...(ROWTERMINATOR = CHAR(10)),我不明白。看起来在命令的WITH部分中无法评估任何表达式。
上面的操作是创建一个命令字符串并执行它。这样巧妙地规避了创建额外文件或进行额外步骤的需要。
我确认语法
ROWTERMINATOR = '''+CHAR(10)+'''
当与EXEC命令一起使用时,此功能可正常工作。
如果您有多个ROWTERMINATOR字符(例如管道符和Unix换行符),则其语法如下:
ROWTERMINATOR = '''+CHAR(124)+''+CHAR(10)+'''
这个问题有点复杂!当你告诉SQL Server ROWTERMINATOR='\n'时,它会将其解释为Windows下的默认行终止符,实际上是"\r\n"(使用C / C ++表示法)。如果你的行终止符只是"\n",则必须使用上面显示的动态SQL。我刚刚花了大约一个小时来弄清楚为什么在BULK INSERT中使用 \n 时它并不真正意味着 \n!
在我看来,有两条通用途径可供选择:一是使用 SQL 脚本中的某种替代方法来读取 CSV,二是使用众多可行的方式之一(如 bcp、unix2dos),事先将 CSV 转换好(如果只需做这件事一次,你甚至可以使用代码编辑器为其修复文件)。
但这样就需要额外一个步骤!
如果此 SQL 是从程序中启动的,你可能需要在该程序中转换行尾。在这种情况下,如果你决定自己编写转换代码,请注意以下事项: 1. 行尾可能是 \n 2. 或 \r\n 3. 甚至是 \r(Mac!) 4. 真是够了,有些行可能是 \r\n,而另一些行是 \n,除非你控制了 CSV 的来源,否则任何组合都有可能出现
好吧,好吧。第四种情况有点牵强附会。虽然这种情况在电子邮件中会发生,但那是另一回事。
\n
会自动替换为\r\n
,因此需要其他解决方法才能获得单独的LF。 - underscore_d问题就在这里。Unix使用LF(ctrl-J),MS-DOS/Windows使用CR/LF(ctrl-M/Ctrl-J)。
当你在Unix上使用'\n'时,它会被转换为LF字符。在MS-DOS/Windows上,它会被转换为CR/LF。当你的导入程序运行在Unix格式的文件上时,它只看到一个LF。因此,通常最好先将文件通过unix2dos运行。但正如你在原始问题中所说,你不想这样做(我假设你不能这样做有一个很好的理由)。
为什么你不能这样做:
(ROWTERMINATOR = CHAR(10))
(ROWTERMINATOR =
)