日期:2014-05-16  浏览次数:20495 次

有关触发器 ORA-04091解决方法
最近在写触发器的时候预到了这个问题,经多方查找,得出
1.于after 类型的 for each row 级别的triggers,不论哪种insert语句触发了trigger,都不允许在 trigger 中访问本trigger所依赖的table的
2.对于before 类型的 for each row 级别的triggers,如果使用 insert into ... values 语句触发此trigger ,则在trigger 中访问本table没有问题;
但如果使用 insert into select .. from 语句触发此trigger ,则在trigger 中访问本table就报ora-04091错误;



解决方法,用oracle的自治事务

create or replace trigger twininfo_trriger
  after insert on twininfo for each row

declare
  PRAGMA AUTONOMOUS_TRANSACTION;--开启自治事务
begin
     IF INSERTING THEN

     if :new.lotno='T01012' then
     update twininfo set info='100_234100_100,1_1_1300;2_1_600;3_1_6500;4_1_13000;5_1_1900;6_1_19500;7_1_117000;8_1_7800;9_1_54000;10_1_9000;11_1_2600;12_1_900'
     where lotno= :new.lotno and batchcode= :new.batchcode;
     dbms_output.put_line(:new.lotno||'====='||:new.batchcode);
     commit;
      dbms_output.put_line('提交'||'=====');
     end if;
      if :new.lotno='T01001' then
     update twininfo set info='8442562400_2232960500_13276345700,1_0_0;2_37_12540700;3_61_1856200;4_133_300000;5_3439_60000;6_12371_10000;7_153408_1000;8_1830877_500;11_0_0;12_8_7524400;13_16_1113700;14_33_150000;15_1021_30000;16_3624_5000;17_46687_500;18_10312_6000'
        where lotno= :new.lotno and batchcode= :new.batchcode;
       commit;
     end if;
 END IF;

 end;


其实最简单应该是:

 create or replace trigger twininfo_trriger
  before insert on twininfo for each row


begin
     IF INSERTING THEN

     if :new.lotno='T01012' then
  

      :new.info :='100_234100_100,1_1_1300;2_1_600;3_1_6500;4_1_13000;5_1_1900;6_1_19500;7_1_117000;8_1_7800;9_1_54000;10_1_9000;11_1_2600;12_1_900';
     end if;
     if :new.lotno='T01001' then
     :new.info :='8442562400_2232960500_13276345700,1_0_0;2_37_12540700;3_61_1856200;4_133_300000;5_3439_60000;6_12371_10000;7_153408_1000;8_1830877_500;11_0_0;12_8_7524400;13_16_1113700;14_33_150000;15_1021_30000;16_3624_5000;17_46687_500;18_10312_6000';
 
    end if;
 END IF;

 end;


别人的例子:
create or replace trigger TR_U_ID_SYNCH
  before update on COMPANY referencing old as old_value
    new as new_value
  for each row
declare
tId  company.id%type;
PRAGMA AUTONOMOUS_TRANSACTION;
begin
if :new_value.U_ID is not null and :new_value.U_ID!=ld_value.U_ID  then
   select t.t_id into tId from company t where t.id= :new_value.U_ID;
   :new_value.P_ID :=:new_value.U_ID;
   :new_value.T_ID :=tId;
end if;
COMMIT;
end TR_CO_GB_ID_SYNCH;