标签: ora-04091

ORA-04091:表[blah]正在变异,触发器/函数可能看不到它

我最近开始研究一个大型的复杂应用程序,我刚刚因为这个错误而被分配了一个错误:

ORA-04091: table SCMA.TBL1 is mutating, trigger/function may not see it
ORA-06512: at "SCMA.TRG_T1_TBL1_COL1", line 4
ORA-04088: error during execution of trigger 'SCMA.TRG_T1_TBL1_COL1'
Run Code Online (Sandbox Code Playgroud)

有问题的触发器看起来像

    create or replace TRIGGER TRG_T1_TBL1_COL1
   BEFORE  INSERT OR UPDATE OF t1_appnt_evnt_id ON TBL1
   FOR EACH ROW
   WHEN (NEW.t1_prnt_t1_pk is not  null)
   DECLARE
        v_reassign_count number(20);
   BEGIN
       select count(t1_pk) INTO v_reassign_count from TBL1
              where  t1_appnt_evnt_id=:new.t1_appnt_evnt_id and t1_prnt_t1_pk is not null;
       IF (v_reassign_count > 0) THEN
           RAISE_APPLICATION_ERROR(-20013, 'Multiple reassignments not allowed');
       END IF;
   END;
Run Code Online (Sandbox Code Playgroud)

该表具有主键" t1_pk","约会事件id" t1_appnt_evnt_id和另一列" …

oracle triggers hibernate ora-04091

6
推荐指数
1
解决办法
2万
查看次数

Oracle触发器 - 变异表的问题

我的桌子:

TableA (id number, state number)
TableB (id number, tableAId number, state number)
TableC (id number, tableBId number, state number)
Run Code Online (Sandbox Code Playgroud)

因此TableC中的项是TableB的子项,TableB中的项是TableA的子项.反之亦然 - TableA中的项是TableB的父项,TableB中的项是TableC的父项.

我想控制父项的状态......比方说,我们有这些数据:

TableA (id, state): 
1, 40

TableB (id, tableAId, state): 
1, 1, 40
2, 1, 60

TableC (id, tableBId, state): 
1, 1, 40
2, 1, 50
3, 2, 60
4, 2, 70
Run Code Online (Sandbox Code Playgroud)

父母国家应该始终保持他孩子最小的状态.所以如果我们现在像这样更新TableC:

update TableC set state = 50 where Id = 1;
Run Code Online (Sandbox Code Playgroud)

我的触发器应该自动更新TableB(设置状态= 50,其中id = 1),然后更新TableA(设置状态= 50,其中id = 1)

我想用触发器(在表A,表B,表C上进行更新,插入,删除之后)执行此操作,以便在执行每个操作后执行以下步骤:

  1. 得到父ID
  2. 从当前父母的所有孩子中找到最小的状态
  3. 如果所有子项的最小状态大于父项的状态,则更新父项

如何避免"改变表错误"?在此示例中是否可以节省使用自治事务?我看到一些意见,变异表错误表明应用程序的逻辑存在缺陷 - 这是真的吗?如何更改我的逻辑以防止此错误? …

oracle triggers ora-04091 mutating-table

6
推荐指数
2
解决办法
5129
查看次数

删除触发后的Oracle ...如何避免变异表(ORA-04091)?

假设我们有以下表格结构:

documents      docmentStatusHistory      status
+---------+   +--------------------+    +----------+
| docId   |   | docStatusHistoryId |    | statusId |
+---------+   +--------------------+    +----------+
| ...     |   | docId              |    | ...      |
+---------+   | statusId           |    +----------+
              | ...                |
              +--------------------+
Run Code Online (Sandbox Code Playgroud)

可能很明显,但值得一提的是,文档的当前状态是输入的最后一个状态历史记录.

系统缓慢但肯定会降低性能,我建议将上述结构更改为:

documents           docmentStatusHistory      status
+--------------+   +--------------------+    +----------+
| docId        |   | docStatusHistoryId |    | statusId |
+--------------+   +--------------------+    +----------+
| currStatusId |   | docId              |    | ...      |
| ...          |   | statusId           |    +----------+
+--------------+   | ...                |
                   +--------------------+
Run Code Online (Sandbox Code Playgroud)

这样我们就可以将文档的当前状态放在应有的位置.

由于遗留应用程序的构建方式,我无法更改旧应用程序上的代码以更新文档表上的当前状态. …

oracle triggers ora-04091

5
推荐指数
1
解决办法
8370
查看次数

Oracle 复合触发器 - 如何存储和“使用”已删除的行?按表索引?

我现在正在为 Oracle 中的 DELETE 触发器进行长期斗争,该触发器在删除一行后,从剩余行中选择一个新的 MAX 值并将其写入另一个表。在偶然发现烦人的 ORA-04091 变异表错误(在 FOR EACH ROW 中无法读取表)之后,我切换到了 Oracle 的复合触发器。

如何最好地存储已删除的行(每行多个值,因为只有当删除的分数可能是高分,而不是较低分数时,进一步检查才会更新)?我担心,如果多个触发事件交叉触发,并且例如为“DeletedMatches”运行高分更新(该更新实际上并未被删除,而是由 Before 触发事件注册),则全局临时表可能会陷入混乱。

我可以创建一个表,a) 仅存在于该触发器中 b) 可以像普通数据库表或临时表一样在 SQL 中使用吗?

每当删除匹配项时,以下(伪)代码将更新 CurrentHighScores 表(旧的高分消失并被剩余的最高分取代)。

CREATE TABLE GameScores (
    MatchId number not null --primary key
    Player  varchar(255) not null,
    Game    varchar(255) not null, -- PacMan, Pong, whatever...
    Score   number not null );

-- High score for each game:
CREATE TABLE CurrentHighScores (
    HiScId number not null --primary key
    Player  varchar(255) not null,
    Game    varchar(255) not null,
    HighScore   number …
Run Code Online (Sandbox Code Playgroud)

oracle triggers delete-row ora-04091

3
推荐指数
1
解决办法
3212
查看次数

ORA-04091 - 如何更改触发器触发的表?

所以我有表foo,我想foo在触发器t_foo触发时删除其他行:

CREATE OR REPLACE TRIGGER "t_foo" AFTER INSERT OR DELETE OR UPDATE ON foo

/*delete some other records from foo that are not :NEW.* or :OLD.* \*
Run Code Online (Sandbox Code Playgroud)

如果没有获得ORA-04091:表名,我将如何进行此操作变异,触发器/函数可能看不到它.这甚至可能吗?

sql oracle triggers ora-04091

1
推荐指数
2
解决办法
948
查看次数

ORA-04091在xxx上插入更新之前创建或替换触发器xxx

有人可以帮我纠正下面的触发器吗?我被分配了这个问题,但我的技术技能有限.

我的脚本点击了下面的错误(ORA 4091):

处理标准采购订单编号:27179

......................................

更新PO状态..

完成批准处理.

dist id 611294gl金额10000.88 bill_del_amount 0 l_amount 10000.88

发生了一些异常**ORA-04091:表PO.PO_DISTRIBUTIONS_ALL正在变异,

触发器/功能可能看不到它**

ORA-06512:在"APPS.XXAET_PO_DELIVER_TO_TRG",

第22行

ORA-01403:未找到任何数据

ORA-04088:执行触发期间出错

"APPS.XXAET_PO_DELIVER

PL/SQL过程成功完成.

SQL>

我设法在客户端机器中找到自定义触发器,但在研究之后我无法确定sql的错误点.请帮忙!

CREATE OR REPLACE TRIGGER apps.xxaet_po_deliver_to_trg
BEFORE INSERT OR UPDATE ON po_distributions_all
   FOR EACH ROW
DECLARE
   l_emp_name   VARCHAR2 (300);
   l_sqlcode    VARCHAR (30)   := SQLCODE;
   l_sqlerrm    VARCHAR (400)  := SUBSTR (SQLERRM, 1, 399);
   x_profile_value  VARCHAR (10) ;
BEGIN

x_profile_value := fnd_profile.value('ORG_ID');
  Select Ship_To_Location_ID
  INTO :NEW.Deliver_To_Location_Id
  from PO_LINE_LOCATIONS_ALL
  WHERE line_location_id = :NEW.line_location_id
  AND ORG_ID = x_profile_value
  ;

EXCEPTION
   WHEN …
Run Code Online (Sandbox Code Playgroud)

oracle triggers plsql exception ora-04091

0
推荐指数
1
解决办法
5680
查看次数

简单的oracle触发器

简单的一个.我有点像PLSql的新手,oracle的错误信息永远不会太有帮助.

我想做一个简单的触发器来更新具有当前日期的列,即表的"修改日期"列.虽然得到一个奇怪的错误.

这个想法很简单

create table test1 (tcol varchar2(255), tcol2 varchar2(255))

CREATE OR REPLACE TRIGGER testTRG
AFTER INSERT OR UPDATE ON test1
FOR EACH ROW
BEGIN 
     update test1
     set tcol2 =  to_char(sysdate)
     where tcol = :OLD.tcol;
END;

insert into test1 (tcol) values ('test1');
Run Code Online (Sandbox Code Playgroud)

这会弹出错误:

ORA-04091: table RAIDBIDAT_OWN.TEST1 is mutating, trigger/function may not see it
ORA-06512: at "RAIDBIDAT_OWN.TESTTRG", line 2
ORA-04088: error during execution of trigger 'RAIDBIDAT_OWN.TESTTRG'
Run Code Online (Sandbox Code Playgroud)

有人可以快速解决这个问题吗?

干杯,

F.

oracle triggers plsql ora-04091 mutating-table

0
推荐指数
1
解决办法
5812
查看次数