一. 问题描述
源库: windows + oracle 10.2.0.1 ,数据库字符集为 ZHS16GBK
目标库: linux 5.4+oracle 10.2.0.1 ,数据库字符集为 US7ASCII
目前的问题是,如何将一个含有汉字的表(aidu用户的aidu表),在源库导出,然后在目标库导入到aidu用户下,导入后表中显示正确的汉字.
通过简单的exp/imp多次测试都宣告失败,目标库中汉字总是显示为'????'.[@more@]
二. 问题分析与解决
2.1 源库上,我们导出前应该设置客户端的NLS_LANG与数据库的字符集完全相同,这样就不会在导出的时候,就发生字符的转换.
源库的信息如下:
C:Documents and Settingsdujiabing>sqlplus / as sysdba
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
有一个表aidu.aidu,含有两条记录,其中一条含有中文内容,如下:
SQL> select * from aidu.aidu;
ID NAME
---------- --------------------
1 aidu1
2 杜家兵
2.2 在源库上进行导出的操作,注意导出前设置客户端的NLS_LANG,使客户端的字符集与源库的字符集相同,这里都是ZHS16GBK,如下:
C:Documents and Settingsdujiabing>exp aidu file=c:tempaidu.dmp tables=aidu
Password:
...
Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set
About to export specified tables via Conventional Path ...
. . exporting table AIDU 2 rows exported
Export terminated successfully without warnings.
2.3 将c:tempaidu.dmp 文件以二进制方式ftp到目标库主机上(LINUX)
2.4 目标库导入前的一些情况描述:
已经存在一个含有一个汉字记录的表,数据库的字符集为US7ASCII.
(也许有人会问,为什么先准备一个有汉字的记录呢? 问的好啊,因为有时候我们导入正确了,
但因为客户端的字符设置问题,导致显示内容仍然还是'????',为了避免这个问题,我们这里在目标库中先插一条合法记录,这样就有比较的对象了.)
SQL> select * from aidu.aidu;
ID NAME
---------- ----------------------------------------
100 测试
SQL> select userenv('LANGUAGE') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.US7ASCII
2.5 修改目标数据库的字符集,与源库相同
(这里郑重声明,请不要在生产数据库上随便做这个操作,存在很大的风险,这个测试是在测试数据库上完成的.)
目标库:
SQL>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>select userenv('language') from dual;
AMERICAN_AMERICA.ZHS16BGK
SQL> select * from aidu.aidu;
ID NAME
---------- ----------------------------------------
100 ??
(恭喜你,数据库的字符集已经更改完成了,但原先的合法记录显示为'??',是不是出问题了,没有,只是因为客户端与数据库的字符集不同,输出的时候做了显示转换)
2.6 设置连接目标数据库的客户端的字符集,然后执行imp操作.
$export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
$imp aidu/aidu file=/tmp/aidu.dmp fromuser=aidu touser=aidu ignore=y
Import: Release 10.2.0.1.0 - Production on Tue May 22 05:45:55 2012
Export file created by EXPORT:V10.02.01 via conventional path
import done in US7ASCII character set and AL16UTF16 NCHAR character set
. importing AIDU's objects into AIDU
. . importing table "AIDU" 2 rows imported
(可以看到导入的过程中,没有发生任何的字符集转换)
检查导入的结果,如下:
[oracle@ocmdb ~]$ sqlplus aidu/aidu
SQL> select * from aidu.aidu;
ID NAME
---------- ----------------------------------------
1 aidu1
2 杜家兵
100 测试
(可以看到,数据正确导入了目标数据库).
2.7 将目标数据库修改为原来的字符集.
SQL>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 US7ASCII;
SQL>shutdown immedaite;
SQL>startup
SQL>EXIT
2.8 检查结果 ,非常成功.
$exort NLS_LANG=AMERIAN_AMERICA.US7ASCII
$sqlplus aidu/aidu
SQL> select * from aidu.aidu;
ID NAME
---------- ----------------------------------------
1 aidu1
2 杜家兵
100 测试
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.US7ASCII
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/32980/viewspace-1058312/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/32980/viewspace-1058312/