【exp/imp】将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中
1.1 BLOG文档结构图
1.2 前言部分
1.2.1 导读和注意事项
各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~:
① 如何将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中(重点,2种方法)?
② 从dmp文件可以获取到哪些信息?如何从dmp文件获取到dmp文件的字符集(重点,N种方法)?
③ 如何从dmp文件中获取到其中的DDL语句,例如建表、建索引语句等(2种方法)
④ dmp文件导入的一般步骤
⑤ imp工具的indexfile选项的作用
⑥ 软件UE、EditPlus、Pilotedit软件的使用
1.3 本文相关知识点
1.3.1 可以从dmp文件获取哪些信息?
在开发中常常碰到,需要导入dmp文件到现有数据库。这里的dmp文件可能来自于其它系统,所以,一般情况下是不知道导出程序(exp)的版本、导出时间或者导出模式等信息的。那么如何从现有的dmp文件中获取到这些信息呢?下面作者将一一讲解。
1.3.1.1 获取基本信息:导出的版本、时间、导出的用户
下面的示例中exp_ddl_lhr_02.dmp是生成的dmp文件:
[ZFZHLHRDB1:oracle]:/tmp>strings exp_ddl_lhr_02.dmp | head -10 TEXPORT:V11.02.00 ====》版本号 DSYS ====》使用SYS用户导出 RTABLES ====》基于表模式导出,RUSERS表示基于用户模式,RENTIRE表示基于全库模式 4096 Tue Aug 2 16:8:8 2016/tmp/exp_ddl_lhr_02.dmp====》生成的时间和文件地址 #C#G #C#G +00:00 BYTE UNUSED
|
1.3.1.2 获取dmp文件中的表信息
下面的示例中,exp_ddl_lhr_02.dmp是生成的dmp文件:
[ZFZHLHRDB1:oracle]:/tmp>strings exp_ddl_lhr_02.dmp | grep "CREATE TABLE"|awk '{print $3}'|sed 's/"//g' EMP ====》说明exp_ddl_lhr_02.dmp中只有一个emp表 |
1.3.1.3 解析dmp文件生成parfile文件
下面的示例中,exp_ddl_lhr_03.dmp是生成的dmp文件:
[ZFZHLHRDB1:oracle]:/tmp>strings exp_ddl_lhr_03.dmp | grep "CREATE TABLE"|awk '{print $3}'|sed 's/"//g'|awk '{ if (FNR==1) print "tables="$1 ; else print ","$1 }' tables=DEF$_AQCALL ,DEF$_AQERROR ,DEF$_CALLDEST ,DEF$_DEFAULTDEST ,DEF$_DESTINATION ,DEF$_ERROR ,DEF$_LOB ,DEF$_ORIGIN ,DEF$_PROPAGATOR ,DEF$_PUSHED_TRANSACTIONS ,MVIEW$_ADV_INDEX [ZFZHLHRDB1:oracle]:/tmp>
|
1.3.2 如何获取数据库DDL的创建语句
数据泵工具(impdp)工具给我们提供了SQLFILE的命令行选项,只获取DDL语句,并未真正的执行数据导入。另外,若单纯为了导出DDL语句则可以在使用expdp导出的时候使用CONTENT=METADATA_ONLY和EXCLUDE=STATISTICS选项,这样导出的DMP文件比较小。如下所示:
expdp \'/ AS SYSDBA\' DIRECTORY=DATA_PUMP_DIR DUMPFILE=lhrsql20161215.dmp LOGFILE=lhrsql20161215.log CONTENT=METADATA_ONLY SCHEMAS=SCOTT EXCLUDE=STATISTICS impdp \'/ AS SYSDBA\' DIRECTORY=DATA_PUMP_DIR DUMPFILE=lhrsql20161215.dmp LOGFILE=imp_exptest.log SQLFILE=expddl_lhr.sql
|
查看expddl_lhr.sql文件即可获取DDL语句。
imp工具使用SHOW=Y LOG=GET_DDL.sql的方式,可以看到清晰的DDL脚本,同时也不会真正的执行数据导入。另外,若单纯为了导出DDL语句则可以在使用exp导出的时候使用ROWS=N选项,这样导出的DMP文件比较小。如下所示:
exp \'/ AS SYSDBA\' TABLES=SCOTT.EMP FILE=/tmp/exp_ddl_lhr_01.dmp LOG=/tmp/exp_table.log BUFFER=41943040 ROWS=N COMPRESS=N imp \'/ AS SYSDBA\' FILE=/tmp/exp_ddl_lhr_01.dmp SHOW=Y LOG=/tmp/get_ddl.sql BUFFER=20480000 FULL=Y
|
查看get_ddl.sql文件即可获取DDL语句。
---- 生成DDL语句不会导入数据 --expdp \'/ AS SYSDBA\' tables=lhr.exptest directory=DATA_PUMP_DIR dumpfile=exptest.dmp logfile=exp_exptest.dmp EXCLUDE=STATISTICS --expdp \'/ AS SYSDBA\' directory=DATA_PUMP_DIR dumpfile=lhrsql20161215.dmp logfile=lhrsql20161215.log content=metadata_only schemas=SCOTT EXCLUDE=STATISTICS impdp \'/ AS SYSDBA\' directory=DATA_PUMP_DIR dumpfile=lhrsql20161215.dmp logfile=imp_exptest.log sqlfile=exptest.sql
exp \'/ AS SYSDBA\' tables=scott.emp file=/tmp/exp_ddl_lhr_01.dmp log=/tmp/exp_table.log buffer=41943040 rows=n compress=n imp \'/ AS SYSDBA\' file=/tmp/exp_ddl_lhr_01.dmp show=y log=/tmp/get_ddl.sql buffer=20480000 full=y
|
。
1.3.2.2 imp的indexfile选项(indexfile导出表和索引的ddl语句)
exp和imp工具中可能存在把table从一个库exp然后imp到另一个数据库出现没有指定tablespace而无法imp,imp的indexfile参数中可以解决的。
Oracle的imp工具指定indexfile参数后,可以不导入任何对象,而只把需要创建的index以sql语句的形式写入文本文件。创建库表等sql语句也会写入,但用rem注释屏蔽。
一、查看并修改导入对象的存储参数
如果原始库中有些表比较大,exp导出对象的初始存储空间设置可能比较高,导入时需要先申请分配较大的存储空间,如果只进行逻辑结构的迁移耗时较长。这时可以用indexfile参数导出sql语句,筛选出初始空间较高的建表语句,手工创建。再次导入时使用ignore选项忽略对象创建错误。
如何解析inexfile文件:可以考虑用sed编辑器进行正则表达式替换,也可以写个程序解析出initial超出一定阈值的库表及其sql。
1.3.2.3 impdp示例:
--expdp \'/ AS SYSDBA\' directory=DATA_PUMP_DIR schemas=SCOTT dumpfile=exptest_sql.dmp logfile=exp_exptest.dmp impdp \'/ AS SYSDBA\' directory=DATA_PUMP_DIR dumpfile=exptest_sql.dmp logfile=imp_exptest.log sqlfile=exptest.sql ------------------------------------------------------------------------- |
1.4 本文简介
一个网友找到我说,一个dmp文件导入数据库中,中文一直是乱码,看我能否帮忙解决一下。说真心话,一般情况下,乱码问题和安装问题,我一般不想接手,因为可能很简单的问题,有的人懒的动脑,碰到问题就问。尤其对于安装类问题,照着安装文档,一步一步来,一般都没有问题。在这里把一张网友分享的图片再分享一下:
可是,问字符集的的哥们,我能感觉到他自己是下了功夫的,都是自己摸索了,实在解决不了,才找到的我。这种情况下,我果断是要帮助的。好了,废话不多说了,且看整个处理过程吧。
1.4.1 本文实验环境介绍
项目 | source db | target db |
db 类型 |
|
|
db version | 10.2.0.1.0 | 10.2.0.1.0 |
db 存储 |
|
|
OS版本及kernel版本 |
|
|
字符集 | US7ASCII | GBK |
dmp文件字符集 | US7ASCII | US7ASCII |
1.5 开始导入
1.5.1 首先获取dmp文件的相关信息
网友给的dmp文件:
大约30M,解压后有282M左右:
[oracle@rhel6lhr ~]$ strings /tmp/hhris.dmp | head -10 EXPORT:V10.02.01 DHHRIS RUSERS 8192 Wed Oct 16 5:0:14 2013/data/dbbackup/expdata/hhris.dmp #G#G #G#G +08:00 BYTE UNUSED [oracle@rhel6lhr ~]$ strings /tmp/hhris.dmp | grep "CREATE TABLE"|awk '{print $3}'|sed 's/"//g' ADDTOHIS APPOINT APPOINTDETAIL APPOINTMASTER BACKUP_HISPPOINT WEB_LOG WEB_USER WORK_FLOW WORK_NODE [oracle@rhel6lhr ~]$ [oracle@rhel6lhr ~]$ cat /tmp/hhris.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 1-2,7-8 0001 SYS@ora10g> SELECT NLS_CHARSET_NAME(TO_NUMBER('0001','XXXX')) FROM DUAL;
NLS_CHARSET_NAME(TO_NUMBER('0001','XXXX')) ------------------------------------------------------------------------------------------------------------------------ US7ASCII
|
可以得出以下结论:
1、dmp文件是由10.02.01的客户端导出的
2、基于HHRIS用户导出
3、该用户下有很多表
4、dmp文件的字符集是US7ASCII
1.5.2 找出dmp文件的DDL语句
主要查看是否有其它表空间导致不能导入的问题。
[oracle@rhel6lhr env_oracle]$ imp \'/ AS SYSDBA\' file=/tmp/hhris.dmp show=y log=/tmp/get_ddl.sql buffer=20480000 full=y
Import: Release 10.2.0.1.0 - Production on Tue May 9 14:06:22 2017
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production With the Partitioning, OLAP and Data Mining options
Export file created by EXPORT:V10.02.01 via direct path
Warning: the objects were exported by HHRIS, not by you
import done in ZHS16GBK character set and AL16UTF16 NCHAR character set export client uses US7ASCII character set (possible charset conversion) . importing HHRIS's objects into SYS "BEGIN " "sys.dbms_logrep_imp.instantiate_schema(schema_name=>SYS_CONTEXT('USERENV','" 《《《《。。。。。。。。篇幅原因,有省略。。。。。。。。》》》》
[oracle@rhel6lhr env_oracle]$ sh gettabdd.sh /tmp/get_ddl.sql > /tmp/gen_tabddl.sql [oracle@rhel6lhr env_oracle]$ more /tmp/gen_tabddl.sql BEGIN sys.dbms_logrep_imp.instantiate_schema(schema_name=>SYS_CONTEXT('USERENV','CURRENT_SCHEMA'), export_db_name=>'ORACLE', inst_scn=>'59161085'); COMMIT; END; / CREATE SEQUENCE "MICROSOFTSEQDTPROPERTIES" MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 50 NOORDER NOCYCLE / CREATE SEQUENCE "R_REPORTLOG_LOGID" MINVALUE 1 MAXVALUE 100000 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER CYCLE / 。。。。。。。。。。。。。 《《《《。。。。。。。。篇幅原因,有省略。。。。。。。。》》》》
|
查找关键字tablespace,发现只有1个表空间HHRIS。
1.5.3 数据库准备
dbca -silent -createDatabase -templateName General_Purpose.dbc -responseFile NO_VALUE \ -gdbname lhrdb -sid lhrdb \ -sysPassword lhr -systemPassword lhr \ -datafileDestination '/cds/oradata' -recoveryAreaDestination '/cds/oradata' \ -storageType FS \ -characterset ZHS16GBK -nationalCharacterSet AL16UTF16 \ -sampleSchema false \ -memoryPercentage 20 \ -databaseType OLTP \ -emConfiguration NONE ORACLE_SID=lhrdb export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK sqlplus / as sysdba CREATE TABLESPACE HHRIS DATAFILE '/cds/oradata/mydg/HHRIS01.dbf' size 1G; create user hhris identified by lhr; grant dba to hhris; exit imp hhris/lhr file=/tmp/hhris.dmp full=Y log=/tmp/log_imp_hhrisgbk.dmp
|
[oracle@rhel6lhr mydg]$ imp hhris/lhr file=/tmp/hhris.dmp full=Y log=/tmp/log_imp_hhrisgbk.dmp
Import: Release 10.2.0.1.0 - Production on Tue May 9 14:17:55 2017
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production With the Partitioning, OLAP and Data Mining options
Export file created by EXPORT:V10.02.01 via direct path import done in ZHS16GBK character set and AL16UTF16 NCHAR character set export client uses US7ASCII character set (possible charset conversion) . importing HHRIS's objects into HHRIS . . importing table "ADDTOHIS" 0 rows imported . . importing table "APPOINT" 0 rows imported . . importing table "APPOINTDETAIL" 0 rows imported . . importing table "APPOINTMASTER" 0 rows imported 《《《《。。。。。。。。篇幅原因,有省略。。。。。。。。》》》》
Import terminated successfully with warnings. [oracle@rhel6lhr mydg]$ [oracle@rhel6lhr mydg]$
|
可以成功导入,但是查询的时候,有中文乱码。
1.5.4 解决乱码
使用UE或Pilotedit软件,以16进制的格式打开dmp文件,修改dmp文件的第4行的第1-4个字节。
修改前:
修改后:
其实,也有资料显示需要把第一行的第2和第3字节,第4行的第1-4字节全部修改掉,如下所示:
经过小麦苗的测试,发现这3个地方全部修改掉,也可以成功导入。
修改后保存文件,上传服务器,重新导入,导入后查询,发现中文已经可以正常显示了。
1.5.5 还有一种不显示乱码的方式
还有一种不显示乱码的方式,那就是将US7ASCII字符集的dmp文件导入到US7ASCII字符集的数据库中。
dbca -silent -createDatabase -templateName General_Purpose.dbc -responseFile NO_VALUE \ -gdbname lhrdb -sid lhrdb \ -sysPassword lhr -systemPassword lhr \ -datafileDestination '/cds/oradata' -recoveryAreaDestination '/cds/oradata' \ -storageType FS \ -characterset US7ASCII -nationalCharacterSet AL16UTF16 \ -sampleSchema false \ -memoryPercentage 20 \ -databaseType OLTP \ -emConfiguration NONE
|
export NLS_LANG=AMERICAN_AMERICA.US7ASCII imp hhris/lhr file=/tmp/hhris.dmp full=Y log=/tmp/log_imp_hhrisgbk.dmp |
导入后,在Windows上设置客户端环境变量NLS_LANG为AMERICAN_AMERICA.US7ASCII,然后重启PL/SQL DEVELOPER软件后就可以正常显示中文了。
本来想着,这样再采用GBK的字符集导出,然后导入GBK的数据库中,结果发现这种方法行不通,始终有乱码。其实,走到这一步,还可以将数据导出成文本格式的文件,然后将文本格式的文件再导入GBK字符集的数据库中仍然是可行的。
1.6 本文总结
有种办法处理将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中的中文乱码问题。第一,修改dmp文件中代表字符集的字符。第二,导入US7ASCII字符集的库中,然后导出成文本格式,再导入到GBK的库中。
About Me
...............................................................................................................................
● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用
● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新
● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/
● 本文博客园地址:http://www.cnblogs.com/lhrbest
● 本文pdf版及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/
● 数据库笔试面试题库及解答:http://blog.itpub.net/26736162/viewspace-2134706/
● QQ群:230161599 微信群:私聊
● 联系我请加QQ好友(646634621),注明添加缘由
● 于 2017-05-09 09:00 ~ 2017-05-30 22:00 在魔都完成
● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解
● 版权所有,欢迎分享本文,转载请保留出处
...............................................................................................................................
拿起手机使用微信客户端扫描下边的左边图片来关注小麦苗的微信公众号:xiaomaimiaolhr,扫描右边的二维码加入小麦苗的QQ群,学习最实用的数据库技术。
转载于:https://blog.51cto.com/lhrbest/1923865