西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页编程开发其它知识 → Oracle导入导出dmp文件字符集乱码的解决方案

Oracle导入导出dmp文件字符集乱码的解决方案

相关软件相关文章发表评论 来源:西西整理时间:2014/6/29 14:30:30字体大小:A-A+

作者:西西点击:1962次评论:0次标签: Oracle

  • 类型:数据库类大小:42.1M语言:中文 评分:4.2
  • 标签:
立即下载

Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币,数字,和日历自动适应本地化语言和平台。

Oracle 在进行dmp备份和还原的时候,服务器端字符集和客户端字符集会对这个过程有较大影响,特别是数据表中存储了中文、存储过程中使用了中文编码(注释)的时候,如果没有处理好字符集的问题,在进行还原的时候就会遇到问题,我所遇到过的问题有一下几种:

1:导入后数据表中存储的中文字符成了乱码;

2:导入后存储过程中的中文字符成了乱码;

3:导入时,提示某些存储过程不存在,报IMP-00098 INTERNAL ERROR:impccr2错误:

其中问题1出现的原因是源数据库使用的字符集和你现在导入的目标数据库字符集不一致,且目标数据库字符集不是源数据库字符集的超集。解决办法是修改目标数据库的字符集(这个字符集是在创建数据库实例的时候设置的),改成和源数据库一致,再执行导入操作,可以解决数据表中中文字符乱码问题。

问题2和问题3的解决办法,修改客户端字符集,检查你的系统环境变量NLS_LANG的值或者注册表HKEY_LOCAL_MACHINE-->SOFTWARE-->ORACLE 在这个分支下面找NLS_LANG键,修改这个键值再重新导入数据即可。

最后我们需要知道字符集应该改成什么?

方法一:去源数据库上查询 

需要用到的视图: nls_database_parameters、props$、v$nls_parameters

方法二:查看导入的时候sqlplus中的提示信息:

最后一行可以看到,export client uses ....也就是说导出客户端使用的字符集是ZHS16GBK,而且根据当前的设置,是有可能进行字符集的转换(也就意味着有可能出现乱码,如果现在用的字符集不是导出字符集的超集)。所以这里就用该把导入数据库客户端字符集设置成ZHS16GBK,再执行导入可以解决问题。

网上有些办法是修改dmp文件,个人认为,如果是目标数据库端字符集不满足要求,可以采用这种方法修改dmp文件,毕竟server端字符集不能随便更改(生产server一个实例下可能有多个应用系统的用户数据)。如果是客户端字符集问题,建议还是修改一下客户端字符集配置,等导入完成之后再把客户端字符集修改回来。

打开dmp文件,它的字符集是US7ASCII,我的服务器和客户端都是ZHS16GBK,有人说只要把dmp文件字符集修改就可以,但修改后文件就无法导入,报错说文件无效。我又试着把我服务器和客户端字符集改成US7ASCII,结果sql*plus打开就乱码,导入dmp文件后数据也还是乱码!!!

修改数据库字符集为'us7ascii'。
    查看数据库当前数据集有两种方式:
      a).select name,value$ from props$ where name like '%NLS_CHARACTERSET%',
      b).select userenv('language') from dual;
    1.常规方案修改数据库字符集
      1).sys登陆数据库:conn  /  as sysdba;
      2).关闭数据库:shutdown immediate;
      3).以mount方式开启数据库:startup mount;
      4).限制其它用户连接数据库使用资源: alter system enable restricted session;
      5).查看系统当前的进程(最大连接数):show parameter processes;记住job_queue_processes参数的当前值,后面需要修改回来。
      6).杀掉CJQ0及相应job进程: alter system set job_queue_processes=0;
      7).修改队列监视进程参数alter system set aq_tm_processes=0;
      8).更改数据库为open方式:alter database open;
      9).更改字符集:alter database character set us7ascii;
      a).如果当前数据库的字符集是系统字符集us7asci的超集,更改不会出问题;如果不是,将会提示:
     ORA-12712: 新字符集必须为旧字符集的超集
     b).如果数据库数据有CLOB类型,系统将会提示:
     ORA-12716: Cannot ALTER DATABASE CHARACTER SET when CLOB data exists
    2.  针对以上的错误a)的解决方案:使用INTERNAL_USE跳过超集检测
 ALTER DATABASE character set INTERNAL_USE us7ascii;
    3. 针对以上的错误b)的解决方案:使用internal_convert转换含有CLOB字段的表
  1).截断表truncate table Metastylesheet;
  2).alter database character set internal_convert zhs16gbk;-- ORACLE会自动转换含有CLOB
  3).因为前面清空了SYS.METASTYLESHEET表,需要重新创建
       9.2通过运行catmet.sql脚本来重建;@?/rdbms/admin/catmet.sql
            10g后通过运行catmeta.sql脚本来重建:@?/rdbms/admin/catmeta.sql
            (注意这个地方有待商榷,不确定,最好不要使用这种方法修改)
    4.完成方案a)和b)后再做如下步骤:
  1).查看当前字符集,确认是否正确修改select userenv('language') from dual;
  2).解除限制: 
           alter system disable restricted session; 
           alter system set job_queue_processes=10;--修改回开始记录的原始值
  3).最好也也设置一下set NLS_LANG 环境变量
  4).关闭数据库再打开;

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)