关于错误:"ORA-04091: table is mutating, trigger/function may not see it"的分析(触发器操作自身表)

简介: 在写trigger的时候,经常会遇到这种情况当在程序块中需要对trigger本表进行修改或查询的时候,系统会提示错误:  ORA-04091: table is mutating, tr...

在写trigger的时候,经常会遇到这种情况
当在程序块中需要对trigger本表进行修改或查询的时候,系统会提示错误:  ORA-04091: table is mutating, trigger/function may not see it

关于这个错误,其实是由于对本表的操作造成的.ORACLE DB里默认在写TRIGGER的时候把本表锁死,不允许对其进行操作,也就是说这个错误是不能通过系统的手段解决的,只能改用一些其它的SQL来绕开它.

对此可通过自治事物解决:

SQL> CREATE TABLE T(ID NUMBER(18),MC VARCHAR2(20),DT DATE);

表已创建。

SQL> CREATE OR REPLACE TRIGGER TR_T
  2  AFTER DELETE ON T
  3  FOR EACH ROW
  4  DECLARE V_COUNT NUMBER;
  5   --PRAGMA AUTONOMOUS_TRANSACTION;
  6  BEGIN
  7     INSERT INTO T VALUES(:OLD.ID,:OLD.MC,SYSDATE);
  8     COMMIT;
  9  END TR_DEL_CABLE;
10  /

触发器已创建

SQL> INSERT INTO T VALUES(1,'111111',SYSDATE);

已创建 1 行。

SQL> INSERT INTO T VALUES(2,'222222',SYSDATE);

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> SELECT ID,MC,TO_CHAR(DT,'YYYYMMDD HH24:MI:SS') FROM T;

        ID MC                   TO_CHAR(DT,'YYYYM
---------- -------------------- -----------------
         1 111111               20080802 11:07:36
         2 222222               20080802 11:07:43

SQL> DELETE FROM T WHERE ID=1;
DELETE FROM T WHERE ID=1
            *
第 1 行出现错误:
ORA-04091: 表 TEST.T 发生了变化, 触发器/函数不能读它
ORA-06512: 在 "TEST.TR_T", line 4
ORA-04088: 触发器 'TEST.TR_T' 执行过程中出错


SQL> SELECT ID,MC,TO_CHAR(DT,'YYYYMMDD HH24:MI:SS') FROM T;

        ID MC                   TO_CHAR(DT,'YYYYM
---------- -------------------- -----------------
         1 111111               20080802 11:07:36
         2 222222               20080802 11:07:43

SQL> CREATE OR REPLACE TRIGGER TR_T
  2  AFTER DELETE ON T
  3  FOR EACH ROW
  4  DECLARE V_COUNT NUMBER;
  5   PRAGMA AUTONOMOUS_TRANSACTION;--开启自治事物
  6  BEGIN
  7     INSERT INTO T VALUES(:OLD.ID,:OLD.MC,SYSDATE);
  8     COMMIT ;--提交自治事物
  9  END TR_DEL_CABLE;
10  /

触发器已创建

SQL> DELETE FROM T WHERE ID=1;

已删除 1 行。

SQL> COMMIT;

提交完成。

SQL> SELECT ID,MC,TO_CHAR(DT,'YYYYMMDD HH24:MI:SS') FROM T;

        ID MC                   TO_CHAR(DT,'YYYYM
---------- -------------------- -----------------
         2 222222               20080802 11:07:43
         1 111111               20080802 11:08:32
目录
相关文章
|
4月前
|
SQL 关系型数据库 MySQL
⑩⑥ 【MySQL】详解 触发器TRIGGER,协助 确保数据的完整性,日志记录,数据校验等操作。
⑩⑥ 【MySQL】详解 触发器TRIGGER,协助 确保数据的完整性,日志记录,数据校验等操作。
39 0
|
5月前
|
关系型数据库 MySQL
Mysql Trigger触发器学习总结
Mysql Trigger触发器学习总结
25 0
|
7月前
|
关系型数据库 MySQL
使用mysql触发器实现保存用户操作历史记录
使用mysql触发器实现保存用户操作历史记录
65 0
|
9月前
|
SQL 存储 监控
sqlserver触发器详解:sqlserver触发器after/for和instead of的区别详解(实例讲解),触发器定义创建操作打通,触发器的优缺点,触发器使用建议
sqlserver触发器详解:sqlserver触发器after/for和instead of的区别详解(实例讲解),触发器定义创建操作打通,触发器的优缺点,触发器使用建议
1240 1
|
存储 SQL 机器学习/深度学习
MySQL高级篇——索引、视图、存储过程和函数、触发器的相关概念及操作(上)
MySQL高级篇——索引、视图、存储过程和函数、触发器的相关概念及操作(上)
MySQL高级篇——索引、视图、存储过程和函数、触发器的相关概念及操作(上)
|
SQL 物联网 Shell
SQLite 虚拟表和触发器操作联结表 | 学习笔记
快速学习 SQLite 虚拟表和触发器操作联结表
312 0
|
存储 SQL 关系型数据库
MySQL高级篇——索引、视图、存储过程和函数、触发器的相关概念及操作(下)
MySQL高级篇——索引、视图、存储过程和函数、触发器的相关概念及操作 (下)
MySQL高级篇——索引、视图、存储过程和函数、触发器的相关概念及操作(下)
|
Java 调度 Spring
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(下)
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(下)
|
Java 调度 Spring
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(上)
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(上)
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(上)