ORACLE EXP/IMP的使用詳解 (解決9i(window)導入到10G的亂碼問題)

導出/導入與字符集


  進行數據的導入導出時,我們要注意關於字符集的問題。在EXP/IMP過程中我們需要注意四個字符集的參數:導出端的客戶端字符集,導出端數據庫字符集,導入端的客戶端字符集,導入端數據庫字符集。

  我們首先需要查看這四個字符集參數。

  查看數據庫的字符集的信息:

  SQL> select * from nls_database_parameters;

  PARAMETER                       VALUE

  ------------------------------ --------------------------------------------------------------------------------

  NLS_LANGUAGE                    AMERICAN

  NLS_TERRITORY                    AMERICA

  NLS_CURRENCY                    $

  NLS_ISO_CURRENCY                AMERICA

  NLS_NUMERIC_CHARACTERS          .,

  NLS_CHARACTERSET                ZHS16GBK

  NLS_CALENDAR                    GREGORIAN

  NLS_DATE_FORMAT                 DD-MON-RR

  NLS_DATE_LANGUAGE               AMERICAN

  NLS_SORT                          BINARY

  NLS_TIME_FORMAT                 HH.MI.SSXFF AM

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

  NLS_TIME_TZ_FORMAT              HH.MI.SSXFF AM TZH:TZM

  NLS_TIMESTAMP_TZ_FORMAT         DD-MON-RR HH.MI.SSXFF AM TZH:TZM

  NLS_DUAL_CURRENCY               $

  NLS_COMP                        BINARY

  NLS_NCHAR_CHARACTERSET          ZHS16GBK

  NLS_RDBMS_VERSION               8.1.7.4.1

  NLS_CHARACTERSET:ZHS16GBK是當前數據庫的字符集。


我的windows oracle編碼爲:

NLS_NCHAR_CHARACTERSET        AL16UTF16
NLS_CHARACTERSET        ZHS16GBK


  我們再來查看客戶端的字符集信息:

  客戶端字符集的參數NLS_LANG=_< territory >.

  language:指定oracle消息使用的語言,日期中日和月的顯示。

  Territory:指定貨幣和數字的格式,地區和計算星期及日期的習慣。

  Characterset:控制客戶端應用程序使用的字符集。通常設置或等於客戶端的代碼頁。或者對於unicode應用設爲UTF8。

  在windows中,查詢和修改NLS_LANG可在註冊表中進行:

HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\HOMExx\

  xx指存在多個Oracle_HOME時的系統編號。

我這裏的windows默認爲:

windows Client:
NLS_LANG    SIMPLIFIED CHINESE_CHINA.ZHS16GBK


在Linux redhat5中:

[oracle@ucit ~]$ cd       注意:cd 後是空格沒有任何內容
[oracle@ucit ~]$ vi .bash_profile

加上:

export NLS_LANG="Simplified Chinese_China".ZHS16GBK    注意:四個端的參數編碼要一致


然後使用:env|grep NLS_LANG看正確沒有


  在unix中:

  $ env|grep NLS_LANG

  NLS_LANG=simplified chinese_china.ZHS16GBK

  修改可用:

  $ export NLS_LANG=AMERICAN_AMERICA.UTF8

  通常在導出時最好把客戶端字符集設置得和數據庫端相同。當進行數據導入時,主要有以下兩種情況:

  (1)     源數據庫和目標數據庫具有相同的字符集設置。

  這時,只需設置導出和導入端的客戶端NLS_LANG等於數據庫字符集即可。

  (2)     源數據庫和目標數據庫字符集不同。

  先將導出端客戶端的NLS_LANG設置成和導出端的數據庫字符集一致,導出數據,然後將導入端客戶端的NLS_LANG設置成和導出端一致,導入數據,這樣轉換隻發生在數據庫端,而且只發生一次。

  這種情況下,只有當導入端數據庫字符集爲導出端數據庫字符集的嚴格超集時,數據才能完全導成功,否則,可能會有數據不一致或亂碼出現。

  不同版本的EXP/IMP問題

  一般來說,從低版本導入到高版本問題不大,麻煩的是將高版本的數據導入到低版本中,在Oracle9i之前,不同版本Oracle之間的EXP/IMP可以通過下面的方法來解決:

  1、在高版本數據庫上運行底版本的catexp.sql;

  2、使用低版本的EXP來導出高版本的數據;

  3、使用低版本的IMP將數據庫導入到低版本數據庫中;

  4、在高版本數據庫上重新運行高版本的catexp.sql腳本。

  但在9i中,上面的方法並不能解決問題。如果直接使用低版本EXP/IMP會出現如下錯誤:

  EXP-00008: orACLE error %lu encountered

  orA-00904: invalid column name

  這已經是一個公佈的BUG,需要等到Oracle10.0才能解決,BUG號爲2261722,你可以到METALINK上去查看有關此BUG的詳細信息。

  BUG歸BUG,我們的工作還是要做,在沒有Oracle的支持之前,我們就自己解決。在Oracle9i中執行下面的SQL重建exu81rls視圖即可。

  Create or REPLACE view exu81rls

  (objown,objnam,policy,polown,polsch,polfun,stmts,chkopt,enabled,spolicy)

  AS select u.name, o.name, r.pname, r.pfschma, r.ppname, r.pfname,

  decode(bitand(r.stmt_type,1), 0,'', 'Select,')

  || decode(bitand(r.stmt_type,2), 0,'', 'Insert,')

  || decode(bitand(r.stmt_type,4), 0,'', 'Update,')

  || decode(bitand(r.stmt_type,8), 0,'', 'Delete,'),

  r.check_opt, r.enable_flag,

  DECODE(BITAND(r.stmt_type, 16), 0, 0, 1)

  from user$ u, obj$ o, rls$ r

  where u.user# = o.owner#

  and r.obj# = o.obj#

  and (uid = 0 or

  uid = o.owner# or

  exists ( select * from session_roles where role='Select_CATALOG_ROLE')

  )

  /

  grant select on sys.exu81rls to public;

  /

  可以跨版本的使用EXP/IMP,但必須正確地使用EXP和IMP的版本:

  1、總是使用IMP的版本匹配數據庫的版本,如:要導入到817中,使用817的IMP工具。

  2、總是使用EXP的版本匹配兩個數據庫中最低的版本,如:從9201往817中導入,則使用817版本的EXP工具。


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