EXP,IMP數據遷移字符集設置

1. 問題描述:

       數據庫之間的數據遷移是一個很常見的作業,EXP/IMP工具是一個常用的數據遷移及轉化工具,因其導出文件具有平臺無關性,所以在跨平臺遷移中,最爲常用。但在實際操作過程中,涉及到源數據庫,客戶端,目標數據庫三方面的字符集問題。操作人員對三者之間的字符集轉換過程不瞭解,而冒然使用EXP/IMP命令,往往在遷移過程中報錯終止,或是在沒有報錯的情況下成功導入,但其背後卻存在隱患,在查詢時經常顯示亂碼。

 

2.解決方法

       2.1 源端數據庫(1)→EXP客戶端(2)→IMP客戶端(3)→目標數據庫(4),數據在遷移過程中要經歷如上的4個點,數據在流動過程中(如上的3個箭頭)需要依次比較箭頭兩端的字符集,如果相同則不轉換,如果不同則進行轉換。如果相鄰的兩個點之間設置的字符集均不相同,則需要轉換3次。

 

       根據上述理論分析,最好的設置方式是,因爲(1)(4)數據庫的字符集是固定的,則設置客戶端的字符集(2)(3)均與(1)相同,這樣最多隻在(3)→(4)的過程中發生一次字符集的轉換。但是前提是(4)的字符集必須是(1)的的字符集的超集。客戶端字符集是通過環境變量NLS_LANG來設置。

Linux: export NLS_LANG=SIMPLIFIEDCHINESE_CHINA.ZHS16GBK
Windows: set NLS_LANG=SIMPLIFIEDCHINESE_CHINA.ZHS16GBK

      EXP導出的文件,可以通過WINDOWS上的工具UE來查看,其中第一行的第2,3個字節顯示的數字代表了文件的字符集。在sqlplus裏通過select nls_charset_name() from dual;可以查看該數字代表的字符集。


03 03 54 45 58 50 4F 52 54 3A

其中,03 54是16進制的數字,代表了一種字符集。將其轉換爲10進製爲:

SQL> select to_number('0354','xxxx') from dual;
TO_NUMBER('0354','XXXX')
------------------------
                     852
查詢852代表的字符集
SQL> select nls_charset_name(852) from dual;
NLS_CHAR
--------
ZHS16GBK

當然還可以逆向操作
SQL> select nls_charset_id('ZHS16GBK') from dual;
NLS_CHARSET_ID('ZHS16GBK')
--------------------------
                       852

       2.2 ORACLE在10g以後的版本中提供了新的遷移工具EXPDP/IMPDP,此工具無需設置客戶端字符集,而是由ORACLE自動去識別並完全字符集的轉換。這是因爲EXPDP/IMPDP並不是完整意義上的客戶端,它和EXP/IMP/sqlplus並不完全一樣。它只是向oracle傳輸了一個命令,oracle在內部生成一個任務,文件只能導出在服務器上,而不能像exp/imp一樣將文件導出到遠程端。但前提依然是,目標數據庫的字符集應是源數據庫字符集的超集。

 

      其實,在使用exp/imp,expdp/impdp時,並不一定要嚴格要求目的數據庫是源數據庫的超集。問題的關鍵之處在於源端的字符能在目的端找到對應的字符。在不同字符集的數據庫傳輸之前,我們最好通過oracle提供的csscan工具來檢查兩個字符集之間是否可以轉換。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章