天天看點

解決Oracle 中文亂碼

一、什麼是oracle字元集

  Oracle字元集是一個位元組資料的解釋的符号集合,有大小之分,有互相的包容關系。ORACLE 支援國家語言的體系結構允許你使用本地化語言來存儲,處理,檢索資料。它使資料庫工具,錯誤消息,排序次序,日期,時間,貨币,數字,和月曆自動适應本地化語言和平台。

SELECT * FROM V$NLS_PARAMETERS

1       NLS_LANGUAGE SIMPLIFIED CHINESE

2       NLS_TERRITORY         CHINA

3       NLS_CURRENCY RMB

4       NLS_ISO_CURRENCY CHINA

5       NLS_NUMERIC_CHARACTERS       .,

6       NLS_CALENDAR GREGORIAN

7       NLS_DATE_FORMAT     DD-MON-RR

8       NLS_DATE_LANGUAGE         SIMPLIFIED CHINESE

9       NLS_CHARACTERSET AL32UTF8

10      NLS_SORT BINARY

11      NLS_TIME_FORMAT      HH.MI.SSXFF AM

12      NLS_TIMESTAMP_FORMAT    DD-MON-RR HH.MI.SSXFF AM

13      NLS_TIME_TZ_FORMAT        HH.MI.SSXFF AM TZR

14      NLS_TIMESTAMP_TZ_FORMAT       DD-MON-RR HH.MI.SSXFF AM TZR

15      NLS_DUAL_CURRENCY        RMB

16      NLS_NCHAR_CHARACTERSET      UTF8

17      NLS_COMP         BINARY

18      NLS_LENGTH_SEMANTICS    BYTE

19      NLS_NCHAR_CONV_EXCP    FALSE

二、如何查詢Oracle的字元集

ORACLE有三方面的字元集,一是oracel server端的字元集,二是oracle client端的字元集;三是dmp檔案的字元集。在做資料導入的時候,需要這三個字元集都一緻才能正确導入。

--檢視oracel server端的字元集

select userenv('language') from dual;

1              SIMPLIFIED CHINESE_CHINA.AL32UTF8

--檢視dmp檔案的字元集

用oracle的exp工具導出的dmp檔案也包含了字元集資訊,dmp檔案的第2和第3個位元組記錄了dmp檔案的字元集。如果dmp檔案不大,比如隻有幾M或幾十M,可以用UltraEdit打開(16進制方式),看第2第3個位元組的内容,如0354,然後用以下SQL查出它對應的字元集:

select nls_charset_name(to_number('0354','xxxx')) from dual

--檢視oracel client端的字元集

  是系統資料庫裡面相應OracleHome的NLS_LANG。還可以在dos視窗裡面自己設定,比如:

  set nls_lang=AMERICAN_AMERICA.ZHS16GBK

  這樣就隻影響這個視窗裡面的環境變量。

Oracle字元集亂碼問題析及解決辦法

一、問題描述

SQL Plus WorkSheet是一個視窗圖形界面的SQL語句編輯器,對于那些喜歡視窗界面而不喜歡字元界面的使用者,該工具相對SQL/PLUS受到了很大的歡迎。但從Oracle 8i以後,如果安裝Oracle 8i時選取的是别于英語的字元集,對于我們中國,通常會選取簡體中文字元集(ZHS16GBK),安裝成功後,運作SQL Plus WorkSheet程式,會出現所有的中文顯示以及查詢結果均為亂碼的情況。

二、問題分析

最初出現該問題,首先懷疑就是安裝時字元集設定有問題,也就是說沒有設定正确的簡體中文字元集。首先檢查資料庫字元集,在SQL/PLUS中,運作下面的SQL語句,檢查所連接配接資料庫的字元集:

SQL> select userenv('language') from dual;

USERENV('LANGUAGE')

SIMPLIFIED CHINESE_CHINA.ZHS16GBK

查詢結果發現資料庫安裝時所選字元集為簡體中文ZHS16GBK,說明安裝時字元集設定完全正确。第二步開始懷疑是使用者用戶端字元集問題,檢查用戶端系統資料庫,打開系統資料庫編輯程式(RegEdit),在HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/NLS_LANG,發現Oracle用戶端字元集為AMERICAN_AMERICA.ZHS16GBK,設定也完全正确,可以排除是用戶端字元集設定錯誤的問題。同時還有一個現象就是在同一個用戶端機器上SQL/PLUS中的查詢字元集顯示完全正常,這也說明不是字元集設定問題,而是系統程式SQL/Plus Worksheet的問題。

在Oracle 8i以前的版本中,從來沒有出現過這樣的情況,這應該和Oracle版本有關,我們知道Oracle 8i和它前面的版本一個顯著的差別就是大部分的Oracle系統程式,現在均采用Java驅動,其實這也就是産生字元集亂碼問題的根本所在。非Java驅動的程式,如SQL*Plus,有一個系統參數NLS_LANG,該參數在UNIX系統中設定在環境變量中,在Windows作業系統中設定在系統資料庫中,這個參數決定了用戶端應用程式的字元集。而對于基于Java應用的程式,如現在遇到的SQL*PLus Worksheet,NLS_LANG參數對這類程式是不起任何作用的。

三、解決方案

找到了問題産生的原因後,下面來讨論如何解決該問題。對于Oracle Enterprise Manager中的所有工具,有一個配置檔案名為dbappscfg.properties,修改該檔案即可解決上述問題。這個檔案的位置在$ORACLE_HOME\sysman\config目錄下,用任何的文本編輯器打開該檔案,在這個檔案裡面,找到這樣一項,

# SQLPLUS_NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1

去掉注釋符#,同時将其修改為

SQLPLUS_NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

對于Windows作業系統,還需要修改一項,在檔案中找到# SQLPLUS_SYSTEMROOT=c:\\WINNT40,去掉注釋符,将其修改為你所在機器的作業系統主目錄。如作業系統的主目錄在D盤的Winnt下,則将其修改為

SQLPLUS_SYSTEMROOT=d:\\WINNT。

對于後面一項的修改隻對Windows作業系統進行,對UNIX作業系統則不需要。如果在Windows作業系統中不修改該項,在Oracle Enterprise Manager中,連接配接系統時,會提示如下的錯誤:

ORA-12560 TNS:protocol adapter error

或者

ORA-12545 Connect failed because target host or object does not exist

修改完成後,儲存檔案,退出編輯。重新連接配接SQL PLUS Worksheet,字元集亂碼問題得到解決,顯示正确的簡體中文字元集。

問題: 使用Oracle Instant Client 出現 ORA-12705: Cannot access NLS data files or invalid environment specified 錯誤。

如果是Windows平台,系統資料庫裡 \HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE 查找鍵 NLS_LANG,這個鍵由Oracle标準用戶端安裝建立, 值是 NA 。這個導緻了 ORA-12705錯誤。解決方法就是改名 NLS_LANG。

Linux下 如果環境變量 NLS_LANG 值是NA 會引起 ORA-12705 錯誤,解決方法是删除這個變量 

unset NLS_LANG