如果客戶端代碼頁與伺服器代碼頁不同,則無法使用 SQL Server ODBC 驅動程式,將字元數據從客戶端正確地轉譯為伺服器

本文可協助您解決在使用 SQL Server ODBC 驅動程式時導致客戶端資料不正確轉譯的問題。

原始產品版本: SQL S
原始 KB 編號: 234748

徵狀

使用 MDAC 2.1 或更新版本的 SQL Server ODBC 驅動程式 (3.70.0623 版或更新版本) 或 OLEDB 提供者 (7.01.0623 版或更新版本) 時,在某些情況下,您可能會遇到將字元數據從用戶端代碼頁轉譯至伺服器代碼頁的情況,即使Autotranslation已停用聯機也一樣。

原因

Autotranslation 不是唯一會導致代碼頁轉換的機制。 SQL Server 7.0 ODBC 驅動程式和 OLEDB 提供者在連線到 MSDE 1.0、SQL Server 7.0 或更新版本時,都會導入新的行為。 所有以語言事件傳送的 SQL 語句都會在傳送至伺服器之前,先轉換成用戶端上的 Unicode。 結束效果類似於 Autotranslation 透過語言事件從用戶端流向伺服器的所有數據,不論連線目前的 Autotranslation 設定為何。 除非嘗試從代碼頁儲存非 SQL Server 代碼頁的非翻譯字元數據,否則不會造成任何困難。

因應措施

請勿將代碼頁 X 資料儲存在代碼頁 Y SQL Server (例如代碼頁 1252 伺服器) 中的代碼頁 950 數據。 雖然在某些情況下,舊版 SQL Server 可能會發生這種情況,但一律不支援。 若為 1252 SQL Server,1252 字元以外的任何專案都不是有效的字元數據。 來自不同代碼頁的非 Unicode 字元數據將無法正確排序,如果是雙位元組 (DBCS) 資料,SQL Server 將無法正確辨識字元界限。 這可能會造成嚴重的問題。

SQL Server 代碼頁的最佳選擇是將存取伺服器之用戶端的代碼頁。

伺服器和用戶端可能會有不同的代碼頁,但您必須確定已在用戶端上啟用自動傳輸,以便在所有情況下,在伺服器的代碼頁中正確地轉譯數據。

如果您的伺服器必須儲存來自多個代碼頁的數據,支持的解決方案是將數據儲存在 Unicode 資料行中, (NCHAR/NVARCHAR/NTEXT) 。

如果您的情況需要將代碼頁 X 資料儲存在代碼頁 Y SQL Server,則只有兩種方式可以可靠地執行這項操作:

  • 將數據儲存在二進位數據行 (BINARY/VARBINARY/IMAGE) 數據行中。
  • 撰寫您的應用程式,以針對處理字元數據的所有 SQL 語句,使用遠端過程調用 (RPC) 。 透過 RPC 事件傳送的數據不受轉換所約束。 在驅動程式或 DSN 層級,您無法變更要傳送的事件類型。 命令是以語言或 RPC 事件傳送,完全取決於撰寫應用程式時程式設計人員所選擇的 API 和語法。

其他相關資訊

自動傳輸 (也就是,在較新的 ODBC 應用程式中執行 字元數據的 翻譯複選框) 將字元數據從用戶端代碼頁轉換成伺服器代碼頁,然後再使用 Unicode 做為翻譯媒體將數據傳送至伺服器。 不過,3.7 SQL Server ODBC 驅動程式也會先將所有以語言事件傳送的 SQL 語句轉換成 Unicode,再將它們放在網路上,其效果類似於自動傳輸,但不受自動傳輸設定所控管。 相反地,從伺服器流回用戶端的字元數據會採用自動傳輸旗標;如果自動傳輸已關閉,則數據會以與伺服器上數據相同的字元碼抵達用戶端應用程式。 同樣地,關閉自動傳輸可以停用客戶端對伺服器 RPC 事件的數據轉譯。 示範行為如何影響語言事件的簡單腳本。 此範例是從連線到代碼頁 437 伺服器的代碼頁 1252 用戶端上的查詢分析器執行:

-- Turn Autotranslation off here.
 USE tempdb
 GO
 CREATE TABLE t1 (c1 int, c2 char(1))
 GO

-- Enter a yen character, using the keystroke ALT-0165.
 INSERT INTO t1 VALUES (1, '¥') 
 SELECT c1, c2, ASCII (c2) FROM t1
c1 c2 
 ----------- ---- ----------- 
 1  157

(1 row(s) affected)

上述範例的下列相關信息:

  • 雖然 Autotranslation 在此批次期間已關閉,但代碼頁 1252) 中的字元碼 165 (已轉換成 157 (代碼頁 437) 。 這是因為 ODBC 驅動程式在將 SQL 字串傳送至伺服器之前,已將它轉換成 Unicode,因此伺服器能夠將它轉換成適當的字元,以便在代碼頁 437 中儲存。
  • 當用戶端執行 SELECT 來擷取已儲存的數據時,字元 157 未翻譯到用戶端 (157 會顯示為代碼頁 1252 用戶端) 上的方塊 ''。 這是因為本文中討論的轉換只適用於從用戶端傳送到伺服器的數據,而非從伺服器傳送到客戶端的數據。 數據未轉譯, Autotranslation 因為設定已關閉。
-- Turn Autotranslation back on before running the following batch.
 INSERT INTO t1 VALUES (2, '¥')
 SELECT c1, c2, ASCII (c2) FROM t1
c1 c2 
 ----------- ---- ----------- 
 1 ¥ 157
 2 ¥ 157

(2 row(s) affected)

在此情況下,重新開啟 Autotranslation 不會影響從用戶端到伺服器 (的翻譯,也就是說,從字元碼 165 到字元碼 157 的相同正確翻譯) ,但它確實會影響從伺服器擷取的數據。 這次執行 SELECT 語句時, (Autotranslation 與 on) ,因為機制已將這些符號從字元碼 157 轉譯回字元碼 165 Autotranslation ,所以在代碼頁 1252 應用程式中會正確顯示。

使用任何 SQL Server ODBC 驅動程式 3.70 版或更新版本並連線到 SQL Server 7.0 或更新版本時,您會在用戶端) 上看到 (將語言事件轉換成 Unicode 的行為。 使用較舊的 ODBC 驅動程式,或使用 3.7 驅動程式連線到 SQL Server 6.5 或更早版本時,不會發生此情況。 此外,如果您將資料儲存在 Unicode 資料行中 (NCHAR/NVARCHAR/NTEXT) 轉換將不會是問題。

如需如何在 2005 SQL Server 中表示字元數據的詳細資訊,請參閱用戶端電腦的代碼頁與 SQL Server 2005 中資料庫的代碼頁不同時,字元數據的表示方式不正確