ORACLE 顯示 中文字型
客戶端為Oracle 11g 查詢中文字型 顯示亂碼
在32位作業系統下
修改 HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\KEY_OraClient11g_home1 下的 NLS_LANG值為 AMERICAN_AMERICA.UTF8
在64位作業系統下
修改 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\KEY_OraClient11g_home1 下的 NLS_LANG值為 AMERICAN_AMERICA.UTF8
分析原因:
引用網上帖子:
oracle字符集問題一般可以分為三類: 資料庫字符集, sqlplus的字符集(客戶端字符集), 終端程式的字符集(非oracle的)。
1、資料庫字符集。
資料庫字符集是所有字元問題的核心,只有資料庫本身的字符集正確了,客戶端的字符集才可能正確。這裡只的客戶端包括sqlplus以及我們自己讀資料庫的應用程式。
在定位問題時,我們需要先看看資料庫當前是什麼字符集。
1)查詢資料庫字符集
select * from nls_database_parameters
其中 nls_language表示了顯示方式, 就是sqlplus的程式的顯示字型,有SIMPLIFIED CHINESE,American america
其中 nls_characterset是字符集設定, 常用的一些字符集有UTF8,US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK, AL32UTF8
2)修改資料庫字符集
當發現數據庫字符集不正確時,如我們期望時GBK的,而資料庫當前是其他的,從而引起中文亂碼。這時我們需要修改資料庫字符集。步驟如下:
$sqlplus /nolog
SQL>conn / as sysdba;
若此時資料庫伺服器已啟動,則先執行SHUTDOWN IMMEDIATE命令關閉資料庫伺服器,然後執行以下命令:
SQL>STARTUP MOUNT;
SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0;
SQL>ALTER DATABASE OPEN;
SQL>ALTER DATABASE CHARACTER SET ZHS16GBK;
SQL>ALTER DATABASE national CHARACTER SET ZHS16GBK;
SQL>SHUTDOWN IMMEDIATE;
SQL>STARTUP
2 客戶端字符集
1)查詢客戶端字符集
select * from nls_instance_parameters
客戶端字符集環境select * from nls_instance_parameters,其來源於v$parameter,
表示客戶端的字符集的設定,可能是引數檔案,環境變數或者是登錄檔
select userenv('language') from dual;
會話字符集環境 select * from nls_session_parameters,其來源於v$nls_parameters,表示會話自己的設定,可能是會話的環境變數或者是alter session完成,如果會話沒有特殊的設定,將與nls_instance_parameters一致。
客戶端的字符集要求與伺服器一致,才能正確顯示資料庫的非Ascii字元。如果多個設定存在的時候,alter session>環境變數>登錄檔>引數檔案
字符集要求一致,但是語言設定卻可以不同,語言設定建議用英文。如字符集是zhs16gbk,則nls_lang可以是American_America.zhs16gbk。 或者.zhs16gbk。注意zhs16gbk前面那個點是必須的哦!!
2) 修改客戶端字符集
oracle 的sqlplus會去讀取OS中環境變數下的nls_lang資訊(關鍵在這裡,通過以上命令檢視
select * from nls_database_parameters 顯示
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
select * from nls_instance_parameters 顯示
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_SORT
NLS_DATE_LANGUAGE
NLS_DATE_FORMAT
NLS_CURRENCY
select * from nls_session_parameters 顯示
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY RMB
也就是說會話字符集與終端字符集一致,而與資料庫字符集設定不一致。
另一個數據庫例項sc
資料庫字符集
select * from nls_database_parameters 顯示
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
select * from nls_instance_parameters 顯示
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_SORT
NLS_DATE_LANGUAGE
NLS_DATE_FORMAT
NLS_CURRENCY
在linux下
select * from nls_session_parameters 顯示
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
用TOD 在windows下顯示
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY RMB
這個我還搞不明白為什麼windows與linux會話字符集為什麼不一樣。
更搞不明白的是為什麼兩個資料庫例項用同一個系統使用者查詢的,也就是說環境變數是一樣的,但查詢結果終端字符集為什麼會不一樣?初步分析(當然不一定對,歡迎指正)是兩個資料庫例項的引數檔案不一致引起的,因為alter session>環境變數>登錄檔>引數檔案,也就是說因為環境變數沒有設定,但sc與st資料庫例項引數檔案不同,但是引數檔案在什麼地方設還不清楚,有高手歡迎指點!
但基本上問題鎖定是因為終端字符集與資料庫字符集不一致引起,在使用者的環境變數中增加
export NLS_LANG=AMERICAN_AMERICA.UTF8
export LANG=en_US.UTF-8
問題解決
再次檢視客戶端字符集
select * from nls_instance_parameters 還是顯示
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_SORT
NLS_DATE_LANGUAGE
NLS_DATE_FORMAT
NLS_CURRENCY
但
select * from nls_session_parameters 顯示
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
看來只要本次會話字符集正確就沒問題了,經過驗證確實如此,用
alter session set NLS_LANGUAGE=‘AMERICAN’後本次會話也不會出現亂碼的。
)
NSL_LANG包括三個部分(語言_地區.字符集)就是V$NLS_PARAMETERS表中的NLS_LANGUAGE,NLS_TERRITORY,NLS_CHARACTERSET
例如可以在cmd中鍵入
set nls_lang="Simplified chinese_china.utf8"
set nls_lang="american_america.us7ascii"
set nls_lang="american_america.zhs16gbk"
set nls_lang="Simplified chinese_china.zhs16gbk"
set nls_lang=".utf8"
set nls_lang=".zhs16gbk"
set nls_lang=".us7ascii"
unix下類似, 不過nls_lang要大寫NLS_LANG, 在.profile或這.bash_profile(根據你用的shell)裡更改NLS_LANG可以長久保持環境變數值.
3、終端字符集
如果資料庫字符集和sqlplus的字符集一致, 還是不能正確顯示了, 那很可能就是你的終端應用程式的字符集不支援了. 例如你用bash登陸sqlplus, 如果你的bash是個小字符集, 那麼就不能正常顯示了.linux修改bash的字符集, 可以先鍵入locale, 看有哪些環境變數, 再用export設定.