摘自:http://dev.tot.name/db/html/20090321/20090321223657.htm
摘 要 字元集的設定不當是影響ORACLE資料庫漢字顯示的關鍵問題。本文從實踐經驗出發,介紹了ORACLE關於字元集的分類、構成及設定方法,分析了ORACLE資料庫漢字顯示亂碼的常見現象及原因,並針對各種現象及原因提出了行之有效解決辦法。
關鍵字 ORACLE 字元集 亂碼解決
1 引言 ORACLE資料庫作為業界領先的資料庫產品,近年來在國內大中型企業中得到了廣泛的應用。雖然ORACLE資料庫產品本身在本地化方面已做得相當成熟,但還是有不少使用者反應漢字顯示亂碼的問題。如對同一資料庫不同的使用者對同一表中的username查詢卻得出了不同的結果: “ORACLE??????”和“ORACLE中國有限公司”,顯然結果中將中文字元顯示為亂碼,那麼為什麼呢?字元集的設定不當是影響ORACLE資料庫漢字顯示的關鍵問題。2 關於字元集 字元集是ORACLE為適應不同語言文字顯示而設定的。用於漢字顯示的字元集主要有ZHS16CGB231280、ZHS16GBK、US7ASCII和UTF-8等。字元集同時存在於伺服器端和用戶端。伺服器端字元集是在安裝ORACLE時指定的,字元集登記資訊儲存在ORACLE資料庫字典的V$NLS_PARAMETERS表中;而用戶端字元集是在系統註冊表(WINDOWS系統)或在使用者的環境變數(UNIX系統)中設定的。3 字元集的構成與設定 字元集的構成與設定方式分為用戶端與伺服器端兩種: (1)用戶端字元集的構成與設定。用戶端的字元集是由目前使用者的環境變數NLS_LANG設定的。環境變數NLS_LANG的構成:NLS_LANG=language_territory.charset 其中,language 指定伺服器訊息的語言territory 指定伺服器的日期和數字格式charset 指定字元集三個成分可以任意組合,例如:AMERICAN_AMERICA.US7SCIISIMPLIFIED CHINESE_CHINA.ZHS16GBKAMERICAN_AMERICA. ZHS16GBK 用戶端字元集的設定方法針對不同作業系統設定方法稍有不同:WINDOWS系統是在登錄機碼:HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0\NLS_LANG中設定;UNIX系統是在目前使用者的環境變數中設定,如在目前使用者的profile檔案中增加一行如下代碼:NLS_LANG=SIMPLIFIED Chinese_CHINA.ZHS16GBK;export NLS_LANG (2)服務端字元集的構成與設定。服務端字元集的構成體現在資料字典表V$NLS_PARAMETERS的NLS_LANGUAGE、NLS_TERRITORY、NLS_CHARACTERSET三項取值上,其中NLS_CHARACTERSET的取值就是具體的資料庫字元集。如利用查詢語句SQL>SELECT * FROM V$NLS_PARAMETERS;可得到如下結果:PARAMETER VALUE------------------------------------------------------------NLS_LANGUAGE SIMPLIFIED CHINESENLS_TERRITORY CHINA……NLS_CHARACTERSET ZHS16GBK…… 即當前資料庫使用的字元集是ZHS16GBK。 資料庫服務端的字元集是在建立資料時設定的。但可通過如下方法對已設定的字元集進行修改: 方法一:重建資料庫。建立資料庫時將資料庫的字元集設定為所需字元集。 方法二:修改SYS.PROPS$表。即用SYS使用者登陸ORACLE後,利用下面語句修改相應的字元集並提交:SQL>UPDATE PROPS$ SET VALUE$=’ZHS16GBK‘WHERE NAME=’NLS_CHARACTERSET’;SQL>COMMIT; 通過此種方法來更改資料庫字元集,只對更改後的資料有效,即資料庫中原來的資料仍以原字元集被儲存。 另外,有的還利用CREATE DATABASE CHARACTER SET ZHS16GBK命令暫時的修改字元集,當重啟資料庫後,資料庫字元集將恢複原來的字元集。4 常見的漢字亂碼問題及解決方案 要在用戶端正確顯示ORACLE資料庫中的漢字資訊,首先必須使用戶端的字元集與伺服器端的字元集一致;其次是載入到ORACLE資料庫的資料字元集必須與伺服器字元集一致。據此,漢字顯示亂碼的問題大致可以分為以下幾種情況: (1)用戶端字元集與伺服器端字元集不同,伺服器端字元集與載入資料字元集一致。這種情況是最常見的,只要把用戶端的字元集設定正確即可。具體解決方案: 第一步:查詢V$NLS_PARAMETERS得到服務端的字元集:SQL>SELECT * FROM V$NLS_PARAMETERS;PARAMETER VALUE-----------------------------------------------------NLS_LANGUAGE SIMPLIFIED CHINESENLS_TERRITORY CHINA ……………………NLS_CHARACTERSET ZHS16GBK …………………… 第二步:根據服務端的字元集設定用戶端的字元集,設定方法參見用戶端的字元集的設定方式。以UNIX系統為例,可在目前使用者的profile檔案中增加如下兩行: NLS_LANG=SIMPLIFIED Chinese_CHINA.ZHS16GBK export NLS_LANG (2)用戶端字元集與伺服器端字元集相同,伺服器端字元集與載入資料字元集不一致。這種情況一般發生在ORACLE版本升級或重新安裝資料庫時選擇了與原來資料庫不同的字元集,而恢複載入的備份資料仍是按原字元集卸出的場合。另一種情況是載入從其它使用不同字元集的ORACLE資料庫卸出的資料。在這兩種情況中,不管用戶端字元集與伺服器端字元集是否一致都無法正確顯示漢字。具體解決方案: 方案一:按服務端字元集的修改方法修改服務端字元集與載入資料字元集一致,然後匯入資料。 方案二:利用資料格式轉儲,避開字元集帶來的問題。即先將載入資料倒入到與其字元集一致的資料庫中,然後再將資料要麼按文字格式設定匯出(資料量較小的情況下),要麼通過第三方工具(如POWER BUILDER,ACCESS,FOXPRO等)倒出資料,最後將倒出的資料匯入到目標資料庫中。 (3)用戶端字元集與伺服器端字元集不同,服務端字元集與輸入資料字元集不同。這種情況是在用戶端字元集與伺服器端字元集不一致時,從用戶端輸入了漢字資訊。輸入的這些資訊即便是把用戶端字元集更改正確,也無法顯示漢字。解決方案:修改用戶端字元集與服務端字元集一致後,重新輸入資料。5 結束語 根據ORACLE官方文檔的說明,一旦資料庫建立後,資料庫的字元集是不能改變的。因此,提前考慮自己的資料庫將選用哪一種字元集是十分重要的。資料庫字元集選擇的一般規則是將資料庫字元集設定為作業系統本地字元集的一個超集,同時資料庫字元集也應該是所有客戶字元集的超集。如同樣是中文環境,在選擇ZHS16CGB231280還是ZHS16GBK時,我們更多的情況是選擇ZHS16GBK,因為它包含了ZHS16CGB231280字元集。參考文獻 1 (美)JONATHAN GENNICK CAROL MCCULLOUGH-DIETER GERRIT-JAN LINKER ,譯者:趙豔勤, 劉冠英, 秦玉傑 等.《ORACLE8I DBA寶典》.電子工業出版社 2 JASON COUCHMAN,SUDHEER MARISETTI.《OCP ORACLE9I DATABASE:FUNDAMENTALS I EXAM GUIDE》.出版社: MCGRAW-HILL 3 ORACLE Corporation.ORACLE 9i Database Administration Fundamentas I Student Guide》