如果用戶端程式字碼頁不同于伺服器字碼頁,您無法使用 SQL Server ODBC 驅動程式,將字元資料從用戶端正確轉譯成伺服器

本文可協助您解決使用 SQL Server ODBC 驅動程式時導致用戶端資料翻譯錯誤的問題。

原始產品版本:   Sqlserver
原始 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 字碼頁的最佳選擇是將存取伺服器之用戶端的程式字碼頁面。

伺服器和用戶端可能會有不同的字碼頁,但是您必須確定用戶端上已啟用 Autotranslation,這樣就能在任何情況下,從伺服器的程式字碼頁中正確地轉譯資料。

如果您的伺服器必須從多個程式字碼頁儲存資料,支援的解決方案是以 Unicode 欄 () 儲存資料 NCHAR/NVARCHAR/NTEXT

如果您的情況需要在程式字碼頁 Y SQL Server 中儲存程式字碼頁 X 資料,則只有兩種方式可以進行可靠的:

  • 將資料儲存在二進位資料欄中 () 資料行 BINARY/VARBINARY/IMAGE
  • 編寫應用程式以使用遠端程序呼叫 (RPCs) 所有處理字元資料的 SQL 語句。 透過 RPC 事件傳送的資料不會受到轉換。 驅動程式或 DSN 層級沒有任何專案可以變更所傳送之事件種類的專案。 命令是否以語言或 RPC 事件形式傳送,都完全取決於程式師在寫入應用程式時所選擇的 APIs 和語法。

詳細資訊

Autotranslation (也就是更新的 ODBC 應用程式中的 字元資料核取方塊執行轉譯) 會在將資料傳送至伺服器之前,將字元資料從用戶端程式字碼頁轉換成伺服器字碼頁,使用 Unicode 做為轉譯媒介。 不過,3.7 SQL Server ODBC 驅動程式也會將所有傳送為語言事件的 SQL 語句轉換成 Unicode,然後再將它置於連線上,其效果類似 Autotranslation,但不是由 Autotranslation 設定所控制。 相反地,從伺服器流向用戶端的字元資料會遵循 Autotranslation 旗標;如果關閉 Autotranslation 已關閉,則資料會到達用戶端應用程式,且具有與伺服器上的資料相同的字元代碼。 同樣地,您可以透過關閉 Autotranslation 來停用用戶端對伺服器 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用戶端) 上顯示為 box ' '。 這是因為本文中所討論的轉換只適用于從用戶端傳送至伺服器的資料,而不是從伺服器傳送至用戶端。 資料未轉譯,因為 Autotranslation 設定為 off。
-- 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 ,日元符號會正確顯示在字碼頁1252應用程式中,因為這些符號已從字元代碼157轉譯回由該機制的字元代碼 165 Autotranslation

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

如需在 SQL Server 2005 中如何表示字元資料的詳細資訊,請參閱 當用戶端電腦的程式字碼頁與 SQL Server 2005 中的資料庫字碼頁不同時,字元資料會不正確地呈現