oracle中匯入dmp字元亂碼分析和解決方案

darren__chan發表於2014-11-13

一、什麼是oracle字符集

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

影響oracle資料庫字符集最重要的引數是NLS_LANG引數。它的格式如下:

  NLS_LANG = language_territory.charset

  它有三個組成部分(語言、地域和字符集),每個成分控制了NLS子集的特性。其中:

  Language 指定伺服器訊息的語言,territory 指定伺服器的日期和數字格式,charset 指定字符集。如:AMERICAN _ AMERICA. ZHS16GBK。

從NLS_LANG的組成我們可以看出,真正影響資料庫字符集的其實是第三部分。所以兩個資料庫之間的字符集只要第三部分一樣就可以相互匯入匯出資料,前面影響的只是提示資訊是中文還是英文。
二、如何查詢Oracle的字符集
  1、查詢oracle server端的字符集

  有很多種方法可以查出oracle server端的字符集,比較直觀的查詢方法是以下這種:

SQL>select userenv(‘language’) from dual;

 結果類似如下:AMERICAN _ AMERICA. ZHS16GBK
  2、如何查詢dmp檔案的字符集

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

  SQL> select nls_charset_name(to_number('0354','xxxx')) from dual;

結果是: ZHS16GBK
  3、查詢oracle client端的字符集

在windows平臺下,就是登錄檔裡面HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0\NLS_LANG 。

如果檢查的結果發現server端與client端字符集不一致,請統一修改為同server端相同的字符集。
三、修改oracle的字符集
  1、修改server端字符集(我試過的)

  若此時資料庫伺服器已啟動,則先執行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 INTERNAL_USE ZHS16GBK(這裡為你所要轉換成的字符集); //跳過超子集檢測

  SQL>ALTER DATABASE national CHARACTER SET INTERNAL ZHS16GBK(這裡為你所要轉換成的字符集);

執行後出錯ORA-00933: SQL 命令未正確結束,不過執行上一行命令已經生效,這一句出錯對修改似乎沒有影響。

下面關閉資料庫,然後重新啟動:

  SQL>SHUTDOWN IMMEDIATE;

  SQL>STARTUP
  2、修改dmp檔案字符集(這個我沒有試,借鑑來的)

 

  上文說過,dmp檔案的第2第3位元組記錄了字符集資訊,因此直接修改dmp檔案的第2第3位元組的內容就可以‘騙’過oracle的檢查。這樣做理論上也僅是從子集到超集可以修改,但很多情況下在沒有子集和超集關係的情況下也可以修改,我們常用的一些字符集,如US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK基本都可以改。因為改的只是dmp檔案,所以影響不大。

  具體的修改方法比較多,最簡單的就是直接用UltraEdit修改dmp檔案的第2和第3個位元組。比如想將dmp檔案的字符集改為ZHS16GBK,可以用以下SQL查出該種字符集對應的16進位制程式碼:

  SQL> select to_char(nls_charset_id('ZHS16GBK'), 'xxxx') from dual;

  結果是:0354

  然後將dmp檔案的2、3位元組修改為0354即可。
3. 修改客戶端的檔案字符集和新配置一個環境變數:
1修改客戶端字符集:

執行regedit命令,在登錄檔中找到這個下的鍵HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0\NLS_LANG

將其值改為上述伺服器端你所修改的字元編碼值。
2 新配置一個環境變數

點選我的電腦右鍵》屬性》高階》環境變數》新建一個使用者變數,其變數名是:NLS_LANG;

變數值是:SIMPLIFIED CHINESE_CHINA.WE8ISO8859P1(這裡的字符集和你在伺服器端和客戶端修改的字符集必須一致)。

注意:最後一定要重啟oracle的主服務!不然亂碼問題依舊存在,這是我今天糾結了很久的問題。

總結:一般將資料庫伺服器端,客戶端,還有新配置的環境變數的值修改成和dmp文件一樣的字符集就可解決亂碼的問題!

解決方案:
在匯入DMP檔案前,在客戶端匯入與伺服器一致的環境變數。
例如:export NLS_LANG=American_America.ZHS16GBK

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29863023/viewspace-1331078/,如需轉載,請註明出處,否則將追究法律責任。

相關文章