【问题标题】:mutating trigger, when we can read from triggering table and when not?变异触发器,什么时候可以从触发表中读取,什么时候不可以?
【发布时间】:2014-03-10 19:35:29
【问题描述】:

我有 2 个触发器,它们都是行级的,并从触发表中读取数据。我的问题是为什么其中一个(trg1)会导致 MUTATING 触发错误,而另一个(trg2)不会。为什么只有其中一个可以选择触发表?我知道自主交易的可能性。我只想了解规则什么时候可以从触发表中读取,什么时候不可以。

触发器:

CREATE OR REPLACE TRIGGER trg1
   AFTER INSERT OR UPDATE
   ON employees
   FOR EACH ROW
DECLARE
   myval   NUMBER
BEGIN
   SELECT COUNT (*)
     INTO myval
     FROM employees;
END;

CREATE OR REPLACE TRIGGER trg2
BEFORE INSERT ON tab_1
FOR EACH ROW
DECLARE
  CURSOR c IS SELECT * FROM tab_1 WHERE col_1 = :NEW.col_1;
BEGIN
  FOR i IN c LOOP
    INSERT INTO tab_2 
    VALUES (:NEW.col_1, :NEW.col_2, NULL );
  END LOOP;
END;

谢谢, T

【问题讨论】:

  • 触发后会出现错误,因为你在修改表的同时试图读取表,事务还没有完成。所以在这种情况下oracle不想读取不一致的数据frm被修改的同一张表。而在触发器之前没有任何更改,它允许您在对表执行 dml 操作之前从表中读取。
  • 如果我们将第一个触发器更改为 BEFORE INSERT,它仍然是一个变异触发器。
  • 你是在告诉我,在将其更改为插入触发器之前,它仍然给你这个错误吗?
  • 是的,我试过了,它还在变异。

标签: oracle plsql triggers


【解决方案1】:

行级触发器只能从表中读取

  • 如果是 BEFORE INSERT 触发器
  • 如果是单行操作

因此,两个触发器都会引发 ORA-04091 - AFTER INSERT 总是会引发一个,只有在您尝试多行 INSERT 时才会引发 BEFORE INSERT。

尝试运行以下语句:

insert into tab_1(col_1, col_2) 
(select 'b', 'seven' from dual union all select 8, 'c', 'eight' from dual);

你也会得到一个 ORA-04091。

详情请见Database journal article on mutating tables

【讨论】:

  • 不客气。如果这解决了您的问题,请考虑将答案标记为已接受。
猜你喜欢
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
  • 2017-04-08
  • 2017-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多