0
create or replace 
trigger audit_att_eval
    AFTER INSERT OR UPDATE OF evaluation ON attendance
    FOR EACH ROW
DECLARE
  fname VARCHAR2(22);
  sname VARCHAR2(22);
  ctitle VARCHAR(30);
  ostartdate DATE;
  oinstructor VARCHAR2(12);
BEGIN
  SELECT student.first_name, student.surname, course.title, offering.start_date, offering.instructor
  INTO fname, sname, ctitle, ostartdate, oinstructor
  FROM student, course, offering, attendance
  WHERE student.student_id = attendance.student_id
  AND attendance.offering_id = offering.offering_id
  AND offering.course_id = course.course_id;
IF (:NEW.evaluation = 0)
    THEN
      INSERT INTO eval_audit
      VALUES (fname, sname, ctitle, ostartdate, oinstructor, :NEW.evaluation);   
  END IF;
END;

这可以编译,但是当我通过尝试更新现有的出勤率来测试它时。评估我收到以下错误:

Error report:
SQL Error: ORA-04091: table.ATTENDANCE is mutating, trigger/function may not see it
ORA-04088: error during execution of trigger 'OPS$1022005.AUDIT_ATT_EVAL'
04091. 00000 -  "table %s.%s is mutating, trigger/function may not see it"
*Cause:    A trigger (or a user defined plsql function that is referenced in
           this statement) attempted to look at (or modify) a table that was
           in the middle of being modified by the statement which fired it.
*Action:   Rewrite the trigger (or function) so it does not read that table.

一如既往,我将不胜感激任何帮助引导我走向正确的方向。

4

1 回答 1

1

当我们执行一些 DML 操作(在您的情况下为 INSERT/UPDATE)并且我们试图从同一个触发器中选择受影响的记录(您从考勤表中获取)时,通常会发生变异错误。所以基本上我们试图从拥有触发器的表中选择触发器中的记录。这会造成不一致,并且 Oracle 会引发变异错误

create or replace 
trigger audit_att_eval
   AFTER INSERT OR UPDATE OF evaluation ON attendance
   FOR EACH ROW
DECLARE
  --fname VARCHAR2(22);
  --sname VARCHAR2(22);
  --ctitle VARCHAR(30);
  --ostartdate DATE;
  --oinstructor VARCHAR2(12);

CURSOR fetch_audit_details
   IS 
    SELECT student.first_name, student.surname, course.title, offering.start_date, offering.instructor
  --INTO fname, sname, ctitle, ostartdate, oinstructor
  FROM student
      , course
      , offering
   -- ,attendence   i have removed this because this is not allowed in this trigger
  WHERE student.student_id = :NEW.student_id    --use the new student id
  AND :NEW.offering_id = offering.offering_id   ----use the new offering_id
  AND offering.course_id = course.course_id;     

fetch_audit_row fetch_audit_details%ROWTYPE;

BEGIN

IF (:NEW.evaluation = 0)
  THEN
  --You need details only when evaluation value is 0 ,thats why i put this inside 
  --condition
   OPEN fetch_audit_details;
   FETCH fetch_audit_details INTO fetch_audit_row;
   CLOSE fetch_audit_details;

  --check whether this cursor returns null ,do what you need to do in this situation??

 INSERT INTO eval_audit
     VALUES (fetch_audit_row.first_name, fetch_audit_row.surname, fetch_audit_row.title, fetch_audit_row.start_date, fetch_audit_row.instructor, 0);   
   END IF;
  END;
于 2013-03-28T00:36:31.937 回答