2

同じテーブルに新しいレコードを挿入したいという点で、テーブルに新しいレコードを挿入するときに発生するトリガーがあります。
私のトリガーは:

create or replace trigger inst_table
after insert on test_table referencing new as new old as old  
for each row
declare 
      df_name varchar2(500);
      df_desc varchar2(2000);

begin
      df_name := :new.name;
      df_desc := :new.description;

     if inserting then
          FOR item IN (SELECT pid FROM tbl2 where pid not in(1))
             LOOP
                 insert into test_table (name,description,pid) values(df_name,df_desc,item.pid); 
             END LOOP;    
     end if; 
end;

そのようなエラーが発生します

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

同じテーブルに挿入するのを妨げていると思います。
この新しいレコードを同じテーブルに挿入するにはどうすればよいですか。

注:-データベースとしてOracle を使用しています

4

3 に答える 3

10

ミューテーションは、トリガーしているテーブルを変更する行レベルのトリガーがある場合に発生します。問題は、オラクルがどのように振る舞うかを知ることができないということです。行を挿入すると、トリガー自体が同じテーブルに行を挿入し、Oracle が混乱します。原因は、トリガーによるテーブルへの挿入です。それらもトリガー アクションの対象になりますか?

解決策は 3 段階のプロセスです。

1.) 挿入される行を追跡するパッケージをインスタンス化するトリガーの前のステートメント レベル。

2.) 前のステップでインスタンス化されたパッケージ変数にその行情報を保存する前または後の行レベルのトリガー。

3.) テーブルに挿入するトリガーの後のステートメント レベル、パッケージ変数に保存されるすべての行。

この例は、次の場所にあります。

http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936

それが役立つことを願っています。

于 2011-11-17T13:00:41.130 に答える
1

トリガーがいかに悪いかについて不平を言った後ですが、ここに別の解決策があります.

たぶん、2 つのテーブルを持つことを検討する必要があります。test_table現在行っているように、データをテーブルに挿入します。ただし、トリガーで追加の行をテーブルに挿入する代わりにtest_table、データを含む詳細テーブルを作成します。その後、トリガーは必要なすべての行をディテール表に挿入できます。

2 つのテーブル間にカスケード削除の外部キー関係がある場合、変更トリガー エラーが再度発生する可能性があるため、これを回避することをお勧めします。

于 2011-11-17T13:43:12.077 に答える
1

これを達成するには、トリガー以外の方法を検討する必要があると思います。Mark Bobak からの回答で述べたように、トリガーは行を挿入し、トリガーによって挿入された行ごとに、トリガーを呼び出してさらに行を挿入する必要があります。

ストアド プロシージャを記述して挿入を作成するか、値ではなくサブクエリを介して挿入するかを検討します。

トリガーは単純な問題を解決するために使用できますが、より複雑な問題を解決する場合は頭痛の種になります。

APC が投稿したこの重複した質問への回答と、Tom Kyteのこの記事を読む価値があります。ところで、記事は重複した質問でも参照されていますが、リンクは古くなっています。

于 2011-11-17T13:32:07.767 に答える