触发器引起ORA-04091

联系:手机(+86 13429648788) QQ(107644445)QQ咨询惜分飞

标题:触发器引起ORA-04091

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

原因:在行级触发器中,不能查询自身表
场景重现:通过触发器实现test_count表中统计test表中行数

--创建子表
create table TEST
(id NUMBER, name varchar2(100), primary key (id));
--创建统计表
create table test_count (test_count int);
--创建触发器
CREATE OR REPLACE TRIGGER T_TEST
  AFTER INSERT OR DELETE ON TEST
  FOR EACH ROW
DECLARE
  A NUMBER;
BEGIN
  SELECT  COUNT(*) INTO A FROM TEST;
  UPDATE TEST_COUNT SET TEST_COUNT = A;
END T_TEST;

模拟错误

INSERT INTO TEST (ID,NAME)VALUES(2,'abc');
ORA-04091: table CHF.TEST is mutating, trigger/function may not see it
ORA-06512: at "CHF.T_TEST", line 2
ORA-04088: error during execution of trigger 'CHF.T_TEST'

处理方法
通过自治事务实现(修改触发器)

CREATE OR REPLACE TRIGGER T_TEST
  AFTER INSERT OR DELETE ON TEST
  FOR EACH ROW
DECLARE
  A NUMBER;
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  SELECT  COUNT(*) INTO A FROM TEST;
  UPDATE TEST_COUNT SET TEST_COUNT = A;
  COMMIT;
END T_TEST;

PRAGMA AUTONOMOUS_TRANSACTION
当前的触发器作为已有事务的子事务运行,子事务自治管理,子事务的commit、rollback操作不影响父事务的状态

此条目发表在 ORA-xxxxx 分类目录,贴了 标签。将固定链接加入收藏夹。

触发器引起ORA-04091》有 1 条评论

  1. 惜 分飞 说:

    对于oracle行级触发器(for each row),不能对本表做任何操作,包括读取
    原则:
    在before insert触发器中,可以实现对本表的访问;
    在after insert触发器中,不能实现对本表的访问;
    在before/after update/delete触发器中,都不能实现对本表的访问

      [引用]  [回复]

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>