Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL错误:ORA-04091:表正在变异,触发器/函数可能看不到它_Sql_Oracle_Plsql_Database Trigger - Fatal编程技术网

SQL错误:ORA-04091:表正在变异,触发器/函数可能看不到它

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

我得到了“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_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;