2017-04-22 66 views
0

如何将以下简单触发器变为复合触发器以避免ORA-04091 table is mutating error将触发器变成复合触发器?

CREATE OR REPLACE TRIGGER grades_before_update 
BEFORE UPDATE OF grade_percent 
ON grades 
FOR EACH ROW 
DECLARE 
    grade_percent_var NUMBER; 
BEGIN 
    SELECT grade_percent 
    INTO grade_percent_var 
    FROM grades 
    WHERE student_id = :new.student_id;  

    IF (grade_percent_var > 100 OR grade_percent_var < 0) THEN 
      RAISE_APPLICATION_ERROR(-20001, 'grade percent must be between 0 and 100'); 
    END IF; 
END; 
/

的原因,我问的是,因为我每次使用UPDATE查询像测试该触发器:

UPDATE grades 
SET grade_percent = 90 
WHERE student_id = 1; 

我得到的ORA-04091 table is mutating error。我搜索了起来,这个网站说,我需要一个复合触发器来避免这个错误:

Using Triggers

但我不知道如何下手。

+0

您的目标是在更新之前检查字段“grade_percent”的值吗? –

+0

是的。必须使用触发器。这是要求的一部分。 – 5120bee

回答

2

您不需要复合触发器,因为您只需检查当前值。该错误是因为您正在选择正在更新的表,并且这是无效的操作(对于之前的触发器)。

所以你只需要你用:new.student_id

下一样,这将是访问该字段的值:

IF (:NEW.grade_percent > 100 OR :NEW.grade_percent < 0) THEN 
     RAISE_APPLICATION_ERROR(-20001, 'grade percent must be between 0 and 100'); 
END IF; 

没有必要声明的变量,也不是select语句。 :NEW.grade_percent是在update命令中使用的值。