关于错误:"table is mutating, trigger/function may not see it
来源:互联网 发布:java 循环替换字符串 编辑:程序博客网 时间:2024/06/06 20:41
转载于:http://www.itpub.net/thread-1032067-1-1.html#
关于错误:"table is mutating, trigger/function may not see it"
关于错误:"ORA-04091: table is mutating, trigger/function may not see it"的分析
在写trigger的时候,经常会遇到这种情况
当在程序块中需要对trigger本表进行修改或查询的时候,系统会提示错误: ORA-04091: table is mutating, trigger/function may not see it
关于这个错误,其实是由于对本表的操作造成的.ORACLE DB里默认在写TRIGGER的时候把本表锁死,不允许对其进行操作,也就是说这个错误是不能通过系统的手段解决的,只能改用一些其它的SQL来绕开它.
刚接触TRIGGER的时候会经常犯这样的错误,其中有大部分是可以通过:new和ld来解决的,这是新手在写trigger时最需要注意的问题之一.
但是还会有一定要对本表进行修改或查询操作的情况,不能避免.
在网上搜索过一些关于这个问题的解决方法,至今也没有从根本上找到解决方法.
有人曾提议说,可以写一个PROCEDURE对本表进行操作,在TRIGGER里直接调用.此方法我也试过,还是不能避免这个问题,也有其他人作了和我一样的测试,结果是一样的.
目前找到的最好的解决这个问题的方法还是通过改写SQL,把一个TRIGGER要完成的功能分解,通过增加一步或几步操作把这个问题绕过去.
可是这种方法一来浪费时间精力,二来,并不是所有问题都可以找到绕过去的方法.
所以一直为此而头疼.
前几天又看到有人发布这个问题的求助,看到之后也只摇头,表示无能为力.
所以在这里提出来,不知道在座的各位高手有没有哪位有这方面的经验心得,有好的解决办法共享一下,在下不胜感激!!
在写trigger的时候,经常会遇到这种情况
当在程序块中需要对trigger本表进行修改或查询的时候,系统会提示错误: ORA-04091: table is mutating, trigger/function may not see it
关于这个错误,其实是由于对本表的操作造成的.ORACLE DB里默认在写TRIGGER的时候把本表锁死,不允许对其进行操作,也就是说这个错误是不能通过系统的手段解决的,只能改用一些其它的SQL来绕开它.
刚接触TRIGGER的时候会经常犯这样的错误,其中有大部分是可以通过:new和ld来解决的,这是新手在写trigger时最需要注意的问题之一.
但是还会有一定要对本表进行修改或查询操作的情况,不能避免.
在网上搜索过一些关于这个问题的解决方法,至今也没有从根本上找到解决方法.
有人曾提议说,可以写一个PROCEDURE对本表进行操作,在TRIGGER里直接调用.此方法我也试过,还是不能避免这个问题,也有其他人作了和我一样的测试,结果是一样的.
目前找到的最好的解决这个问题的方法还是通过改写SQL,把一个TRIGGER要完成的功能分解,通过增加一步或几步操作把这个问题绕过去.
可是这种方法一来浪费时间精力,二来,并不是所有问题都可以找到绕过去的方法.
所以一直为此而头疼.
前几天又看到有人发布这个问题的求助,看到之后也只摇头,表示无能为力.
所以在这里提出来,不知道在座的各位高手有没有哪位有这方面的经验心得,有好的解决办法共享一下,在下不胜感激!!
============
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
表已创建。
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
__________________
==============
注意慎用AUTONOMOUS_TRANSACTION。一个DML可能触发很多次触发器,因此产生了大量独立的事务,很容易产生死锁。
ASKTOM上对AUTONOMOUS_TRANSACTION的看法是:唯一的用途就是作审计日志,其他一概不该使用。
还有我在这里不止一次呼吁过的:取消触发器,把你的业务逻辑写到存储过程去。
- 关于错误:"table is mutating, trigger/function may not see it
- 错误"ORA-04091: table is mutating, trigger/function may not see it"的原因以及解决办法
- 关于错误:"ORA-04091: table is mutating, trigger/function may not see it"的分析(触发器操作自身表)
- 关于错误:"ORA-04091: table is mutating, trigger/function may not see it"的分析(触发器操作自身表)
- trigger抛出异常ORA-04091:table ...... is mutating, trigger/function may not see it
- ORA-04091: table XXXX is mutating, trigger/function may not see it
- ORA-04091: table name is mutating, trigger/function may not see it.
- ORA-04091: table is mutating, trigger/function may not see it
- Oracle触发器报错table xxxx is mutating,trigger/function may not see it
- 關於觸發器(Trigger)對於變異表(Mutating table)的操作
- mysql 触发器的问题 Can't update table 'tbl' in stored function/trigger because it is already used by state
- Can't update table 'psxt_user' in stored function/trigger because it is already used by statement wh
- Can't update table 'tbl' in stored function/trigger because it is already used by statement which invoked this stored function/t
- MySQL触发器更新本表数据异常:Can't update table 'tbl' in stored function/trigger because it is already used by statement which invoked this
- Solution for Can’t update table ‘t1′ in stored function/trigger because it is already used by statement which invoked this store
- mysql -- error code [1442]; Can't update table 'table_name' in stored function/trigger because it is already used by statement w
- ERROR 1442 (HY000): Can\'t update table \'sign\' in stored function/trigger because it is already used by statement which invoke
- MySQL触发器更新本表数据异常:Can’t update table ‘tbl’ in stored function/trigger because it is already used by s
- 如何创建一个 Windows 服务应用程序的安装项目在 Visual C# 中
- 浅析Oracle存储过程触发器在数据同步中的应用
- Assignment 1: PL/SQL stored procedure P9
- SQL FOREIGN KEY 约束的建立与删除(转)
- GAIA page
- 关于错误:"table is mutating, trigger/function may not see it
- 关于UUID,GUID,OCMB
- 正则表达式
- 规划分析输出表格设计思路(2010_09)
- 计算机常用英文单词
- Boot time kernel options
- P2P直播、点播技术学习经验
- linux 增加交换空间
- windows核心编程笔记[7]