NLS considerations in Import/Export - Frequently Asked Questions (Doc ID 227332.1)
NLS在Import/Export中的注意事项 -- FAQ (Doc ID 227332.1)
应用于:
Oracle Database - Enterprise Edition - Version 8.0.3.0 及以后版本
Oracle Database - Standard Edition - Version 8.0.3.0 及以后版本
所有平台适用
用途:
文档用于使用导出/导入(包括旧的exp/imp 和expdp/impdp)功能时的字符集转换
细节:
主要的全球语言NLS常见问题请看:Note:60134.1 Globalization (NLS) - Frequently Asked Questions
主要的exp/imp常见问题请看:Note:175624.1 Oracle Server - Export and Import FAQ
1. NLS如何影响exp / imp(旧的导入/导出)?
imp和exp都是客户端类的产品,和sqlplus或者oracle的其他形式,所以说翻译数据库的字符集也是由NLS_LANG参数所定义的,所导出的字符集将会被存储在导出文件中,并且该文件被导入的时候,import进程将会检查该文件所使用的字符集,当该字符集和import进程所使用的NLS_LANG参数设定不一致的时候,将会把文件的字符集转换成import进程所使用的字符集,再进行导入,假如有必要的话,会转换成数据库的字符集
参考:
Note:15095.1 Old Exp/Imp (not datapump) and NLS Considerations
旧的Exp/Imp (不是数据泵)和NLS的注意事项
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';
这个样子从原始数据库导出exportfile文件将会不用执行任何字符集的转换操作,包括原始数据库的所有数据(假如不这样,甚至会储存错误的数据).
即使这个计划是导入到不同的字符集设置的数据库,字符集的转换也可以直到导入(imp)的时候才进行.
注意:
(1)这个和操作系统的字符集没有关系,假如你的源数据库是WE8MSWIN1252,那么你应当将NLS_LANG在导入之前设置成AMERICAN_AMERICA.WE8MSWIN125,甚至在Unix服务器上也是如此
(2)当与数据库交互的时候(例如sqlplus),需要正确的配置(unix)客户端的字符集,并且可能会与NLS_CHARACTERSET这个参数不同
3. 在使用imp(旧的导入)的时候怎样设置NLS_LANG?
假如源数据库和目标数据库的字符集设置是一样的,那么在导入和导出的时候,NLS_LANG的字符集设置也应当使用一样的字符集
NLS_LANG=AMERICAN_AMERICA.<source db NLS_CHARACTERSET>
假如导出和导入的数据库的字符集设置不和NLS_LANG的最佳(首选)字符集一样,那么exp和imp应当还是和源数据库的字符集一样
NLS_LANG=AMERICAN_AMERICA.<source db NLS_CHARACTERSET>
设置目标数据库的NLS_LANG在导入期间同样是正确的,但是还是有一些限制,当使用一个多字节的字符集类型(例如UTF8)时,在imp和exp期间使用源NLS_CHARACTERSET是最简最好选择,它可以避免任何问题,像IMP16的"请求的字符集转换(type %lu to %lu)不支持".
所以说,首选的字符集转换的时候就是当导入到目标数据库的时候进行字符集之间的转换.
注意:
(1)这与操作系统无关。如果你的源数据库是一个WE8MSWIN1252数据库。在WE8MSWIN1252导入之前,甚至在一个Unix服务器,你仅仅需要设定NLS_LANG参数为AMERICAN_AMERICA。
(2)在于数据库交互期间(比如sqlplus)你需要正确的配置你的客户端,确切的说,客户端的设置可能和NLS_CHARACTERSET不一样
3,a)仔细检查源数据库上的NLS_CHARACTERSET设置
举个例子:你想使用旧的exp/imp工具从一个WE8MSWIN1252到一个AL32UTF8数据库:
注意,这仅仅是exp/imp的例子,如果你想迁移到AL32UTF8 or UTF8,那么请参考文档260192.1,去在8i, 9i , 10g and 11g 中设置NLS_CHARACTERSET为AL32UTF8/UTF8 (Unicode),或者去看Note 1297961.1 ORA-01401/ORA-12899 当在一个AL32UTF8 / UTF8 (Unicode)或者其他的多字节NLS字符集数据库导入数据时
select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET';
导出的时候将NLS_LANG参数设置成AMERICAN_AMERICA <源数据库的NLS字符集的设置>
(如果你想的话,这同样也是用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,导入到目标数据库
这个例子的展示了在导入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的数据库插入数据的时候,数据转换到UTF8就已经完成了
我们建议设置明确的NLS_LANG参数值,在Unix中的shell中(->How to Set Unix Environment Variable)或者在Windows中使用dos使用exp或者imp工具的时候.(-> "c:\>set NLS_LANG=AMERICAN_AMERICA.<characterset of the source database>")
4.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)
在导入日志中这是正常的,不是一种错误状态。
如果你为没有为用户或者应用使用N-types,那这就是一个单纯的信息式消息。
这个SELECT语句可以查询所有的N-type表格
select distinct OWNER, TABLE_NAME from DBA_TAB_COLUMNS where DATA_TYPE in ('NCHAR','NVARCHAR2', 'NCLOB');
但即使在这种情况下你用了N-types,例如NCHAR或者NCLOB,这也不是个问题。
(1)数据库将会自动把“旧的”NCHAR字符集转换为一个新的。(另外,区别于“正常”的字符集,在导入导出时NLS_LANG对这个转换没有影响)
(2)AL16UTF16或者 UTF8(在9i中只有这两种可能)是unicode字符集,可以存储任何字符。所以可以预见是没有数据丢失的。参见9i,10g,11g中的国际字符集。
6.怎样得知一个被创建的dmp文件使用了什么样的字符集?
问题很简单: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是怎么影响数据泵的呢?
数据泵不是用NLS_LANG在数据库之间做转换的。两个数据库字符集之间的转换纯粹是基于源数据库和目标数据库的NLS_CHARACTERSET(或Nchar Nvarchar和Nclob数据类型的NLS_NCHAR_CHARACTERSET)的。
然而,在参数文件中指定了被用于编码参数文件的NLS_LANG。如果你在参数文件中使用非英语字符的情况下(例如查询参数),这是唯一需要注意的。
如果你在参数文件中使用非英语字符,NLS_LANG环境变量应该在使用数据泵的会话中设置为符合的参数文件的编码.(!)
不要对所有低于10.2.0.4(包括10.1.0.5)的10g版本或者更低版本中使用(AL32)UTF8或其他多字节字符集的数据库进行expdp/impdp,11.1.0.6也受到影响。
它会导致数据损坏,除非补丁5874989已经被应用于导入端。导出不受影响,因此转储文件中的数据是正确的。而且“旧的”exp/imp工具是不受影响的。
这个问题被解决在10.2.0.4 11.1.0.7补丁集中。在11.2.0.1和以上的版本中被彻底解决,
在windows中的修复方案是:
10.1.0.5.0补丁20(10.1.0.5.20P)或之后,看文档276548.1
10.2.0.3.0补丁11(10.2.0.3.11P)或之后,看文档342443.1
8.是什么原因导致在导入期间(IMP和IMPDP)出现ora-01401或ora-12899?
9i或者更低的版本会出现ORA-01401:inserted value too large for column。
10g或者更高的版本会出现ORA-12899:value too large for column
当从一个使用8位的nls字符集(像we8iso8859p1,we8mswin1252,we8dec…)的数据库向一个16位的NLS_CHARACTERSET(如ja16sjis,zhs16gbk,ko16mswin949),或NLS_CHARACTERSET被设置为AL32UTF8或者UTF8的数据库中导出数据的时候会出现上述两种错误
请看1297961.1 ora-01401/ora-12899 当向AL32UTF8 / UTF8 (Unicode)或其他多字节NLS_CHARACTERSET数据库导入数据.
NLS在Import/Export中的注意事项 -- FAQ (Doc ID 227332.1)
应用于:
Oracle Database - Enterprise Edition - Version 8.0.3.0 及以后版本
Oracle Database - Standard Edition - Version 8.0.3.0 及以后版本
所有平台适用
用途:
文档用于使用导出/导入(包括旧的exp/imp 和expdp/impdp)功能时的字符集转换
细节:
主要的全球语言NLS常见问题请看:Note:60134.1 Globalization (NLS) - Frequently Asked Questions
主要的exp/imp常见问题请看:Note:175624.1 Oracle Server - Export and Import FAQ
1. NLS如何影响exp / imp(旧的导入/导出)?
imp和exp都是客户端类的产品,和sqlplus或者oracle的其他形式,所以说翻译数据库的字符集也是由NLS_LANG参数所定义的,所导出的字符集将会被存储在导出文件中,并且该文件被导入的时候,import进程将会检查该文件所使用的字符集,当该字符集和import进程所使用的NLS_LANG参数设定不一致的时候,将会把文件的字符集转换成import进程所使用的字符集,再进行导入,假如有必要的话,会转换成数据库的字符集
参考:
Note:15095.1 Old Exp/Imp (not datapump) and NLS Considerations
旧的Exp/Imp (不是数据泵)和NLS的注意事项
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';
这个样子从原始数据库导出exportfile文件将会不用执行任何字符集的转换操作,包括原始数据库的所有数据(假如不这样,甚至会储存错误的数据).
即使这个计划是导入到不同的字符集设置的数据库,字符集的转换也可以直到导入(imp)的时候才进行.
注意:
(1)这个和操作系统的字符集没有关系,假如你的源数据库是WE8MSWIN1252,那么你应当将NLS_LANG在导入之前设置成AMERICAN_AMERICA.WE8MSWIN125,甚至在Unix服务器上也是如此
(2)当与数据库交互的时候(例如sqlplus),需要正确的配置(unix)客户端的字符集,并且可能会与NLS_CHARACTERSET这个参数不同
3. 在使用imp(旧的导入)的时候怎样设置NLS_LANG?
假如源数据库和目标数据库的字符集设置是一样的,那么在导入和导出的时候,NLS_LANG的字符集设置也应当使用一样的字符集
NLS_LANG=AMERICAN_AMERICA.<source db NLS_CHARACTERSET>
假如导出和导入的数据库的字符集设置不和NLS_LANG的最佳(首选)字符集一样,那么exp和imp应当还是和源数据库的字符集一样
NLS_LANG=AMERICAN_AMERICA.<source db NLS_CHARACTERSET>
设置目标数据库的NLS_LANG在导入期间同样是正确的,但是还是有一些限制,当使用一个多字节的字符集类型(例如UTF8)时,在imp和exp期间使用源NLS_CHARACTERSET是最简最好选择,它可以避免任何问题,像IMP16的"请求的字符集转换(type %lu to %lu)不支持".
所以说,首选的字符集转换的时候就是当导入到目标数据库的时候进行字符集之间的转换.
注意:
(1)这与操作系统无关。如果你的源数据库是一个WE8MSWIN1252数据库。在WE8MSWIN1252导入之前,甚至在一个Unix服务器,你仅仅需要设定NLS_LANG参数为AMERICAN_AMERICA。
(2)在于数据库交互期间(比如sqlplus)你需要正确的配置你的客户端,确切的说,客户端的设置可能和NLS_CHARACTERSET不一样
3,a)仔细检查源数据库上的NLS_CHARACTERSET设置
举个例子:你想使用旧的exp/imp工具从一个WE8MSWIN1252到一个AL32UTF8数据库:
注意,这仅仅是exp/imp的例子,如果你想迁移到AL32UTF8 or UTF8,那么请参考文档260192.1,去在8i, 9i , 10g and 11g 中设置NLS_CHARACTERSET为AL32UTF8/UTF8 (Unicode),或者去看Note 1297961.1 ORA-01401/ORA-12899 当在一个AL32UTF8 / UTF8 (Unicode)或者其他的多字节NLS字符集数据库导入数据时
select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET';
导出的时候将NLS_LANG参数设置成AMERICAN_AMERICA <源数据库的NLS字符集的设置>
(如果你想的话,这同样也是用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,导入到目标数据库
这个例子的展示了在导入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的数据库插入数据的时候,数据转换到UTF8就已经完成了
我们建议设置明确的NLS_LANG参数值,在Unix中的shell中(->How to Set Unix Environment Variable)或者在Windows中使用dos使用exp或者imp工具的时候.(-> "c:\>set NLS_LANG=AMERICAN_AMERICA.<characterset of the source database>")
4.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)
在导入日志中这是正常的,不是一种错误状态。
如果你为没有为用户或者应用使用N-types,那这就是一个单纯的信息式消息。
这个SELECT语句可以查询所有的N-type表格
select distinct OWNER, TABLE_NAME from DBA_TAB_COLUMNS where DATA_TYPE in ('NCHAR','NVARCHAR2', 'NCLOB');
但即使在这种情况下你用了N-types,例如NCHAR或者NCLOB,这也不是个问题。
(1)数据库将会自动把“旧的”NCHAR字符集转换为一个新的。(另外,区别于“正常”的字符集,在导入导出时NLS_LANG对这个转换没有影响)
(2)AL16UTF16或者 UTF8(在9i中只有这两种可能)是unicode字符集,可以存储任何字符。所以可以预见是没有数据丢失的。参见9i,10g,11g中的国际字符集。
6.怎样得知一个被创建的dmp文件使用了什么样的字符集?
问题很简单: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是怎么影响数据泵的呢?
数据泵不是用NLS_LANG在数据库之间做转换的。两个数据库字符集之间的转换纯粹是基于源数据库和目标数据库的NLS_CHARACTERSET(或Nchar Nvarchar和Nclob数据类型的NLS_NCHAR_CHARACTERSET)的。
然而,在参数文件中指定了被用于编码参数文件的NLS_LANG。如果你在参数文件中使用非英语字符的情况下(例如查询参数),这是唯一需要注意的。
如果你在参数文件中使用非英语字符,NLS_LANG环境变量应该在使用数据泵的会话中设置为符合的参数文件的编码.(!)
不要对所有低于10.2.0.4(包括10.1.0.5)的10g版本或者更低版本中使用(AL32)UTF8或其他多字节字符集的数据库进行expdp/impdp,11.1.0.6也受到影响。
它会导致数据损坏,除非补丁5874989已经被应用于导入端。导出不受影响,因此转储文件中的数据是正确的。而且“旧的”exp/imp工具是不受影响的。
这个问题被解决在10.2.0.4 11.1.0.7补丁集中。在11.2.0.1和以上的版本中被彻底解决,
在windows中的修复方案是:
10.1.0.5.0补丁20(10.1.0.5.20P)或之后,看文档276548.1
10.2.0.3.0补丁11(10.2.0.3.11P)或之后,看文档342443.1
8.是什么原因导致在导入期间(IMP和IMPDP)出现ora-01401或ora-12899?
9i或者更低的版本会出现ORA-01401:inserted value too large for column。
10g或者更高的版本会出现ORA-12899:value too large for column
当从一个使用8位的nls字符集(像we8iso8859p1,we8mswin1252,we8dec…)的数据库向一个16位的NLS_CHARACTERSET(如ja16sjis,zhs16gbk,ko16mswin949),或NLS_CHARACTERSET被设置为AL32UTF8或者UTF8的数据库中导出数据的时候会出现上述两种错误
请看1297961.1 ora-01401/ora-12899 当向AL32UTF8 / UTF8 (Unicode)或其他多字节NLS_CHARACTERSET数据库导入数据.