US7ASCII DMP 导入 ZHS16GBK DB 一方案
朋友有个EXP 导出的文件,因为源端导出是US7ASCII,导入ZHS16GBK总是乱码。
Oracle的字符集命名遵循以下命名规则:
<Language><bit size><encoding>
即: <语言><比特位数><编码>
可以查询以下数据字典或视图查看字符集设置情况
nls_database_parameters、props$、v$nls_parameters
imp导入时验证三方的字符集,
1. oracel server端的字符集(TARGET DB); 2. oracle client端的字符集(OS ENV); 3. dmp文件的字符集。
下面是我的方法。9I导出的DMP 文件。导入我用的是10205 的客户端导入10205的DB.
1、导出
export NLS_LANG=AMERICAN_AMERICA.US7ASCII
2,尝试导入失败
[oracle@oem ~]$ env |grep LANG NLS_LANG=american_america.US7ASCII LANG=SIMPLIFIED CHINESE.ZHS16GBK [oracle@oem ~]$ imp system/oracle fromuser=dagluser touser=test tables=NZ_DJB file=haidianbiaoqian.dmp import done in US7ASCII character set and AL16UTF16 NCHAR character set import server uses ZHS16GBK character set (possible charset conversion) . importing DAGLUSER's objects into TEST . . importing table "NZ_DJB" 303243 rows imported Import terminated successfully without warnings. SQL> select * from NLS_database_PARAMETERS; PARAMETER VALUE ------------------------------ ---------------------------------------- NLS_LANGUAGE AMERICAN NLS_TERRITORY AMERICA NLS_CURRENCY $ NLS_ISO_CURRENCY AMERICA NLS_NUMERIC_CHARACTERS ., NLS_CHARACTERSET ZHS16GBK NLS_CALENDAR GREGORIAN NLS_DATE_FORMAT DD-MON-RR NLS_DATE_LANGUAGE AMERICAN NLS_SORT BINARY NLS_TIME_FORMAT HH.MI.SSXFF AM NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR NLS_DUAL_CURRENCY $ NLS_COMP BINARY NLS_LENGTH_SEMANTICS BYTE NLS_NCHAR_CONV_EXCP FALSE NLS_NCHAR_CHARACTERSET AL16UTF16 NLS_RDBMS_VERSION 10.2.0.5.0 SQL> select NZ_DJB.QYMC from test.nz_djb where rownum<10; QYMC -------------------------------------------------------------------------------- ???????????????????????????? ???????????????????????????????????????? ?????????????????????????????????????? ???????????????????????? ?????????????????????????? ???????????????????????????? ???????????????????????????????? ???????????????????????????????? ?????????????????????????????????????????? [oracle@oem ~]$ env |grep LANG NLS_LANG=american_america.US7ASCII LANG=american_america.US7ASCII --导入同样乱码, 删除表,再接着下面的修改。 下面是用UltraEdit(专业文本/十六进制编辑器版本 17.30.0.1011)打下dmp 文件的16进制显示部分样式已截取 03 00 01 45 58 50 4F 52 54 ... 2E 30 31 0A 44 47 4C 55 53 ... 53 45 52 53 0A 32 30 34 38 ... 0A 00 01 00 01 07 D0 00 01 ... 注意第2,3 byte内容,为00 01 转换为10进制 1,也就是这个dmp文件的字符集编号为1,下面使用NLS_CHARSET_NAME function转换一下字符集的名称 sys@ANBOB>select nls_charset_name(to_number('0001','xxxx')) from dual; NLS_CHARSET_NAME(TO_NUMBER('0001','XXXX' ---------------------------------------- US7ASCII 可以看到那个dmp文件的字符集是US7ASCII,如果要替换为ZHS16GBK,我们需要转换一对应的编号,使用NLS_CHARSET_ID function
sys@ANBOB>select to_char(nls_charset_id('ZHS16GBK'),'xxxxxxxxxx') from dual; TO_CHAR(NLS ----------- 354
另外注意经过测试只修改第2、3 BYTE导入依旧乱码,还要修改第二处,位置我发现不固定,我暂时没有找到dmp file header结构, 目前发现是在UE 16进制显示的第4行如上面UE的红色字体,处于07 D0 00前面的两个字节,有时是第3、4,本例打开是第4、5,也是US7ASCII,同样需要修改为ZHS16GBK对应的0354. 修改后
03 03 54 45 58 50 4F 52 54 ... 2E 30 31 0A 44 47 4C 55 53 ... 53 45 52 53 0A 32 30 34 38 ... 0A 00 01 03 54 07 D0 00 01 ... 2、编辑DMP文件(ultraedit) 修改第一行:2,3字节(0001)为0354 如果DMP 文件过大可使用linux工具截取转换
cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6
注意在linux下显示高低位置颠倒,上面的dmp ,修改后od时显示如下
[oracle@db231 ~]$ cat haidianbiaoqian.dmp|od -x|head -4 0000000 0303 4554 5058 524f 3a54 3056 2e39 3030 0000020 302e 0a31 4444 4741 554c 4553 0a52 5552 0000040 4553 5352 320a 3430 0a38 0a30 3032 300a 0000060 000a 0301 0754 00d0 0001 0000 0000 0000
3、再次导入
[oracle@oem ~]$ export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
[oracle@oem ~]$ export LANG=AMERICAN_AMERICA.ZHS16GBK
[oracle@oem ~]$ env |grep LANG
NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
LANG=AMERICAN_AMERICA.ZHS16GBK
[oracle@db231 ~]$ imp system/oracle file=haidianbiaoqian.dmp touser=weejar fromuser=DAGLUSER tables=NZ_DJB
Import: Release 11.2.0.3.0 – Production on Fri Jun 13 13:24:10 2014
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export file created by EXPORT:V09.00.01 via conventional path
Warning: the objects were exported by DAGLUSER, not by you
import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
. importing DAGLUSER’s objects into WEEJAR
. . importing table “NZ_DJB” 303243 rows imported
Import terminated successfully without warnings.
4,在另一客户端WINDOWS查询
C:\>set NLS_LANG=american_america.zhs16gbk
C:\>sqlplus weejar/weejar@192.168.168.231:1521/anbob.com
SQL*Plus: Release 10.2.0.1.0 – Production on Mon Jan 28 14:31:26 2013
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select NZ_DJB.QYMC from nz_djb where rownum<10;
QYMC
——————————————————————————–
北京XXX房地产开发有限公司
北京XXX贸有限公司物业管理分公司
北京XX讯器材有限公司北太平庄分公司
北京XX业科技有限公司
北京XX电子技术有限公司
北京XX视业文化传播有限公司
北京XXXXX生物技术有限责任公司
北京羽XXXX美发中心学院路咨询部
北京市声XXX有限公司第一销售分公司
9 rows selected.
–DONE.
SUMMARY:
exp 时注意保证三处的字符集一致,对于本例的US7ASCII(10g) DMP 导入 ZHS16GBK DB (11g), 采用了修改dmp文件中的两处字符集编号,最终解决了字符集乱码问题。
对不起,这篇文章暂时关闭评论。