【问题标题】:Insert rows with Unicode characters using BCP使用 BCP 插入带有 Unicode 字符的行
【发布时间】:2017-05-21 07:26:37
【问题描述】:

我正在使用 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 字符?

【问题讨论】:

  • 只是检查,但您在目标表中使用nvarchar 数据类型,对吗? varchardata 类型不支持 unicode,而 nvarchar 支持。 ncharcharntexttext 相同
  • @SqlZim 是的,我正在使用 NVARCHAR。在本地数据库实例上使用 BULK INSERT 插入相同的 CSV 文件没有相同的问题。

标签: sql-server unicode azure-sql-database bulkinsert bcp


【解决方案1】:

但是 data.csv 是 UTF8 编码的

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 是“代码页”,65001 是 UTF-8 的代码页。

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

版本 13 (SQL Server 2016) 之前的版本不支持代码页 65001(UTF-8 编码)。以 13 开头的版本可以将 UTF-8 编码导入 SQL Server 的早期版本。

更新

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

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

【讨论】:

    【解决方案2】:

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

    我很难弄清楚 SQL Server 2014 的 UTF 和 Unicode。我正在使用 Powershell 使用 BCP 上传到 SQL Server 2014 SP2 数据库。我的文件是荷兰语,UTF-8,没有 BOM。我使用 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 的模板文件都不起作用。

    【讨论】:

    • 您好。仅供参考:如果您使用的是 SQL Server 2014 SP2,那么您已经拥有原生 UTF-8 支持,并且不需要先转换文件 :-)。您可以只使用-c -C 65001 命令行选项。似乎这是在 SQL Server 2016 发布后,在 SQL Server 2014 的 SP2 中添加的。我在答案中添加了指向知识库文章的链接。
    猜你喜欢
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 2013-07-05
    • 2020-05-02
    • 1970-01-01
    • 2017-08-25
    相关资源
    最近更新 更多