如果“之后”DDL 触发器导致错误,DDL 是否回滚?

Jac*_*las 5 trigger oracle ddl rollback

已建议该DDL在逻辑上进行这样的事情:

begin
    COMMIT;
    perform any appropriate pre-DDL trigger code;
    do the ddl;
    perform any appropriate post-DDL trigger code;
    COMMIT;
exception
    when others then
         ROLLBACK;
         raise;
end;
Run Code Online (Sandbox Code Playgroud)

这表明触发器中的任何错误都会导致 DDL 回滚。是这种情况吗?

Jac*_*las 9

至少在 11.2 上,答案是“这取决于”:

create是回滚的:

create trigger trig_foo after create on schema
begin
  raise_application_error(-20001, 'Dont do it!');
end;
/
--
create table foo as select level as id from dual connect by level<=10000;
/*
SQL Error: ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Dont do it!
*/
--
select count(*) from foo;
/*
SQL Error: ORA-00942: table or view does not exist
*/
Run Code Online (Sandbox Code Playgroud)

但这truncate不是:

create table foo as select level as id from dual connect by level<=10000;
--
create trigger trig_foo after truncate on schema
begin
  raise_application_error(-20001, 'Dont do it!');
end;
/
--
truncate table foo;
/*
SQL Error: ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Dont do it!
*/
select count(*) from foo;
/*
COUNT(*)               
---------------------- 
0                  
*/
Run Code Online (Sandbox Code Playgroud)