oracle imp/exp 字符集问题

在做EXP/IMP操作时,会发生字符集转换。且发生多次,具体过程如下:
1、在EXP导出时,EXP会检查数据库字符集与本地NLS_LANG参数所指定的字符集是否一致,若不一致,则会发生字符转换,而字符转换过程中可能发生字符丢失。
    举例来说,如果数据为AL32UTF8字符集,而本地电脑的NLS_LANG所指定的字符集是US7ASCII,那么所有英文,数字及标准符号以外的字符在这一步时,就已经丢失了。因为ASCII不支持这些字符以外的字符,比如中文字符。

2、在IMP导入时,先检查导出生成的DMP文件的字符集标志(如何查看后面再说)。再检查本地电脑的NLS_LANG的设置,若两者不一致,则发生字符集转换。

3、再检查目标数据库的字符集,若与本地电脑的NLS_LANG的设置也不一致,则再次发生字符集转换。
如果在以上发生字符集转换的可能点上,源字符集与目标字符集不一致,且不是目标字符集的子集,就会发生字符集的转换,且丢失那些在目标字符集中不存在的字符信息。

查看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
  如果dmp文件很大,比如有2G以上(这也是最常见的情况),用文本编辑器打开很慢或者完全打不开,可以用以下命令(在unix主机上):
  cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6
  然后用上述SQL也可以得到它对应的字符集。
综上,若希望在EXP/IMP的全过程中,不发生字符丢失,就要把本地电脑上的NLS_LANG参数设置为与数据库相同的字符集。这样,在整个过程中,就没有字符集的转换,也就不会发生因字符转换而引发的字符丢失。但这样做的前提是目标数据库的字符集与源数据库的字符集一致。
若源数据库字符集与目标数据库字符集不一致,则分两种情况:
情况1:源数据库字符集是目标数据库的子集。则在导出时,在导出的电脑上设置NLS_LANG为源数据库字符集,这样导出时,不会发生字符集转换,同时导出的文件中,会标识该文件所使用的字符集为源数据库字符集。在导入时,在本地电脑上,设置NLS_LANG参数与DMP文件的字符集相同,这样,在导入的第一步时,也不会发生字符转换,只是在从会话向数据库中导入数据的过程中会发生字符转换,但由于源数据库字符集为目标库字符集的子集,所以,也不会发生因字符转换而发生的字符丢失或乱码现象。
情况2:源数据库字符集是目标数据库字符集的超集,或二者不兼容,那么字符丢失在所难免。除非源数据库中的字符恰好全部在目标库字符集中存在。比如源数据库字符集是zhs16gbk,但存储的全部是英文字符和数字,而没有任何中文或中文符号,那么,即使目标数据库的字符集是US7ASCII,也是不会出现字符丢失的。

你可能感兴趣的:(Oracle问题解决)