ALTER INDEX "MNG"."IND_ADTAB1_UID" NOPARALLEL;
CREATE INDEX "MNG"."IND_ADTAB1_CRT" ON "AD"."ADTAB1" ("CREATED")
PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 8388608 NEXT 8388608 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TS_PUB" PARALLEL 1 ;
ALTER INDEX "MNG"."IND_ADTAB1_CRT" NOPARALLEL;
。。。其它部分略
#####最后执行导入
---导入前赋予imp_full_database较色给ad,因为要导入的内容里包含了其它Schema信息
grant imp_full_database to ad;
---导入成功
impdp ad/123456 directory=tmpdir dumpfile=ad.adtab1.dmp logfile=imp_ad.adtab1.log
Master table "AD"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "AD"."SYS_IMPORT_FULL_01": ad/******** directory=tmpdir dumpfile=ad.adtab1.dmp logfile=imp_ad.adtab1.log
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "AD"."ADTAB1" 6.781 KB 45 rows
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Job "AD"."SYS_IMPORT_FULL_01" successfully completed at 09:35:56
####结果检查OK
set linesize 180
SQL> select count(*) from adtab1;
COUNT(*)
----------
45
select owner,index_name,status,table_owner,table_name from dba_indexes where table_name='ADTAB1';
OWNER INDEX_NAME STATUS TABLE_OWNER TABLE_NAME
------------------------------ ------------------------------ -------- ------------------------------ ------------------------------
MNG IND_ADTAB1_CRT VALID AD ADTAB1
MNG IND_ADTAB1_UID VALID AD ADTAB1
总结:本例中导致ORA-39154的根本问题在于ad表上的索引没有建在ad用户下,这样的情况称为cross schema references,即不同schema的对象间存在关联,cross schema references导致的impdp错误还是比较隐蔽的,好在我们使用了sysdba权限从源库expdp导出表,然后通过impdp时有关统计信息无法导入的ORA-39154错误,一步一步追溯直至发现索引和表不在同一个schema下,问题才得以精确定位。这个案例也告诉我们在table mode export的方式下,如果依赖于a.taba表的对象,比如基于a.taba的索引名为index_b,建在了b用户下,那么下面的命令在导出结果里不会包含b用户下的索引
expdp user/passwd tables=a.taba directory=dirname dumpfile=a.taba.dmp logfile=exp_a.taba.dmp
必须使用schemas、include参数精确指定表名和索引名称,例如:
expdp user/passwd schemas=a,b include=TABLE:\"=\'TABA\'\",INDEX:\"IN \(\'INDEX_B\'\)\" directory=dirname dumpfile=a.taba.dmp logfile=exp_a.taba.dmp
顺便提一句,如果我们一开始从源库导出表的时候没有像下面这样使用sysdba权限
expdp \"/ as sysdba\" tables=ad.adtab1 directory=tmpdir dumpfile=ad.adtab1.dmp logfile=exp_ad.adtab1.log reuse_dumpfiles=yes
而是像下面这样使用ad用户
expdp ad/123456 tables=ad.adtab1 directory=tmpdir dumpfile=ad.adtab1.dmp logfile=exp_ad.adtab1.log reuse_dumpfiles=yes
那么在之后impdp时是不会收到任何报错的。这样造成的结果却很严重:目标库上的表应该有索引的字段却没有建索引。