题目部分
在Oracle中,可以从exp出来的dmp文件获取哪些信息?
♣
答案部分
在开发中常常碰到,需要导入dmp文件到现有数据库。这里的dmp文件可能来自于其它系统,所以,一般情况下是不知道导出程序(exp)的版本、导出时间或者导出模式等信息的。那么如何从现有的dmp文件中获取到这些信息呢?下面作者将一一讲解。
(一)获取基本信息:导出的版本、时间、导出的用户
下面的示例中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
(二)获取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表
(三)解析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
(四)如何查看dmp文件的字符集
有两种办法可以查看dmp文件的字符集,第一种办法为imp导入命令查看,示例如下所示:
[ZFLHRZHDB1:oracle]:/oracle>ORACLE_SID=lhrdb
[ZFLHRZHDB1:oracle]:/oracle>export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
[ZFLHRZHDB1:oracle]:/oracle>exp \'/ AS SYSDBA\' tables=scott.emp file=/tmp/exp_ddl_lhr_03.dmp log=/tmp/exp_table.log buffer=41943040 rows=n compress=n
Export: Release 11.2.0.4.0 - Production on Tue Oct 25 17:14:49 2016
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Tes
Export done in AL32UTF8 character set and AL16UTF16 NCHAR character set<<<--当前的NLS_LANG环境变量的值,即生成的dmp文件的字符集
server uses ZHS16GBK character set (possible charset conversion)<<<<<<<--当前数据库的字符集
Note: table data (rows) will not be exported
About to export specified tables via Conventional Path ...
Current user changed to SCOTT
. . exporting table EMP
EXP-00091: Exporting questionable statistics.
EXP-00091: Exporting questionable statistics.
Export terminated successfully with warnings.
[ZFLHRZHDB1:oracle]:/oracle>ORACLE_SID=mydb <<---更换数据库
[ZFLHRZHDB1:oracle]:/oracle>export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
[ZFLHRZHDB1:oracle]:/oracle>imp \'/ AS SYSDBA\' tables=xxx.xx file=/tmp/exp_ddl_lhr_03.dmp
Import: Release 11.2.0.4.0 - Production on Tue Oct 25 16:27:15 2016
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Tes
Export file created by EXPORT:V11.02.00 via conventional path<<<<<<<<<----dmp文件的导出版本号
import done in ZHS16GBK character set and AL16UTF16 NCHAR character set<<<<<<--当前的NLS_LANG环境变量的值
import server uses WE8ISO8859P1 character set (possible charset conversion)<<<<<<---当前数据库的字符集
export client uses AL32UTF8 character set (possible charset conversion)<<<<<<--dmp文件的字符集
IMP-00029: cannot qualify table name by owner (xxx.xx), use FROMUSER parameter
IMP-00000: Import terminated unsuccessfully
如果NLS_LANG的值和当前数据库的字符集相同,那么将不显示“server uses”和“import server uses”行。如果没有显示“export client”行,那么说明当前dmp文件的字符集和当前的NLS_LANG环境变量的值相同。无论是使用exp还是imp工具都会显示当前的NLS_LANG环境变量的值(表现为“Export done”、“import done”)。
第二种查看dmp文件字符集的办法是,以十六进制的方式打开dmp文件,然后查看第2和第3个字节。如下所示:
[ZFLHRZHDB1:oracle]:/oracle>cat /tmp/exp_ddl_lhr_03.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 1-2,7-8
0369
[ZFLHRZHDB1:oracle]:/oracle>cat /tmp/exp_ddl_lhr_03.dmp |od -x|head -1
0000000 0303 4569 5058 524f 3a54 3156 2e30 3230
然后在数据库中可以查到十六进制0369代表的字符集:
SYS@lhrdb> SELECT NLS_CHARSET_NAME(TO_NUMBER('0369','XXXX')) FROM DUAL;
NLS_CHARSET_NAME(TO_NUMBER('0369','XXXX'
----------------------------------------
AL32UTF8
以上结果说明dmp文件的字符集是UTF8。常用的US7ASCII、ZHS16GBK和AL32UTF8对应的字符集ID如下所示:
SYS@lhrdb> SELECT NLS_CHARSET_NAME(TO_NUMBER('0001', 'XXXX')) US7ASCII,
2 NLS_CHARSET_NAME(TO_NUMBER('0354', 'XXXX')) ZHS16GBK,
3 NLS_CHARSET_NAME(TO_NUMBER('0369', 'XXXX')) AL32UTF8,
4 TO_CHAR(NLS_CHARSET_ID('US7ASCII'), 'XXXX') US7ASCII_ID,
5 TO_CHAR(NLS_CHARSET_ID('ZHS16GBK'), 'XXXX') ZHS16GBK_ID,
6 TO_CHAR(NLS_CHARSET_ID('AL32UTF8'), 'XXXX') AL32UTF8_ID
7 FROM DUAL;
US7ASCII ZHS16GBK AL32UTF8 US7ASCII_I ZHS16GBK_I AL32UTF8_I
------------- ----------- --------- ---------- ---------- ----------
US7ASCII ZHS16GBK AL32UTF8 1 354 369
若dmp文件在Windows平台下,则可以使用软件UltraEdit(UE)、EditPlus或Pilotedit等文本编辑工具以十六进制的方式打开dmp文件查看。其中,软件Pilotedit可以轻松打开上G的文件。示例如下:
需要注意的是,十六进制在Linux和Windows下顺序不同。
如果将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中,那么还需要根据文件修改第4行的第3-4个字节(即07 D0之前的2个字节)。
修改前:
修改后:
其实,也可以把第一行的第2-3字节,第4行的第1-4字节(即07 D0之前的4个字节)全部修改掉,也可以成功导入,如下所示:
& 说明:
将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-2138791/
本文选自《Oracle程序员面试笔试宝典》,作者:小麦苗