在删除触发器上选择表时突变触发器

时间:2015-11-26 06:29:57

标签: sql oracle plsql triggers mutating-table

请帮助以下。 我有一个有两行的表,在删除一行时,我写了一个触发器,我想将记录写入另一行的临时表(staging_tbl),删除后将留下。 但它会抛出一个有效的变异触发错误。但有没有办法可以避免它并将记录写入临时表,只有主表中有2行,其中一行被删除(而不是表中的所有删除)。

create or replace TRIGGER a_del_trg
  after delete on item_master
  for each row

DECLARE

  l_item NUMBER :=0;
  l_item_parent number :=0;
BEGIN

  INSERT INTO tmp_chk (item,item_parent) VALUES (:OLD.item,:OLD.item_parent);

  SELECT a.item,a.item_parent INTO l_item , l_item_parent
  FROM item_master a , tmp_chk  b  WHERE  a.item_parent = b.item_parent
  and a.item != b.item;

      INSERT INTO staging_tbl
        (create_date, table_name, item_sku, if_name)
      values
        (SYSDATE, 'Item_master', l_item, 'W'); -- want to add the remaining item here
    END IF;

END a_del_trg;

1 个答案:

答案 0 :(得分:1)

<强> PRAGMA AUTONOMOUS_TRANSACTION

我使用以下声明重现了您的错误:

create table item_master(item number, item_parent number);
insert into item_master values (1, 10);
insert into item_master values (2, 10);

create table tmp_chk(item number, item_parent number);

create table staging_tbl(create_date date, table_name varchar2(30), item_sku number, if_name varchar2(10));

我使用了你的触发器(在触发器结束时删除END IF残留代码后)。我收到错误"ORA-04091: table name is mutating, trigger/function may not see it." message.

参考这个好的解释Fix Oracle mutating trigger table errors,必须重申以下摘录:

  

在一天结束时,变异表错误通常是应用程序设计不良的结果,应尽可能避免使用变异触发器。

在参考autonomous transactions中的第四个选项之后,我按如下方式重写了你的触发器:

create or replace TRIGGER a_del_trg
  after delete on item_master
  for each row

DECLARE

  l_item NUMBER :=0;
  l_item_parent number :=0;
  pragma autonomous_transaction;
BEGIN

  INSERT INTO tmp_chk (item,item_parent) VALUES (:OLD.item,:OLD.item_parent);

  SELECT a.item,a.item_parent INTO l_item , l_item_parent
  FROM item_master a , tmp_chk  b  WHERE  a.item_parent = b.item_parent
  and a.item != b.item;

      INSERT INTO staging_tbl
        (create_date, table_name, item_sku, if_name)
      values
        (SYSDATE, 'Item_master', l_item, 'W'); -- want to add the remaining item here
commit;
END a_del_trg;
/

运行查询:

select * from item_master;
2   10

select * from tmp_chk ;
1   10

select * from staging_tbl;
27-NOV-15   Item_master 2   W

ROLLBACK

来自here

  

&#34; ...如果你发现自己被迫&#34;强迫&#34;用一个   自动交易 - 这可能意味着您拥有严肃的数据   你没想过的诚信问题。

     

人们在哪里尝试使用它们?

     
      
  • 在该触发器中调用提交的过程(不是错误   记录例程)。哎哟,你回滚时必须受伤。
  •   
  • 在该触发器中获取变异表约束。哎哟,那个   伤害甚至更多
  •   
  • 错误记录 - 确定。
  •   
  • 几乎所有其他事情 - 不行。&#34;
  •