
Oracle导入导出字符集乱码问题.docx
5页OracleOracle 导入导出字符集乱码问题导入导出字符集乱码问题导出/导入与字符集 进行数据的导入导出时,我们要注意关于字符集的问题在 EXP/IMP 过程 中我们需要注意四个字符集的参数:导出端的客户端字符集,导出端数据库字 符集,导入端的客户端字符集,导入端数据库字符集我们首先需要查看这四个字符集参数查看数据库的字符集的信息:SQL> select * from nls_database_parameters;PARAMETER VALUE------------------------------ ---------------------------------- ----------------------------------------------NLS_LANGUAGE AMERICANNLS_TERRITORY AMERICANLS_CURRENCY $NLS_ISO_CURRENCY AMERICANLS_NUMERIC_CHARACTERS .,NLS_CHARACTERSET ZHS16GBKNLS_CALENDAR GREGORIANNLS_DATE_FORMAT DD-MON-RRNLS_DATE_LANGUAGE AMERICANNLS_SORT BINARYNLS_TIME_FORMAT HH.MI.SSXFF AMNLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AMNLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZH:TZMNLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZH:TZMNLS_DUAL_CURRENCY $NLS_COMP BINARYNLS_NCHAR_CHARACTERSET ZHS16GBKNLS_RDBMS_VERSION 8.1.7.4.1NLS_CHARACTERSET:ZHS16GBK 是当前数据库的字符集。
我的 windows oracle 编码为:NLS_NCHAR_CHARACTERSET AL16UTF16 NLS_CHARACTERSET ZHS16GBK我们再来查看客户端的字符集信息:客户端字符集的参数 NLS_LANG=_.language:指定 oracle 消息使用的语言,日期中日和月的显示Territory:指定货币和数字的格式,地区和计算星期及日期的习惯Characterset:控制客户端应用程序使用的字符集通常设置或等于客户 端的代码页或者对于 unicode 应用设为 UTF8在 windows 中,查询和修改 NLS_LANG 可在注册表中进行:HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\HOMExx\xx 指存在多个 Oracle_HOME 时的系统编号我这里的 windows 默认为:windows Client: NLS_LANG SIMPLIFIED CHINESE_CHINA.ZHS16GBK在 Linux redhat5 中:[oracle@ucit ~]$ cd 注意:cd 后是空格没有任何内容 [oracle@ucit ~]$ vi .bash_profile 加上:export NLS_LANG=“Simplified Chinese_China“.ZHS16GBK 注意:四个 端的参数编码要一致然后使用:env|grep NLS_LANG 看正确没有在 unix 中:$ env|grep NLS_LANGNLS_LANG=simplified chinese_china.ZHS16GBK修改可用:$ export NLS_LANG=AMERICAN_AMERICA.UTF8通常在导出时最好把客户端字符集设置得和数据库端相同。
当进行数据导 入时,主要有以下两种情况:(1) 源数据库和目标数据库具有相同的字符集设置这时,只需设置导出和导入端的客户端 NLS_LANG 等于数据库字符集即可2) 源数据库和目标数据库字符集不同先将导出端客户端的 NLS_LANG 设置成和导出端的数据库字符集一致,导出 数据,然后将导入端客户端的 NLS_LANG 设置成和导出端一致,导入数据,这样 转换只发生在数据库端,而且只发生一次这种情况下,只有当导入端数据库字符集为导出端数据库字符集的严格超 集时,数据才能完全导成功,否则,可能会有数据不一致或乱码出现不同版本的 EXP/IMP 问题一般来说,从低版本导入到高版本问题不大,麻烦的是将高版本的数据导 入到低版本中,在 Oracle9i 之前,不同版本 Oracle 之间的 EXP/IMP 可以通过 下面的方法来解决:1、在高版本数据库上运行底版本的 catexp.sql;2、使用低版本的 EXP 来导出高版本的数据;3、使用低版本的 IMP 将数据库导入到低版本数据库中;4、在高版本数据库上重新运行高版本的 catexp.sql 脚本但在 9i 中,上面的方法并不能解决问题。
如果直接使用低版本 EXP/IMP 会 出现如下错误:EXP-00008: orACLE error %lu encounteredorA-00904: invalid column name这已经是一个公布的 BUG,需要等到 Oracle10.0 才能解决,BUG 号为 2261722,你可以到 METALINK 上去查看有关此 BUG 的详细信息BUG 归 BUG,我们的工作还是要做,在没有 Oracle 的支持之前,我们就自 己解决在 Oracle9i 中执行下面的 SQL 重建 exu81rls 视图即可Create or REPLACE view exu81rls(objown,objnam,policy,polown,polsch,polfun,stmts,chkopt,enabled,spoli cy)AS select u.name, o.name, r.pname, r.pfschma, r.ppname, r.pfname,decode(bitand(r.stmt_type,1), 0,'', 'Select,')|| decode(bitand(r.stmt_type,2), 0,'', 'Insert,')|| decode(bitand(r.stmt_type,4), 0,'', 'Update,')|| decode(bitand(r.stmt_type,8), 0,'', 'Delete,'),r.check_opt, r.enable_flag,DECODE(BITAND(r.stmt_type, 16), 0, 0, 1)from user$ u, obj$ o, rls$ rwhere u.user# = o.owner#and r.obj# = o.obj#and (uid = 0 oruid = o.owner# orexists ( select * from session_roles where role='Select_CATALOG_ROLE'))/grant select on sys.exu81rls to public;/可以跨版本的使用 EXP/IMP,但必须正确地使用 EXP 和 IMP 的版本:1、总是使用 IMP 的版本匹配数据库的版本,如:要导入到 817 中,使用 817 的 IMP 工具。
2、总是使用 EXP 的版本匹配两个数据库中最低的版本,如:从 9201 往 817 中导入,则使用 817 版本的 EXP 工具。












