Sql-Server

在 Python 中檢索到的 SQL Server VARCHAR 列的編碼問題

  • February 12, 2018

我們最近遇到了與在 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您可以通過(包括NCHARand NTEXT,但永遠不要使用NTEXT)和獲得 UTF-16 Little Endian (LE) XML,或者基於程式碼頁,通過VARCHAR(包括CHARand TEXT,但永遠不要使用TEXT)獲得一些 8 位編碼.

這裡的問題是您的程式碼錯誤地翻譯了 0x82 字元,認為它是 UTF-8,但事實並非如此。沒有值為 0x82 的 UTF-8“字元”,這就是為什麼您會得到“�”的“未知”/替換符號。請參閱以下 UTF-8 表,該表顯示單字節 0x82 沒有字元:

UTF-8 編碼表

正如 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 字元,這可能會干擾頁面上的其他字元。

引用自:https://dba.stackexchange.com/questions/182700