【问题标题】:Mutating table exception is not occurring没有发生变异表异常
【发布时间】:2019-02-11 19:38:16
【问题描述】:

我创建了一个触发器,并期待在以下情况下出现变异表错误,但没有通过正常插入得到一个,但在使用查询插入时出错。我不确定我在这里缺少哪个概念。

drop table temp;
create table temp (id number,name varchar2(500),is_active number);

create or replace trigger temp_trg before insert  on temp
for each row
declare 
v_count number;
begin
 select count(1) into v_count from temp;
 update temp set is_active=0 where is_active=1 and id=:new.id;
end;
/

select * from temp;

insert into temp values (1,'xyz',1);
insert into temp values (1,'xyz',1);
insert into temp select 1,'xyz',1 from dual;

【问题讨论】:

    标签: oracle plsql database-trigger


    【解决方案1】:

    使用查询插入时出错。

    当我们查询拥有触发器的表时,会发生变异表。具体来说,当 Oracle 无法保证查询的结果时会发生这种情况。现在,当您在表中插入单行时,Oracle 可以预测 FOR EACH ROW 触发器触发时的查询结果,因为它是单行。

    但是对于 INSERT FROM 查询,Oracle 感到困惑:计数应该是包含查询选择的所有行的最终数字还是只是滚动计数?在这种情况下,答案似乎很简单,但很容易想象其他问题的答案并不明确。 Oracle 不会对每个查询的可预测性进行评估,而是对所有查询驱动的插入强制执行一个普通的命令并抛出 ORA-04091。

    【讨论】:

      【解决方案2】:

      Mutating Tables 的限制适用于所有使用FOR EACH ROW 子句的触发器,除非满足以下任一条件:

      • 触发器在BEFORE 事件上触发,即数据实际上并未更改
      • 已知只有一行会受到影响 - INSERT ... VALUES 是唯一满足此条件的 DML

      【讨论】:

        猜你喜欢
        • 2016-08-25
        • 1970-01-01
        • 1970-01-01
        • 2010-09-12
        • 2019-11-11
        • 1970-01-01
        • 2021-09-18
        • 2021-04-15
        • 1970-01-01
        相关资源
        最近更新 更多