2012-03-20 13 views
2

ステートメントレベルのトリガーを作成する際にSQL/Oracle 10gに問題があります。私は、このトリガーを達成しようとしていることは、学生の入学は、以下< 5のときの実用的なクラスを削除することです、私が書いたものです:私はしかし、取得していますエラーがあるSQL/Oracle 10g - トリガーに関する問題

CREATE OR REPLACE TRIGGER delete_prac 
AFTER UPDATE ON studEnrol 
BEGIN 
    DELETE FROM pracList 
    WHERE Practical IN (
    SELECT Practical 
    FROM studEnrol 
    GROUP BY Practical 
    HAVING COUNT(Practical) < 5); 
END delete_prac; 

ORA-04091: pracList table is mutating, trigger/function may not see it 

私はこのエラーを調べました。新しいキーワードと古いキーワードを含めることを提案しましたが、どうすればよいのかわかりません。

ご協力いただきましてありがとうございます。

ありがとうございました。

EDIT:そのpracListテーブル、変異されたテーブルに追加する EDIT2を忘れ:文レベルのトリガにそれを変更し、変更表はまだpracList

+2

pracListに別のトリガーがありますか? –

+1

表のddlを表示します。pracList、studEnrol – turbanoff

答えて

2

これはおそらくFlorin Ghitaが示唆しているように、あなたはpraclistにトリガーを持っていると考えられます。 studenrolを更新すると、praclistから削除しようとします。この行為はあなたの問題の原因となる別のトリガーを発生させます。このエラーは、データの読み込み一貫性のあるビューを提供するために発生します。 Tom Kyte saysこのエラーは、スキーマまたはロジックの欠陥を示す可能性があり、その一方または両方を再考する必要があります。また

、およびトリガーで何をやっている、一般的に言って、全表スキャンは、悪いアイデアTMです。テーブルのサイズによっては、studlistの各アップデートで1秒または2時間を費やすことになります。これは最適ではありません。

praclistのスキーマやトリガーがわからない場合は、あなたのケースではが「」と思われます。このトリガーを完全にドロップします。それは必要ありません。

materialized viewを作成して、必要なデータを提供してください。いつもここで情報を常に最新の状態に保つためのビューを持つことができる場合は、常に値を削除して、praclistに挿入することは意味がありません。次のクエリは、それを行う必要があります。

select p.* 
    from praclist p 
    join (select practical 
      from studenrol 
      group by practical 
     having count(*) >= 5) s 
    on p.practical = s.practical 

ところで、あなたの現在のトリガがpraclistへの挿入を許可しない生徒の数は実用的には場所を取るために十分になっ突然在籍している場合。マテリアライズド・ビューは、この問題と変換表エラーを処理します。

1

で発生した後、あなたのトリガーをFOR EACH ROW

を削除します行を更新した後に1回だけ実行すると、テーブルは変更されません。

+0

動作しません。私はstudEnrolテーブルの学生の登録を別のものに変更しようとしましたが、エラーはまだ発生します。例えば、5人の学生が物理学に登録された後、物理学をやっている1人の学生が数学を編集し、トリガーはプラクラストから実践を削除する必要があります。 – user1280446