在 Python 中检索到的 SQL Server VARCHAR 列的编码问题

Eri*_*ric 12 sql-server sql-server-2008-r2 utf-8 encoding python

我们最近遇到了与在 SQL Server 中存储为 varchar(120) 的字段相关的编码问题。在 SSMS 中,varchar 显示为:

“谁杀了琼本?”

但是,当它被带入python时,它显示为:

在此处输入图片说明

我从 Python 方面对此进行了研究,并没有发生什么奇怪的事情。我的理论是 SQL Server 中的 varchar 接受 UTF-8 字符,这些字符在 python 中的显示方式与 SSMS 不同。我对 SQL Server 中的编码不是很熟悉。有人可以让我知道以下内容:

  • 在 SSMS 中有没有办法查看 varchar 的编码?例如,查看 \x82 而不是显示当前来自 SSMS 的逗号?
  • 我们正在使用 SQL Server 2008。有没有办法将任何 UTF-8 字符的编码更改为 ASCII 字符而不使用导入/导出工具或转储到平面文件?即我可以通过查询进行这种转换吗?
  • 有什么方法可以通过查询以编程方式识别有问题的记录(问题被定义为 ASCII 不支持的 UTF-8 字符)?

先感谢您!

使用sp_help N'table_name';我发现这个VARCHAR列的排序规则是:SQL_Latin1_General_CP1_CI_AS

Sol*_*zky 21

SQL Server 在任何情况下都不存储 UTF-8。您可以通过NVARCHAR(包括NCHARand NTEXT,但永远不要使用NTEXT) and获得 UTF-16 Little Endian (LE) XML,或者基于代码页的一些 8 位编码,通过VARCHAR(包括CHARand TEXT,但永远不要使用TEXT) .

这里的问题是您的代码错误翻译了那个 0x82 字符,认为它是 UTF-8,但事实并非如此。没有值为 0x82 的 UTF-8“字符”,这就是为什么您会得到“未知”/“?”的替换符号。请参阅以下 UTF-8 表,其中显示 0x82 的单字节没有字符:

UTF-8 编码表

正如 OP 所述,有问题的列的排序规则是SQL_Latin1_General_CP1_CI_AS,这意味着 8 位编码使用的是代码页 1252,即Windows Latin 1 (ANSI)。检查该图表(向下滚动到底部图表,因为它具有字符名称)值 0x82(在“代码点”列中查找“82”)实际上是您在 SSMS 中看到的单个低 9 引号。该字符在 UTF-8 中是一个 3 字节序列:E2 80 9A.

所有这一切意味着:您的 Python 代码需要将 SQL Server 连接的客户端编码设置为代码页 1252,或者您需要将返回字符串的编码代码页 1252更改/转换UTF-8。

当然,如果它显示在网页上,那么您可以将页面的声明字符集更改为Windows-1252,但如果那里已经存在 UTF-8 字符,则可能会干扰页面上的其他字符。