SQL错误:ORA-04091:表正在变异,触发器/函数可能看不到它
我得到了“SQL错误:ORA-04091:表正在变化,当我更新表中的数据时,触发器/函数可能看不到它” DDL: 触发:SQL错误:ORA-04091:表正在变异,触发器/函数可能看不到它,sql,oracle,plsql,database-trigger,Sql,Oracle,Plsql,Database Trigger,我得到了“SQL错误:ORA-04091:表正在变化,当我更新表中的数据时,触发器/函数可能看不到它” DDL: 触发: CREATE OR REPLACE TRIGGER STUDENT_DIM_HIST BEFORE UPDATE ON STUDENT_DIM FOR EACH ROW BEGIN CASE WHEN UPDATING('CURR_STUD_NAME') THEN UPDATE STUDENT_DIM SET PREV_STUD_NAME = :OLD.CURR_STUD_N
CREATE OR REPLACE TRIGGER STUDENT_DIM_HIST BEFORE UPDATE ON STUDENT_DIM FOR EACH ROW
BEGIN
CASE WHEN UPDATING('CURR_STUD_NAME') THEN UPDATE STUDENT_DIM SET PREV_STUD_NAME = :OLD.CURR_STUD_NAME WHERE STUD_ID = :OLD.STUD_ID;
WHEN UPDATING('CURR_DOJ') THEN UPDATE STUDENT_DIM SET PREV_DOJ = :OLD.CURR_DOJ WHERE STUD_ID = :OLD.STUD_ID;
WHEN UPDATING('CURRR_DEPT_NAME') THEN UPDATE STUDENT_DIM SET PREV_DEPT_NAME = :OLD.CURRR_DEPT_NAME WHERE STUD_ID = :OLD.STUD_ID;
END CASE;
END;
更新:
UPDATE STUDENT_DIM SET CURR_STUD_NAME = 'RAM KUMAR' WHERE STUD_ID = 3;
Oracle mutating trigger错误发生在触发器引用拥有该触发器的表时,导致ORA-04091:表名正在发生变化,触发器/函数可能看不到它。信息 不要使用触发器-避免变异表错误的最好方法是不要使用触发器。虽然面向对象的Oracle提供了与表关联的方法,但大多数精明的PL/SQL开发人员都避免使用触发器,除非绝对必要 使用after或instead触发器-如果必须使用触发器,最好使用after触发器来避免突变表错误,以避免与突变表相关的货币问题。例如,使用触发器:在xxx上更新之后,原始更新已经完成,表将不会发生变化 重新使用触发器语法-避免使用行级和语句级触发器组合来改变表 使用自治事务-通过将触发器标记为自治事务,使其独立于调用过程的表,可以避免突变表错误
在同一个表的操作更新期间,触发器尝试引用拥有该触发器的表,因此会出现问题 改为使用一些指定,如下所示:
CREATE OR REPLACE TRIGGER STUDENT_DIM_HIST BEFORE UPDATE ON STUDENT_DIM FOR EACH ROW
BEGIN
CASE WHEN UPDATING('CURR_STUD_NAME') THEN :NEW.PREV_STUD_NAME := :OLD.CURR_STUD_NAME;
WHEN UPDATING('CURR_DOJ') THEN :NEW.PREV_DOJ := :OLD.CURR_DOJ;
WHEN UPDATING('CURRR_DEPT_NAME') THEN :NEW.PREV_DEPT_NAME := :OLD.CURRR_DEPT_NAME;
END CASE;
END;
CREATE OR REPLACE TRIGGER STUDENT_DIM_HIST BEFORE UPDATE ON STUDENT_DIM FOR EACH ROW
BEGIN
CASE WHEN UPDATING('CURR_STUD_NAME') THEN :NEW.PREV_STUD_NAME := :OLD.CURR_STUD_NAME;
WHEN UPDATING('CURR_DOJ') THEN :NEW.PREV_DOJ := :OLD.CURR_DOJ;
WHEN UPDATING('CURRR_DEPT_NAME') THEN :NEW.PREV_DEPT_NAME := :OLD.CURRR_DEPT_NAME;
END CASE;
END;