突变表异常未发生

时间:2018-09-06 13:57:24

标签: oracle plsql database-trigger

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

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;

2 个答案:

答案 0 :(得分:3)

  

在使用查询插入时出错。

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

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

答案 1 :(得分:1)

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

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