NLS considerations in Import Export - Frequently Asked Questions (文件 ID 227332.1)

張玉龍發表於2016-10-19



NLS considerations in Import/Export - Frequently Asked Questions (文件 ID 227332.1)


使用匯出/匯入(exp/imp和expdp/impdp)時的文件字符集轉換。


For the main Globalization (NLS) FAQ please see: Note:60134.1 Globalization (NLS) - Frequently Asked Questions
For the main exp/imp FAQ please see: Note:175624.1 Oracle Server - Export and Import FAQ


1. NLS如何影響exp/imp


Imp和exp是客戶端產品,與SQL * Plus或Oracle Forms相同,
因此會將資料庫字符集中的字元轉換為NLS_LANG定義的字符集。 
用於匯出的字符集將儲存在匯出檔案中,並且在匯入檔案時,impdp將檢查使用的字符集。 
如果它與匯入環境中的NLS_LANG定義的字符集不同,則字元將被轉換為匯入環境中的字符集,然後,如有必要,轉換為資料庫字符集。


參考:
Note:15095.1  Old Exp/Imp (not datapump) and NLS Considerations
Note:48644.1  Identifying the Export Character Set


2. 如何在使用exp時設定NLS_LANG?


Oracle建議將NLS_LANG環境引數的字符集設定為與要匯出的資料庫的字符集相同
NLS_LANG=AMERICAN_AMERICA.<source db NLS_CHARACTERSET>


select value from nls_database_parameters where parameter='NLS_CHARACTERSET';


這樣,不會進行轉換,匯出建立的檔案的字符集將以與原始資料庫的字符集相同,幷包含來自原始資料庫的所有資料(即使是不正確的儲存資料)。
如果計劃將此匯入到具有不同字符集的資料庫中,可以到imp時轉換。


注意:
1). 這與作業系統沒有關係。 如果您的源資料庫是一個WE8MSWIN1252資料庫,那麼你只需要在匯入之前將NLS_LANG設定為AMERICAN_AMERICA.WE8MSWIN1252,即使在Unix伺服器上。
2). 在與資料庫(例如sqlplus)*互動*期間,您需要正確配置您的(Unix)客戶端,並且可能不同於NLS_CHARACTERSET。


3. 如何在使用imp時設定NLS_LANG?


如果源資料庫和目標資料庫具有相同的字符集,則NLS_LANG的字符集應在exp和imp時設定為相同的字符集。
NLS_LANG=AMERICAN_AMERICA.<source db NLS_CHARACTERSET>


如果匯出和匯入資料庫的字符集不同,用於exp和imp上的NLS_LANG的字符集的最佳(首選)值仍是源資料庫的字符集。
NLS_LANG=AMERICAN_AMERICA.<source db NLS_CHARACTERSET>


在imp期間將NLS_LANG設定為目標資料庫的字符集也是正確的,但是在轉到多位元組字符集(如UTF8)時匯入有一些限制,
因此在imp和exp會話期間使用SOURCE NLS_CHARACTERSET只是最好的選項,
避免任何問題,比如IMP-16“不支援所需的字符集轉換(型別%lu到%lu)”。


因此,執行轉換的首選位置是在匯入可執行檔案和目標資料庫之間。


注意:
1). 這與作業系統沒有關係。 如果您的源資料庫是一個WE8MSWIN1252資料庫,那麼你只需要在匯入之前將NLS_LANG設定為AMERICAN_AMERICA.WE8MSWIN1252,即使在Unix伺服器上。
2). 在與資料庫(例如sqlplus)*互動*期間,您需要正確配置您的(Unix)客戶端,並且可能不同於NLS_CHARACTERSET。


3 a) 仔細檢查SOURCE資料庫上的NLS_CHARACTERSET
例如:您想使用exp/imp工具從WE8MSWIN1252轉到AL32UTF8資料庫:
請注意,這只是exp/imp示例,如果要遷移到AL32UTF8或UTF8檢查Note:260192.1 Changing the NLS_CHARACTERSET to AL32UTF8 / UTF8 (Unicode) in 8i, 9i , 10g and 11g
和 Note 1297961.1 ORA-01401 / ORA-12899 While Importing Data In An AL32UTF8 / UTF8 (Unicode) Or Other Multibyte NLS_CHARACTERSET Database 。


 select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET';


匯出時將NLS_LANG設定為AMERICAN_AMERICA.<source db NLS_CHARACTERSET>
(如果您使用exp作為備份進行匯出,這也是您要使用的設定)
在這種情況下,我們要建立一個包含WE8MSWIN1252資料的匯出檔案。


 on unix this is:
       $ set NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252
       $ export NLS_LANG
       $ exp ....


       on windows this is:


       c:\>set NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252
       c:\>exp ....


3 b) 匯入時將NLS_LANG設定為AMERICAN_AMERICA.<source db NLS_CHARACTERSET>匯入目標資料庫。


在這個例子中,在匯入到AL32UTF8資料庫之前將NLS_LANG設定為AMERICAN_AMERICA.WE8MSWIN1252


on unix this is:
       $ set NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252
       $ export NLS_LANG
       $ imp ....


       on windows this is:


       c:\>set NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252
       c:\>imp ....


在通過imp連線將資料插入到UTF8資料庫中時,完成到UTF 8的轉換。


我們建議在當前shell中為unix(->如何設定Unix環境變數)或在視窗中使用exp或imp工具的dos框中設定NLS_LANG顯示
(->“c:\> set NLS_LANG =AMERICAN_AMERICA.<characterset of the source database>“)


4. exp和imp是否受NLS_LANGUAGE和NLS_TERRITORY影響


exp和imp不受NLS_LANGUAGE和NLS_TERRITORY影響
通常,您使用AMERICAN_AMERICA預設值,但如果您使用NLS_LANG設定為FRENCH_FRANCE進行匯入,則您將不會有問題,即使源環境使用GERMAN_GERMANY等。
NLS_LANGUAGE和NLS_TERRITORY與儲存在資料庫中的實際語言之間沒有任何關係。


5. 我在imp期間有訊息“(possible ncharset conversion)”。


你看到類似的資訊
Export file created by EXPORT:V08.01.07 via direct path 
     import done in WE8ISO8859P15 character set and AL16UTF16 NCHAR character set 
     export server uses WE8ISO8859P15 NCHAR character set (possible ncharset conversion)


在匯入日誌中,這是正常的,不是錯誤資訊。


如果您在USER/應用程式資料中不使用N-types,那麼這是一個純資訊性訊息。


此查詢將給出所有N-types型別的表
select distinct OWNER, TABLE_NAME from DBA_TAB_COLUMNS where DATA_TYPE in ('NCHAR','NVARCHAR2', 'NCLOB');


但是即使在使用N-types如NCHAR或NCLOB的情況下,這不是一個問題:
資料庫將自動從“old”NCHAR字符集轉換為新的字符集。 (並且與“normal”字符集不同,NLS_LANG在exp/imp期間不影響對此轉換)
AL16UTF16或UTF8(9i中只有2個可能的值)是unicode字符集,因此可以儲存任何字元...因此不會出現資料丟失。 請參閱Oracle 9i,10g和11g中的國家字符集


6. 如何知道在什麼字符集中建立了一個dmp(exp)檔案?


只需發出:imp system/oracle@database show=yes file=test.dmp
輸出給你
import done in US7ASCII character set and AL16UTF16 NCHAR character set
      -> this is the current NLS_LANG value set in the environment 
      and the NCHAR characterset of the target database


    import server uses WE8MSWIN1252 character set (possible charset conversion)
      -> this is only shown if the NLS_LANG during this import session is different 
      from the target database characterset, so if you see 3 lines you might have problems :-)


    export client uses UTF8 character set (possible charset conversion)
      -> this is the characterset used during the export session and the
      characterset used in the dmp file.


7. NLS_LANG如何影響資料泵(expdp / impdp)?


資料泵不使用NLS_LANG在資料庫之間進行轉換。
2個資料庫字符集之間的轉換完全基於源資料庫和目標資料庫的NLS_CHARACTERSET(或NLSAR,Nvarchar和Nclob資料型別的NLS_NCHAR_CHARACTERSET)。
但是,如果指定引數檔案,則NLS_LANG *is* 用於引數檔案的編碼。 這隻有在引數檔案中使用非英語字元(例如,對於QUERY引數)才重要。
如果在引數檔案中使用非英語字元,那麼應該將NLS_LANG環境變數(在啟動Data Pump作業的會話中)設定為引數檔案(!)的正確編碼。


在所有低於10.2.0.4(包括10.1.0.5)的10g版本上轉到(AL32)UTF8或其他多位元組字符集時,請不要使用Expdp/Impdp。 11.1.0.6也受影響。
它將引發資料損壞,除非補丁5874989應用於Impdp端。 Expdp不受影響,因此轉儲檔案中的資料是正確的。此外,“old”exp / imp工具不受影響。
此問題在10.2.0.4和11.1.0.7修補程式集中已解決。
固定在11.2.0.1及以上
對於Windows,修復程式包括在
10.1.0.5.0 Patch 20 (10.1.0.5.20P) or later, see Note 276548.1 .
10.2.0.3.0 Patch 11 (10.2.0.3.11P) or later, see Note 342443.1 .


8. 匯入期間導致ORA-01401 ora ORA-12899的原因(imp和impdp)


9i和更低的值給出ORA-01401:對於列,插入值太大,10g及以上給出ORA-12899:值過大的列


當從具有8位NLS_CHARACTERSET(如WE8ISO8859P1,WE8MSWIN1252,WE8DEC ...)的資料庫匯出到具有16位NLS_CHARACTERSET(如JA16SJIS,ZHS16GBK,KO16MSWIN949)或NLS_CHARACTERSET設定為AL32UTF8或UTF8的資料庫時,可以看到此情況
在AL32UTF8 / UTF8(Unicode)或其他多位元組NLS_CHARACTERSET資料庫中匯入資料時,請參見注釋1297961.1 ORA-01401 / ORA-12899。

相關文章