使用 BCP 插入带有 Unicode 字符的行

Insert rows with Unicode characters using BCP

我正在使用 BCP 将数据从 CSV 文件批量上传到 SQL Azure(因为不支持 BULK INSERT)。此命令运行并上传行:

bcp [resource].dbo.TableName in C:\data.csv -t "," -r "0x0a" -c -U bcpuser@resource -S tcp:resource.database.windows.net

但是 data.csv 是 UTF8 编码的并且包含非 ASCII 字符串。这些被破坏了。我尝试将 -c 选项更改为 -w:

bcp [resource].dbo.TableName in C:\data.csv -t "," -r "0x0a" -w -U bcpuser@resource -S tcp:resource.database.windows.net

但是我得到“复制了 0 行”。

我做错了什么以及如何使用 BCP 批量插入 Unicode 字符?

But data.csv is UTF8 encoded

UTF-8 编码是主要问题。使用 -w 无济于事,因为在 Microsoft 领域,术语 "Unicode" 几乎总是指 UTF-16 Little Endian。

解决方案将取决于您使用的 BCP 版本,因为在最新版本 (13.0 / 2016) 中添加了一个选项:

  • 如果您使用的是 SQL Server 2016(版本 13.0)之前的 SQL Server 附带的 BCP,那么您需要将 csv 文件转换为 UTF-16 Little Endian (LE) 是 Windows / SQL Server / .NET 用于所有字符串的。并使用 -w 开关。

    我在 Notepad++ 中将文件编码为 "UCS-2 LE BOM",而使用 -c 开关时相同的导入文件失败。

  • 如果您使用的是 SQL Server 2016(版本 13.0)或更高版本附带的 BCP,则只需将 -c -C 65001 添加到命令行即可。 -C用于"code page",65001是UTF-8的代码页。

bcp Utility 的 MSDN 页面指出(在 -C 开关的解释中):

Versions prior to version 13 (SQL Server 2016) do not support code page 65001 (UTF-8 encoding). Versions beginning with 13 can import UTF-8 encoding to earlier versions of SQL Server.

更新

已通过 SP2 将对 UTF-8/代码页 65001 的支持添加到 SQL Server 2014,如这篇 Microsoft 知识库文章所述:

UTF-8 encoding support for the BCP utility and BULK INSERT Transact-SQL command in SQL Server 2014 SP2

Solomon 的回答帮助我解决了与 Unicode 和 SQL Server 2014 的斗争。我想在这里分享我关于 Unicode 的经验。我希望这可以帮助下一个遇到 BCP Unicode 问题的人。

我很难弄清楚 SQL Server 2014 的 UTF 和 Unicode。我正在使用 Powershell 使用 BCP 上传到 SQL Server 2014 SP2 数据库。我的文件是荷兰语,没有 BOM 的 UTF-8。我使用 Powershell 将文件转换为微软的 Unicode:

Get-ChildItem "C:\Documents\ProjectA" -filter *.CSV |
ForEach-Object {
    $path = $_.basename + '.unicode.CSV' 
    get-content $_ | Set-Content -Encoding Unicode -path $path 
}

然后我使用没有格式文件的BCP:

Get-ChildItem "C:\Documents\ProjectA" -filter *.unicode.CSV |
 ForEach-Object { 
   try { $output = bcp ProjectA.dbo.auditlog in $_.FullName -w "-t," -T -F2 
            if ($LASTEXITCODE)
            {  throw $output
            }
    catch
    { $Output >> C:\Documents\ProjectA\BCPCommandFailed$(get-date -f yyyy-MM-dd).log
    }
}

转换为 Unicode 导致文件大小加倍,例如从 11,630KB 变为 23,259KB。模板文件无论是 XML 还是非 XML 都不起作用。