如果出现错误,如何使DBMS_DATAPUMP错误?

Ben*_*Ben 5 oracle plsql oracle11gr2

当源表和目标表中的列不匹配时,DBMS_DATAPUMP不会失败。这意味着不会引发任何异常。我正在尝试使用GET_STATUS过程来了解是否有任何错误,但不幸的是似乎没有...

我的最终目标是让DBMS_DATAPUMP在导入失败的情况下引发异常。不同的列是一个易于使用的示例,因为我知道它应该失败。

这是我当前的代码(我故意遮盖了模式名称)。我使用的环境在两台服务器上都是相同的,只是我向源表添加了额外的列。我还对表中的行数进行计数。

connect schema/*@db1/db1
-- */

create table tmp_test_datapump as
 select u.*, cast(null as number) as break_it
   from user_tables u;

Table created.


select count(*) from tmp_test_datapump;

  COUNT(*)
----------
      1170

connect schema/*@db2/db2
-- */

set serveroutput on

create table tmp_test_datapump as
 select u.*
   from user_tables u;

Table created.
Run Code Online (Sandbox Code Playgroud)

在尝试对此进行测试时,DATAPUMP代码变得有些复杂。无限循环中的所有内容都可以删除,其作用相同。

declare
   l_handle number;
   l_status varchar2(255);
   l_job_state varchar2(4000);
   l_ku$status ku$_status1020;
begin
   l_handle := dbms_datapump.open( operation => 'IMPORT'
                                 , job_mode => 'TABLE'
                                 , remote_link => 'SCHEMA.DB.DOMAIN.COM'
                                 , job_name => 'JOB_TEST_DP'
                                 , version => 'COMPATIBLE' );
   dbms_datapump.set_parameter( handle => l_handle
                              , name => 'TABLE_EXISTS_ACTION'
                              , value => 'TRUNCATE');
   dbms_datapump.metadata_filter( handle => l_handle
                                , name => 'NAME_EXPR'
                                , value => 'IN (''TMP_TEST_DATAPUMP'')');
   dbms_datapump.start_job(handle => l_handle);

   while true loop
      dbms_datapump.wait_for_job(handle => l_handle,job_state => l_status);

      if l_status in ('COMPLETED','STOPPED') then
         exit;
      end if;

      dbms_datapump.get_status( handle => l_handle
                              , mask => dbms_datapump.KU$_STATUS_JOB_ERROR
                              , job_state => l_job_state
                              , status => l_ku$status);
      dbms_output.put_line('state: ' || l_job_state);
      if l_ku$status.error is not null and l_ku$status.error.count > 0 then

         for i in l_ku$status.error.first .. l_ku$status.error.last loop
            dbms_output.put_line(l_ku$status.error(i).logtext);
         end loop;
       end if;
   end loop;

end;
/

PL/SQL procedure successfully completed.

select count(*) from tmp_test_datapump;

  COUNT(*)
----------
        47
Run Code Online (Sandbox Code Playgroud)

如您所见,表中的记录数是不同的。导入失败,并且未引发任何异常。各种各样的 博客DBA.SE问题暗示可以进行某种错误捕获。但我似乎无法管理。

如何在DBMS_DATAPUMP导入中捕获致命错误?

小智 0

当为impdp创建日志时,您可以将datapump命令放入shell脚本中,在结束shell脚本之前,您可以检查日志中是否有IMP-错误或ORA-错误,如果为true,则警告用户查看日志文件中的错误。