我创建了一个触发器,并在以下情况下期望发生突变表错误,但没有通过常规插入得到一个,但是在使用查询插入时却得到了错误。我不确定在这里缺少哪个概念。
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;
答案 0 :(得分:3)
在使用查询插入时出错。
当我们查询拥有触发器的表时,发生突变表。具体来说,当Oracle无法保证查询结果时,就会发生这种情况。现在,当您在表中插入一行时,由于FOR EACH ROW触发器触发,Oracle可以预测查询的结果,因为它是一行。
但是对于INSERT FROM查询,Oracle感到困惑:计数应该是包含查询选择的所有行的最终数字还是只是滚动计数?在这种情况下,答案似乎很简单,但是很容易想到其他答案不明确的查询。 Oracle不会对每个查询的可预测性进行评估,而是对所有查询驱动的插入强制执行常规命令和ORA-04091。
答案 1 :(得分:1)
对突变表的限制适用于所有使用FOR EACH ROW
子句的触发器,除非满足以下任一条件:
BEFORE
事件上触发触发器,即数据实际上并未更改INSERT ... VALUES
是唯一满足此条件的DML