联系:手机/微信(+86 17813235971) QQ(107644445)
作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]
原因:在行级触发器中,不能查询自身表
场景重现:通过触发器实现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操作不影响父事务的状态
对于oracle行级触发器(for each row),不能对本表做任何操作,包括读取
原则:
在before insert触发器中,可以实现对本表的访问;
在after insert触发器中,不能实现对本表的访问;
在before/after update/delete触发器中,都不能实现对本表的访问