在 Python 中檢索到的 SQL Server VARCHAR 列的編碼問題
我們最近遇到了與在 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
.
SQL Server 在任何情況下都不儲存 UTF-8。
NVARCHAR
您可以通過(包括NCHAR
andNTEXT
,但永遠不要使用NTEXT
)和獲得 UTF-16 Little Endian (LE)XML
,或者基於程式碼頁,通過VARCHAR
(包括CHAR
andTEXT
,但永遠不要使用TEXT
)獲得一些 8 位編碼.這裡的問題是您的程式碼錯誤地翻譯了 0x82 字元,認為它是 UTF-8,但事實並非如此。沒有值為 0x82 的 UTF-8“字元”,這就是為什麼您會得到“�”的“未知”/替換符號。請參閱以下 UTF-8 表,該表顯示單字節 0x82 沒有字元:
正如 OP 所述,有問題的列的排序規則是
SQL_Latin1_General_CP1_CI_AS
,這意味著 8 位編碼正在使用 Code Page 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 字元,這可能會干擾頁面上的其他字元。