14

問題は次のとおりです。

特定のクラスの全体的な平均成績を 2.5 未満に下げる変更を受講関係に加えないようにするトリガーを作成します。注: このトリガーは、特定の学生の平均 GPA に対処することを意図したものではなく、特定のクラスに割り当てられたすべての成績の平均成績に対処する必要があります。

スキーマは次のとおりです。

Student-schema =(studentnum, name, standing, gpa, major)
Class-schema = (schedulenum, semester, department, classnum, days, time, place, enrollment)
Instructor-schema = (name, department, office)
Teaches-schema = (name, schedulenum, semester)
Taking-schema = (studentnum, schedulenum, semester, grade)

私はこれらのトリガーでひどい時間を過ごしていますが、これを機能させるための私の試みは次のとおりです。

CREATE OR REPLACE TRIGGER stopChange
    AFTER UPDATE OR INSERT OR DELETE ON taking
    REFERENCING OLD AS old
    NEW AS new
    FOR EACH ROW
DECLARE

grd_avg taking.grade%TYPE;

BEGIN
    SELECT AVG(grade)
    INTO grd_avg
    FROM taking
    WHERE studentnum = :new.studentnum
    AND schedulenum = :new.schedulenum
    AND semester = :new.semester;

    IF grd_avg < 2.5 THEN
        UPDATE taking
        SET grade = :old.grade
        WHERE studentnum = :old.studentnum
        AND schedulenum = :old.schedulenum
        AND semester = :old.semester;
    END IF;

END;   
/

タプルを更新または削除しようとすると、エラーが発生するため、明らかに何か間違っています。

ERROR at line 1:
ORA-04091: table TAKING is mutating, trigger/function may not see it
ORA-06512: at "STOPCHANGE", line 6
ORA-04088: error during execution of trigger 'STOPCHANGE'

何かアドバイス?オラクルを使用しています。

4

6 に答える 6

15

このステートメントを内部DECLAREで使用すると、機能します。

pragma autonomous_transaction;
于 2016-07-12T11:16:10.190 に答える
6

これは、 afterトリガーではなくbeforeトリガーとして書き直すことで解決できると思います。ただし、これは挿入と削除の場合は少し複雑になる可能性があります。アイデアは次のとおりです。

CREATE OR REPLACE TRIGGER stopChange
    BEFORE UPDATE OR INSERT OR DELETE ON taking
    REFERENCING OLD AS old
    NEW AS new
    FOR EACH ROW
DECLARE

grd_avg taking.grade%TYPE;

BEGIN
    SELECT (SUM(grade) - oldgrade + new.grade) / count(*)
    INTO grd_avg
    FROM taking
    WHERE studentnum = :new.studentnum
    AND schedulenum = :new.schedulenum
    AND semester = :new.semester;

    IF grd_avg < 2.5 THEN
        new.grade = old.grade
    END IF;
END;  
于 2013-04-24T02:27:18.757 に答える
0

私たちのプロジェクトでも同じ問題が発生しました。しかし、いくつかのオラクル フォーラムを検索した結果、以下の解決策が見つかりました。

1)古い/新しい列データを行レベル トリガーの pat として一時テーブルに保存します。2) ステートメント レベルのトリガーを記述し、手順 1 で保存したデータを使用します。

これは私が考える問題を解決するでしょう。

于 2016-07-04T09:36:52.283 に答える