Oracle 字符集的查看和修改【下】


查看數據庫字符集
涉及三方面的字符集,
1. oracel server端的字符集;
2. oracle client端的字符集;
3. dmp文件的字符集。
 
在做數據導入的時候,需要這三個字符集都一致才能正確導入。
 
4.1 查詢oracle server端的字符集
有很多種方法可以查出oracle server端的字符集,比較直觀的查詢方法是以下這種:
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
 
SQL>select userenv(‘language’) from dual;
AMERICAN _ AMERICA. ZHS16GBK
 
4.2 如何查詢dmp文件的字符集
oracleexp工具導出的dmp文件也包含了字符集信息,dmp文件的第2和第3個字節記錄了dmp文件的字符集。如果dmp文件不大,比如只有幾M或幾十M,可以用UltraEdit打開(16進制方式),看第23個字節的內容,如0354,然後用以下SQL查出它對應的字符集:
SQL> select nls_charset_name(to_number('0354','xxxx')) from dual;
ZHS16GBK
 
如果dmp文件很大,比如有2G以上(這也是最常見的情況),用文本編輯器打開很慢或者完全打不開,可以用以下命令(unix主機上):
cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6
然後用上述SQL也可以得到它對應的字符集。
 
4.3 查詢oracle client端的字符集
windows平臺下,就是註冊表裏面相應OracleHomeNLS_LANG。還可以在dos窗口裏面自己設置,
比如: set nls_lang=AMERICAN_AMERICA.ZHS16GBK
這樣就隻影響這個窗口裏面的環境變量。
 
unix平臺下,就是環境變量NLS_LANG
$echo $NLS_LANG
AMERICAN_AMERICA.ZHS16GBK
 
如果檢查的結果發現server端與client端字符集不一致,請統一修改爲同server端相同的字符集。
 
補充:
(1).數據庫服務器字符集
select * from nls_database_parameters
來源於props$,是表示數據庫的字符集。
 
(2).客戶端字符集環境
select * from nls_instance_parameters
其來源於v$parameter,表示客戶端的字符集的設置,可能是參數文件,環境變量或者是註冊表
 
(3).會話字符集環境
select * from nls_session_parameters
來源於v$nls_parameters,表示會話自己的設置,可能是會話的環境變量或者是alter session完成,如果會話沒有特殊的設置,將與nls_instance_parameters一致。
 
(4).客戶端的字符集要求與服務器一致,才能正確顯示數據庫的非Ascii字符
如果多個設置存在的時候,NLS作用優先級別Sql function > alter session > 環境變量或註冊表 參數文件 數據庫默認參數
 
字符集要求一致,但是語言設置卻可以不同,語言設置建議用英文。如字符集是zhs16gbk,則nls_lang可以是American_America.zhs16gbk
 
 
五. 修改oracle的字符集
按照上文所說,數據庫字符集在創建後原則上不能更改。因此,在設計和安裝之初考慮使用哪一種字符集十分重要。對數據庫server而言,錯誤的修改字符集將會導致很多不可測的後果,可能會嚴重影響數據庫的正常運行,所以在修改之前一定要確認兩種字符集是否存在子集和超集的關係。一般來說,除非萬不得已,我們不建議修改oracle數據庫server端的字符集。特別說明,我們最常用的兩種字符集ZHS16GBKZHS16CGB231280之間不存在子集和超集關係,因此理論上講這兩種字符集之間的相互轉換不受支持。
 
不過修改字符集有2種方法可行。
1. 通常需要導出數據庫數據,重建數據庫,再導入數據庫數據的方式來轉換
2. 通過ALTER DATABASE CHARACTER SET語句修改字符集,但創建數據庫後修改字符集是有限制的,只有新的字符集是當前字符集的超集時才能修改數據庫字符集,例如UTF8US7ASCII的超集,修改數據庫字符集可使用ALTER DATABASE CHARACTER SET UTF8 
 
 
5.1 修改server端字符集(不建議使用)
 
1.       關閉數據庫
SQL>SHUTDOWN IMMEDIATE
 
2. 啓動到Mount
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 AL16UTF16;
--如果是從子集到父集,需要使用INTERNAL_USE 參數,跳過超子集檢測
SQL>ALTER DATABASE CHARACTER SET INTERNAL_USE AL32UTF8;
SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE AL16UTF16;
 
SQL>SHUTDOWN IMMEDIATE;
SQL>STARTUP
注意:如果沒有大對象,在使用過程中進行語言轉換沒有什麼影響,(切記設定的字符集必須是ORACLE支持,不然不能start 按上面的做法就可以。
 
若出現‘ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when NCLOB data exists’ 這樣的提示信息,
要解決這個問題有兩種方法
1. 利用INTERNAL_USE 關鍵字修改區域設置,
2. 利用re-create,但是re-create有點複雜,所以請用internal_use
 
SQL>SHUTDOWN IMMEDIATE;
SQL>STARTUP MOUNT EXCLUSIVE;
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 NATIONAL CHARACTER SET INTERNAL_USE UTF8;
SQL>SHUTDOWN immediate;
SQL>startup;
如果按上面的做法做,National charset的區域設置就沒有問題
 
5.2 修改dmp文件字符集
上文說過,dmp文件的第23字節記錄了字符集信息,因此直接修改dmp文件的第23字節的內容就可以oracle的檢查。這樣做理論上也僅是從子集到超集可以修改,但很多情況下在沒有子集和超集關係的情況下也可以修改,我們常用的一些字符集,如US7ASCIIWE8ISO8859P1ZHS16CGB231280ZHS16GBK基本都可以改。因爲改的只是dmp文件,所以影響不大。
 
具體的修改方法比較多,最簡單的就是直接用UltraEdit修改dmp文件的第2和第3個字節。
比如想將dmp文件的字符集改爲ZHS16GBK,可以用以下SQL查出該種字符集對應的16進制代碼: SQL> select to_char(nls_charset_id('ZHS16GBK'), 'xxxx') from dual;
0354
然後將dmp文件的23字節修改爲0354即可。
如果dmp文件很大,用ue無法打開,就需要用程序的方法了。
 
5.3客戶端字符集設置方法
     1)UNIX
環境
         $NLS_LANG=“simplified chinese”_china.zhs16gbk
         $export NLS_LANG
         
編輯oracle用戶的profile文件
    2)Windows
環境
         
編輯註冊表
         Regedit.exe ---
 HKEY_LOCAL_MACHINE ---SOFTWARE --- ORACLE--》HOME
  或者在窗口設置:
        set nls_lang=AMERICAN_AMERICA.ZHS16GBK
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章