【问题标题】:ORA-04091: table is mutating when using cursor in trigger to insert in other tableORA-04091: 在触发器中使用游标插入其他表时,表正在发生变化
【发布时间】:2018-11-20 03:47:53
【问题描述】:
create table dept(dno number(3) primary key)
create table emp(eno number(3) primary key,dno number(3) references dept)
create table emp_cnt(dno number(3),cnt number(3),foreign key(dno) references dept)

insert all
into dept values(101)
into dept values(102)
into dept values(103)
into dept values(104)
into dept values(105)
select * from dual

create or replace trigger count_emp after insert or update or delete on emp for each row
declare
cursor c1 is select dno,count(eno) cnt from emp group by dno;
begin
for row in c1
loop
insert into emp_cnt(dno,cnt) values(row.dno,row.cnt);
end loop;
end;

insert into emp values(1,101)

当我尝试像上面的语句那样在“emp”表中插入数据时,它会显示一个错误,告诉我我的“emp”表正在发生变化。下面我显示了它显示的确切错误

ORA-04091: table SYSTEM.EMP is mutating, trigger/function may not see it
ORA-06512: at "SYSTEM.COUNT_EMP", line 2
ORA-06512: at "SYSTEM.COUNT_EMP", line 4
ORA-04088: error during execution of trigger 'SYSTEM.COUNT_EMP'
1. insert into emp values(1,101)

最后一次插入我在“emp”表中插入,这将调用触发器“emp_count”,在这个触发器中,我使用游标来计算每个部门的员工人数,然后我插入'emp_cnt'表中游标的数据

【问题讨论】:

  • 同一张表插入后不能再插入表中,即使有效也会导致死循环。您可能想解释一下您想通过最后一个插入来实现什么。无论如何,看到这个问题:stackoverflow.com/questions/8167200/…stackoverflow.com/questions/34227363/…
  • 我已经编辑了帖子,解释了最后一次插入会发生什么,抱歉一开始信息较少。
  • 对不起,我一开始没看懂你的代码示例。问题是您试图从emp 中进行选择,而这不能在emp 的触发器中完成。您可能需要重新考虑您的方法。或许,您可以使用:new.dno 更新此特定记录的计数,而不是每次都插入整个表。
  • 好的,感谢您的帮助

标签: oracle triggers


【解决方案1】:

如 cmets 中所述,您无法查询或修改作为触发器所有者的表,否则会导致错误。

触发器不适用于此类要求。请改用View

create or replace view  emp_cnt
 AS
 select dno,count(eno) cnt from emp 
group by dno;


insert into emp values(1,101);
insert into emp values(2,101);
insert into emp values(3,102);


select * from  emp_cnt;

DNO CNT
102 1
101 2

Demo

【讨论】:

  • 我没有修改'emp'表,它是触发器的所有者,我只是在那个表上触发一个 SELECT 查询。我正在修改‘emp_cnt’表
  • @PruthviGandhi :请再读一遍,我说“无法查询或修改表”,这意味着您甚至无法进行选择。请参阅问题下方评论中提到的链接以了解更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-02
  • 2016-08-02
  • 1970-01-01
  • 2011-11-18
  • 2011-05-21
  • 2015-06-28
  • 1970-01-01
相关资源
最近更新 更多