PRB:SQL Server ODBC 驅動程式將語言事件轉換為 Unicode

文章翻譯 文章翻譯
文章編號: 234748 - 檢視此文章適用的產品。
本文曾發行於 CHT234748
全部展開 | 全部摺疊

徵狀

若您使用 MDAC 2.1 或更早版本 的 SQL 伺服器 ODBC 驅動程式 (3.70.0623 或更早版本) 或 OLEDB 提供者 (7.01.0623 或更早版本),在某些情況下會產生用戶端字碼頁被轉譯成伺服器字碼頁的情形,甚至連線停用自動轉譯 (Autotranslation) 功能時亦然。

發生的原因

自動轉譯不是唯一可進行字碼頁轉換的機制。若連線到 MSDE 1.0、SQL Server 7.0 或更新的版本時,SQL Server 7.0 的 ODBC 驅動程式及 OLEDB 提供者具有新的執行方式。所有作為語言事件方式傳送的 SQL 陳述式,在被傳送至伺服器之前,都會在用戶端先轉為 Unicode。它的最終結果與從使用者到伺服器的資料傳輸語言事件相似,無論連線的自動轉譯設定為何。這並不會產生任何問題,除非是要從 SQL 伺服器以外的字碼頁儲存未轉譯的字元資料。

其他可行方案

請勿將字碼頁 X 的資料存入字碼頁 Y 的 SQL Server (例如將字碼頁 950 的資料存入字碼頁 1252 的伺服器)。若使用舊版的 SQL Server,這在某些情形下是可行的,但事實上本程式並不支援。在 1252 SQL Server 中,唯有 1252 字元是合法的字元資料。來自不同字碼頁的非 Unicode 字元資料無法正確排序,而雙位元組 (DBCS) 資料,SQL Server 則無法正確地辨識其字元界線。上述狀況可能造成嚴重問題,包括下列 Microsoft 知識庫文件中所描述之狀況:
155723INF:SQL Server 截斷 DBCS 字串
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 事件的轉譯,亦可藉由關閉自動轉譯功能而停用。下面這個簡單 的 Script 說明了這種行為如何影響語言事件的流動。此範例是從字碼頁 1252 用戶端連線到字碼頁 437 伺服器的 Query Analyzer 上執行的:

    -- 關閉自動轉譯功能。
    使用 tempdb
    GO
    CREATE TABLE t1 (c1 int, c2 char(1))
    GO
    
    -- 使用 ALT-0165 鍵輸入日圓符號
    INSERT INTO t1 VALUES (1, '?') 
    SELECT c1, c2, ASCII (c2) FROM t1
  •         c1          c2               
            ----------- ---- ----------- 
            1           ?    157
            
            (1 row(s) affected)
    
    
    					

請注意下列有關上述範例的說明:

  • 雖然在這個批次指令中,自動轉譯功能是關閉的,字元碼 165 (字碼頁 1252 中的日圓符號) 還是會被轉換成 157 (字碼頁 437 中的日圓符號)。這是因為 ODBC 驅動程式在將 SQL 字串傳送到伺服器前,會先將它轉換成 Unicode,如此伺服器才能將它再轉成適當的字元儲存於字碼頁 437。
  • 當使用者執行 SELECT 以擷取剛剛儲存的資料時,字元 157 會以未經轉譯的模式出現在用戶端 (157 以 "?" 的形式出現在 字碼頁 1252 的用戶端)。這是因為本文所提到的轉換只適用於從用戶端至伺服器的資料傳送,不適用於反向的資料傳送。資料未被翻譯的原因,是因為自動轉譯設定為關閉。

    
    -- 執行下列批次指令前重新開啟自動轉譯功能。
    INSERT INTO t1 VALUES (2, '¥')    
    SELECT c1, c2, ASCII (c2) FROM t1
        c1          c2               
        ----------- ---- ----------- 
        1           ?    157
        2           ?    157
        
        (2 row(s) affected)


					
此處重新啟用自動轉譯功能並不影響從用戶端至伺服器的轉譯 (即字元碼 165 一樣被正確地轉譯成字元碼 157),但對於從伺服器擷取的資料卻會產生影響。請注意,這次執行 SELECT 陳述式時 (自動轉譯功能開啟) ,日圓符號正確地顯示在字碼頁 1252 應用程式中,因為自動轉譯功能已將此碼從字元碼 157 轉回字元碼 165。

這種情況 (語言事件在用戶端被轉譯為 Unicode) 會發生在使用任何 SQL Server ODBC 驅動程式 3.70 版或更新版本,並連線至 SQL Server 7.0 或更新的版本之時。若使用舊版本的 ODBC 驅動程式或 3.7 版驅動程式連線至 SQL Server 6.5 或更舊版本,則不會發生此現象。另外,若您將資料存放在 Unicode 資料行 (NCHAR/NVARCHAR/NTEXT),文字轉換也不會有問題。 本文件是根據Microsoft Knowledgebase 文件編號 Q234748 翻譯的。若要參考原始英文文件內容,請至以下網址:

http://support.microsoft.com/support/kb/articles/Q234/7/48.asp

屬性

文章編號: 234748 - 上次校閱: 2004年9月22日 - 版次: 1.0
這篇文章中的資訊適用於:
  • Microsoft SQL Server 7.0 Standard Edition
  • Microsoft SQL Server 2000 Standard Edition
關鍵字:?
kbtshoot KB234748
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com