触发取消交易

时间:2015-05-05 16:49:23

标签: sql oracle triggers oracle11g transactions

我必须基于涉及四个表的相对复杂的查询来实施规则。如果任何表更新/插入/删除,我需要运行相同的查询来检查是否应该拒绝该操作(通过抛出异常)。

我认为必须有四个独立的触发器,因为看起来CREATE TRIGGER只接受一个" on"条款;但我不想重复查询,而是将其保存在单独的存储过程中。

我想知道是否有一种方法可以为验证查询提供数据库状态的表示,就像触发事件的事件一样;并且如果需要,让查询能够取消该事务,回滚到触发器触发之前的状态。这不是每行"之前/每行#34;是的,我想;因为它使用:new:old - 如果我要使用新行,我将不得不重写查询四次,用new替换每个相应的表。

改编答案:

即使我尽力使自己变得可怕并且设置了自动提交,但是在声明之后#39;触发做正确的事;即,在该块的底部没有选择任何行。

create or replace trigger test_after_tr
  after insert or update or delete on footable
begin
  raise_application_error(-20000, 'violated');
end;
/

set autocommit on;
begin
  execute immediate 'set autocommit on';
  insert into footable(name) values('fail');
exception when others then null;
end;
/

select * from footable where name = 'fail';

1 个答案:

答案 0 :(得分:3)

您可以使用" after语句"在语句后看到数据库状态。触发(即省略for each row子句)。但是,您无法在语句级触发器中访问oldnew。您可以检查4个表中的数据是否会破坏您的规则(可能很慢),或者您可以在每个表上使用行级触发器来记录PL / SQL集合中受影响记录的键,然后您可以使用它们在" after语句后执行更具选择性的查询"触发。