首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

解决ORA-04091行触发器中访问变异表的偏题

2012-12-21 
解决ORA-04091行触发器中访问变异表的难题核心思路就是:在第一次插入时保存值到包变量中,第二次插入时不再

解决ORA-04091行触发器中访问变异表的难题

核心思路就是:在第一次插入时保存值到包变量中,第二次插入时不再读取表本身,转而读取包变量,可以成功解决这类难题。

在工作中,需要为各个BOM的每个ITEM依次自动编号,不同BOM的ITEM的SEQ_NUMBER列都要 按1.2.3…自动生成序号。
第一次,我这样写,

解决ORA-04091行触发器中访问变异表的偏题CREATE?OR?REPLACE?TRIGGER?TR_BOM_AUTONUMBER_SEQNUMBER
解决ORA-04091行触发器中访问变异表的偏题BEFORE?INSERT
解决ORA-04091行触发器中访问变异表的偏题ON?BOM?
解决ORA-04091行触发器中访问变异表的偏题REFERENCING?NEW?AS?NEW?OLD?AS?OLD
解决ORA-04091行触发器中访问变异表的偏题FOR?EACH?ROW
解决ORA-04091行触发器中访问变异表的偏题DECLARE
解决ORA-04091行触发器中访问变异表的偏题????tmpVar?number;
解决ORA-04091行触发器中访问变异表的偏题BEGIN
解决ORA-04091行触发器中访问变异表的偏题????tmpVar?:=?0;
解决ORA-04091行触发器中访问变异表的偏题???SELECT?GREATEST(nvl(Max(to_number(SEQ_NUMBER)),0),?Count(*))?+?1?INTO?tmpVar?FROM?BOM?Where?BOMID=:New.BOMID;
解决ORA-04091行触发器中访问变异表的偏题???:NEW.?SEQ_NUMBER:=?nvl(tmpVar,1);
解决ORA-04091行触发器中访问变异表的偏题END?TR_BOM_AUTONUMBER_SEQNUMBER;
解决ORA-04091行触发器中访问变异表的偏题

由于Insert操作会修改表数据,所以Insert…Select插入多行数据时,会报ORA-04091: table string.string is mutating, trigger/function may not see it错误,原因在于插入第2条数据时表已修改不能再访问。

查阅了很多文章,有提示在其中使用 PRAGMA AUTONOMOUS_TRANSACTION来保证每行插入动作为自治事务。但实际上,经过我的测试,虽然DML不会出错,但实际SEQ_NUMBER全部为1,没有达到依次自动编号的目的。

经过多次试验后,我使用保存于包中的索引表保存各个BOM的最大SEQ_NUMBER,可以防止BOM之间及用户之间的并发冲突。

核心思路就是:在第一次插入时保存值到包变量中,第二次插入时不再读取表本身,转而读取包变量,可以成功解决这类难题。

详细代码如下:

解决ORA-04091行触发器中访问变异表的偏题CREATE?OR?REPLACE?PACKAGE?BOM_AUTONUMBER
解决ORA-04091行触发器中访问变异表的偏题IS
解决ORA-04091行触发器中访问变异表的偏题TYPE?t_MAX_SEQNUMBER?is?table?of?number?INDEX?BY?PLS_INTEGER;
解决ORA-04091行触发器中访问变异表的偏题v_MAX_SEQNUMBER?t_MAX_SEQNUMBER;
解决ORA-04091行触发器中访问变异表的偏题end?BOM_AUTONUMBER;
解决ORA-04091行触发器中访问变异表的偏题/解决ORA-04091行触发器中访问变异表的偏题解决ORA-04091行触发器中访问变异表的偏题CREATE?OR?REPLACE?TRIGGER?TR_BOM_AUTONUMBER_SEQNUMBER
解决ORA-04091行触发器中访问变异表的偏题BEFORE?INSERT
解决ORA-04091行触发器中访问变异表的偏题ON?BOM?
解决ORA-04091行触发器中访问变异表的偏题REFERENCING?NEW?AS?NEW?OLD?AS?OLD
解决ORA-04091行触发器中访问变异表的偏题FOR?EACH?ROW
解决ORA-04091行触发器中访问变异表的偏题DECLARE
解决ORA-04091行触发器中访问变异表的偏题????vNumber?number;
解决ORA-04091行触发器中访问变异表的偏题????vBOMID?number;
解决ORA-04091行触发器中访问变异表的偏题BEGIN
解决ORA-04091行触发器中访问变异表的偏题????vNumber:=?0;
解决ORA-04091行触发器中访问变异表的偏题????vBOMID:=?:New.BOMID;
解决ORA-04091行触发器中访问变异表的偏题????if?not?BOM_AUTONUMBER.v_MAX_SEQNUMBER.EXISTS(vBOMID)?then
解决ORA-04091行触发器中访问变异表的偏题????????SELECT?GREATEST(nvl(Max(to_number(SEQ_NUMBER)),0),?Count(*))?INTO?vNumber?FROM?BOM?Where?ITEM?=?vBOMID;
解决ORA-04091行触发器中访问变异表的偏题????????BOM_AUTONUMBER.v_MAX_SEQNUMBER(vBOMID)?:=?nvl(vNumber,?0);
解决ORA-04091行触发器中访问变异表的偏题????end?if;
解决ORA-04091行触发器中访问变异表的偏题????BOM_AUTONUMBER.v_MAX_SEQNUMBER(vBOMID)?:=?BOM_AUTONUMBER.v_MAX_SEQNUMBER(vBOMID)?+?1;
解决ORA-04091行触发器中访问变异表的偏题???:NEW.SEQ_NUMBER?:=?BOM_AUTONUMBER.v_MAX_SEQNUMBER(vBOMID);
解决ORA-04091行触发器中访问变异表的偏题END?TR_BOM_?AUTONUMBER_SEQNUMBER;
解决ORA-04091行触发器中访问变异表的偏题/

热点排行