Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1996088
  • 博文数量: 1647
  • 博客积分: 80000
  • 博客等级: 元帅
  • 技术积分: 9980
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 15:15
文章分类

全部博文(1647)

文章存档

2011年(1)

2008年(1646)

我的朋友

分类:

2008-10-28 18:27:04


  以前也看了一些关于字符集转换的文章,但是实际使用的时候还是发生了问题,出现了乱码,为了彻底搞清楚字符集问题,我决定做,用EXP/IMP工具在不同字符集之间互相转换数据。
  
  环境:两台PC机器,分称A机器(192.168.1.5)和B机器(192.168.1.8)
  
  两台机器的配置都是一致的,安装WIN2000操作系统和8.1.7数据库
  
  计划从A机器导出包含有中文的数据,然后倒入到B机器中。
  
  测试计划:
  
  分别在两台机器上安装两个instance,这两个instance又分别是中,英文字符集。
  
  为了简单起见,国家字符集和字符集设置都是一样的,就是说,设置成英文字符集的时候,上面说的两个设置都是US7ASCII,设置中文字符集的时候都是ZHS16GBK,我没有考虑国家字符集和字符集不一致的情况。
  
  客户端也分成C,D两个部分,实际测试的时候C和D是一个客户端,因为如果A和C的字符集不一致,是不允许导出的;同样,如果B和D的字符集不一致,是不允许导入的。
  
  在C机器上建立四个服务指向上面新建的4个instance。
  
  5c:中文 在A机器上
  
  5e:英文 在A机器上
  
  8c:中文 在B机器上
  
  8e:英文 在B机器上
  
  四个进程都建立相同的用户和表。
  
  Connect system/manager
  
  Create user test identified by test default tablespace users temporary tablespace temp;
  
  Grant connect,resource to test;
  
  Connect test/test
  
  Create table emp(id number(2) , address varchar2(100));
  
  然后只在A机器上的两个进程中插入数据。
  
  Insert into emp(id,address) values(1,'北京市');
  
  Insert into emp(id,address) values(2,'成都市');
  
  Insert into emp(id,address) values(3,'上海市');
  
  Insert into emp(id,address) values(4,'天津市');
  
  Insert into emp(id,address) values(5,'重庆市');
  
  Insert into emp(id,address) values(6,'武汉市');
  
  Insert into emp(id,address) values(7,'广州市');
  
  Commit;
  
  然后测试,过程如下
  
  一:在C机器上测试,C机器是英文字符集
  
  exp system/manager@5c file=c:5c1.dmp owner=test
  
  exp system/manager@5e file=c:5e1.dmp owner=test
  
  都导出成功。
  
  发现上面两个文件的ACSII字符集都是0001
  
  二:在C机器上测试,C机器换成中文字符集
  
  exp system/manager@5c file=c:5c2.dmp owner=test
  
  exp system/manager@5e file=c:5e2.dmp owner=test
  
  发现上面两个文件的ACSII字符集都是0354
  
  A机器上的数据库变换字符集,就是把原来英文字符集数据库换成中文字符集,把原来中文字符集数据库换成英文字符集。
  
  备注:之后没有把原来的数据删掉重新录入中文数据,而是用以前的旧的数据。后来发现:原来英文字符集数据库换成中文字符集后,数据可以正常显示;反之,中文字符集数据库换成英文字符集后,数据已经是乱码了,已经不能正常显示了。
  
  原因:中文字符集占两个字节,英文字符集占一个字节,所以当中文转换成英文的时候,数据库压缩,数据就无法正常显示了。反过来可以正常显示,所以推荐建立数据库的时候用英文字符集,好处多多(包括全文索引的时候)。
  
  所以后来倒出的5c3.dmp和5c4.dmp实际上包含的数据都已经是不对的,测试已经没有意义了。于是我重新进行试验,在变换数据库字符集后,删掉原来的数据库emp表中的数据,插入正确的数据,保证源数据库中的数据是可用的。重新测试。
  
  然后把A机器上的数据库变换字符集,就是原来是中文的数据库我换成英文,原来是英文的数据库我换成中文,采用的方法是修改props$表。
  
  三:A机器上的数据库变换字符集后。
  
  C机器上导出操作,C机器是英文字符集
  
  exp system/manager@5c file=c:5c3.dmp owner=test
  
  exp system/manager@5e file=c:5e3.dmp owner=test
  
  都导出成功。
  
  发现上面两个文件的ACSII字符集都是0001
  
  四:A机器上的数据库变换字符集后。
  
  C机器上导出操作,C机器是中文字符集
  
  exp system/manager@5c file=c:5c4.dmp owner=test
  
  exp system/manager@5e file=c:5e4.dmp owner=test
  
  都导出成功。
  
  发现上面两个文件的ACSII字符集都是0354
  
  备份上面导出的8个数据文件。
  
  这时候修改上面导出的8个文件的ACSII字符集,进行中英文互换,把0001和0354互换
  
  修改后的文件名都加了一个"_2"标记
  
  小结:
  
  1. 导出的时候,如果客户端和数据库的字符集设置不一致,导出的时候并没有提示。
  
  2. 导出文件的ACSII字符集和客户端的字符集设置有关,与被导数据库字符集的设置无关。
  
  ****************************************
  
  **** 导入操作 ****
  
  ****************************************
  
  一:向B的8c倒入操作,客户机D是英文字符集
  
  1. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c1.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c1.dmp是英文客户端导出的中文数据库文件;ASCII字符集是英文的
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  2. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c1_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c1_2.dmp是英文客户端导出的中文数据库文件,ASCII字符集是改成中文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  3. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c2.dmp是中文客户端导出的中文数据库文件,ASCII字符集是中文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  4. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c2_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c2_2.dmp是中文客户端导出的中文数据库文件,但是ASCII字符集是改成英文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  5. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c3.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c3.dmp是英文客户端导出的英文数据库文件,但是数据库是换过的,ASCII字符集是英文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  6. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c3_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c3_2.dmp是英文客户端导出的英文数据库文件,但是数据库是换过的,但是ASCII字符集是改成中文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是???(注意:问号不是乱码),实际上导入失败。
  
  7. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c4.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c4.dmp是中文客户端导出的英文数据库文件;但是数据库是换过的。
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  8. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c4_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c4_2.dmp是中文客户端导出的中文数据库文件,但是数据库是换过的。
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  9. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e1.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e1.dmp是英文客户端导出的英文数据库文件
  
  ,ASCII字符集是英文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  10. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e1_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e1_2.dmp是英文客户端导出的英文数据库文件,但是ASCII字符集是换成中文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是???(注意:问号不是乱码),实际上导入失败。
  
  11. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集侵形模?e2.dmp是中文客户端导出的英文数据库文件,ASCII字符集是中文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  12. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e2_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e2_2.dmp是中文客户端导出的英文数据库文件,但是ASCII字符集是换成英文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  13. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e3.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e3.dmp是英文客户端导出的中文数据库文件,但是数据库是换过的,ASCII字符集是英文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是???(注意:问号不是乱码),实际上导入失败。
  
  14. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e3_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e3_2.dmp是英文客户端导出的中文数据库文件,但是数据库是换过的,但是ASCII字符集是换成中文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是???(注意:问号不是乱码),实际上导入失败。
  
  15. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e4.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e4.dmp是中文客户端导出的中文数据库文件,但是数据库是换过的
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是???(注意:问号不是乱码),实际上导入失败。
  
  16. D机器是英文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e4_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e4_2.dmp是中文客户端导出的中文数据库文件,但是数据库是换过的,但是ASCII字符集是换成英文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  小结:
  
  1. 导入的时候,如果客户端和数据库的字符集设置不一致,导入的时候Oracle并没有提示。
  
  2. 导入的时候,如果客户端和数据库的字符集设置不一致,ORACLE不进行字符集验证,最终结果是数据库不可用。
  
  3. 至于是乱码还是问号,我没有总结,因为没有必要,反正是数据库不可用。
  
  4. 上面的操作其实没有必要做,因为导入的客户端和目的数据库字符集不一致,导入后肯定不能用,但是为了试验的完整性,我还是自己做了一遍,希望大家不要嫌烦
  
  二:向B的8c倒入操作,客户机是中文字符集
  
  17. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c1.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c1.dmp是英文客户端导出的中文数据库文件;ASCII字符集是英文的
  
  提示:不支持要求的字符集转换,倒入失败。
  
  18. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c1_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c1_2.dmp是英文客户端导出的中文数据库文件,ASCII字符集是改成中文的;
  
  导入成功,有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  19. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c2.dmp是中文客户端导出的中文数据库文件,ASCII字符集是中文的;
  
  导入成功,有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是???(注意:问号不是乱码),实际上导入失败。
  
  20. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c2_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c2_2.dmp是中文客户端导出的中文数据库文件,但是ASCII字符集是改成英文的;
  
  提示:不支持要求的字符集转换,倒入失败。
  
  21. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c3.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c3.dmp是英文客户端导出的英文数据库文件,但是数据库是换过的,ASCII字符集是英文的;
  
  提示:不支持要求的字符集转换,倒入失败。
  
  22. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c3_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c3_2.dmp是英文客户端导出的英文数据库文件,但是数据库是换过的,但是ASCII字符集是改成中文的;
  
  导入成功,有报错信息。
  
  用英文字符集客户端是???,问号;用中文客户端是正确结果,可以看到中文。
  
  实际上导入成功。
  
  23. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c4.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c4.dmp是中文客户端导出的英文数据库文件;但是数据库是换过的。ASCII字符集是中文的;
  
  导入成功,有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  24. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5c4_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5c4_2.dmp是中文客户端导出的中文数据库文件,但是数据库是换过的。ASCII字符集是换成英文的;
  
  提示:不支持要求的字符集转换,倒入失败。
  
  25. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e1.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e1.dmp是英文客户端导出的英文数据库文件,ASCII字符集是英文的;
  
  提示:不支持要求的字符集转换,倒入失败。
  
  26. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e1_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e1_2.dmp是英文客户端导出的英文数据库文件,但是ASCII字符集是换成中文的;
  
  导入成功,有报错信息。
  
  用英文字符集客户端是???,问号;用中文客户端是正确结果,可以看到中文。
  
  实际上导入成功。
  
  27. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e2.dmp是中文客户端导出的英文数据库文件,ASCII字符集是中文的;
  
  导入成功,有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  28. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e2_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e2_2.dmp是中文客户端导出的英文数据库文件,但是ASCII字符集是换成英文的;
  
  提示:不支持要求的字符集转换,倒入失败。
  
  29. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e3.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e3.dmp是英文客户端导出的中文数据库文件,但是数据库是换过的,ASCII字符集是英文的;
  
  提示:不支持要求的字符集转换,倒入失败。
  
  30. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e3_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e3_2.dmp是英文客户端导出的中文数据库文件,但是数据库是换过的,但是ASCII字符集是换成中文的;
  
  导入成功,有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8C,数据库是???(注意:问号不是乱码),实际上导入失败。
  
  31. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e4.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e4.dmp是中文客户端导出的中文数据库文件,但是数据库是换过的
  
  导入成功,有报错信息。
  
  用英文字符集客户端是???,问号;用中文客户端是正确结果,可以看到中文。
  
  实际上导入成功。
  
  32. D机器是中文字符集,B机器是中文数据库
  
  imp system/manager@8c file=c:5e4_2.dmp fromuser=test touser=test ignore=y
  
  8C数据库字符集是中文,5e4_2.dmp是中文客户端导出的中文数据库文件,但是数据库是换过的,但是ASCII字符集是换成英文的;
  
  提示:不支持要求的字符集转换,倒入失败。
  
  小结:
  
  1:导入的时候,只有当客户机和的字符集一致的时候才进行倒入的字符集验证,当导入文件(DMP文件)的ASCII字符集和他们一致的时候才能导入,否则报:不支持要求的字符集转换。
  
  2:必要条件是导出文件是可用的,就是说,导出的时候的客户端和端的字符集是一致的。可以解释26和31的成功。
  
  3:26的成功说明了就算是英文的数据库保存中文数据,在导出后修改DMP文件的字符集,还是可以导入到中文数据库中的。
  
  4:31的成功说明了就算数据库是转换过的,但是还是可以正确导出中文数据的。
  
  5:22的成功说明了就算是英文的数据库保存中文数据,在导出后修改DMP文件的字符集,还是可以导入到中文数据库中的。(即使这个英文数据库原来是中文的)
  
  7:最不可理解的是19,为什么不行,按道理说,它应该是最有把握的。
  
  三:向B的8e倒入操作(数据库是英文数据库),客户机D是英文字符集
  
  备注:客户机是中文字符集的情况其实不用测试了,因为客户机和服务器不一致,肯定出现问题。
  
  33. D机器是英文字符集,B机器是英文数据库
  
  imp system/manager@8e file=c:5c1.dmp fromuser=test touser=test ignore=y
  
  5c1.dmp是英文客户端导出的中文数据库文件;ASCII字符集是英文的
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8E,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  34. D机器是英文字符集,B机器是英文数据库
  
  imp system/manager@8e file=c:5c1_2.dmp fromuser=test touser=test ignore=y
  
  5c1_2.dmp是英文客户端导出的中文数据库文件,ASCII字符集是改成中文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8E,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  35. D机器是英文字符集,B机器是英文数据库
  
  imp system/manager@8e file=c:5c2.dmp fromuser=test touser=test ignore=y
  
  5c2.dmp是中文客户端导出的中文数据库文件,ASCII字符集是中文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8E,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  36. D机器是英文字符集,B机器是英文数据库
  
  imp system/manager@8e file=c:5c2_2.dmp fromuser=test touser=test ignore=y
  
  5c2_2.dmp是中文客户端导出的中文数据库文件,但是ASCII字符集是改成英文的;
  
  导入成功,没有报错信息。
  
  但是不管用中文客户端还是用英文客户端SQL/PLUS访问8E,数据库是乱码(注意:乱码不是问号),实际上导入失败。
  
  37. D机器是英文字符集,B机器是英文数据库
  
  imp system/manager@8e file=c:5c3.dmp fromuser=test touser=test ignore=y
  
  5c3.dmp是英文客户端导出的英文数据库文件,但是数据库是换过的,ASCII字符集是英文的;
  
  导入成功,没有报错信息。
  
  用英文客户端SQL/PLUS访问8E,数据库是中文,实际上导入成功。
  
  38. D机器是英文字符集,B机器是英文数据库
  
  imp system/manager@8e file=c:5c3_2.dmp fromuser=test touser=test ignore=y
  
  >5c3_2.dmp是英文客户端导出的英文数据库文件,但是数据库是换过的,但是ASCII字符集是改成中文的;
  
  导入成功,没有报错信息。
  
  用英文客户端SQL/PLUS访问8E,数据库是???,倒入不成功。
【责编:admin】

--------------------next---------------------

阅读(179) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~