0

BEFORE INSERT TRIGGERで不思議なエラーが発生しましたが、理解できません。同様の問題でここに投稿された複数の質問を読んだ後でも。

「メソッド」の処理に失敗しました:category_id='foo'およびrequest_id='99'エラー:java.sql.BatchUpdateException:ORA-04091:テーブルSCHEMA.ANIMAL_TABLEが変化しています、トリガー/関数はそれを認識しない可能性がありますORA-06512:at " SCHEMA.TRIGGER_NAME "、7行目ORA-04088:トリガー'SCHEMA.TRIGGER_NAME'の実行中にエラーが発生しました

トリガーは次のとおりです。

CREATE OR REPLACE TRIGGER TRIGGER_NAME 
BEFORE INSERT ON animal_table FOR EACH ROW WHEN (NEW.animal_type = 'cats')

DECLARE    base_animal_id NUMBER(19,0);   base_amount NUMBER(19,0);

BEGIN

SELECT animal_nbr INTO base_animal_id 
FROM animal_table 
WHERE category_id = :NEW.category_id AND summary_id = :NEW.summary_id 
AND animal_type = 'special'; 

SELECT animal_amount INTO base_amount 
FROM animal_table 
WHERE category_id = :NEW.category_id AND summary_id = :NEW.summary_id 
AND animal_type = 'special';


IF :NEW.category_id = 'foo' THEN

  :NEW.animal_info1 := base_animal_id;   
  :NEW.animal_info2 := base_amount;   
  :NEW.animal_info3 := '00';

END IF;

END;

トリガーが保持されているのと同じテーブルでの変更に関するルールを知っていますが、新しい列を変更するときに、:NEWフィールドに対してのみ機能する必要があるものも赤くしています。また、トリガーイベントとしてUPDATEが欠落している可能性があると思いましたが、そうではありませんでした。誰か助けてくれませんか?トリガーとPL/SQLは初めてです。

4

1 に答える 1

0

エラーメッセージは、テーブルの更新とは関係ありません。ROWレベルのトリガーSELECTで現在変更されているテーブルからはできません。

これに対する唯一の回避策は、新しい行を行レベルのトリガーの中間テーブルに書き込むことです。次に、中間テーブルに書き込まれたすべての行を処理するステートメントレベルのトリガーを作成します(ほとんどの場合、副選択を含む単一のUPDATEステートメントのみ)。

たとえば、animal_type ='cats'およびcategory_id='foo'をチェックすることにより、ステートメントレベルのトリガー内で後処理される行を識別できる場合は、行レベルのトリガーと中間テーブルがなくても問題が解決する可能性があります。

その場合、次のトリガー(テストされていない!!!)が(あなたが持っているものの代わりに)あなたが望むことをするかもしれません

CREATE OR REPLACE TRIGGER TRIGGER_NAME 
AFTER INSERT ON animal_table 
BEGIN

  UPDATE animal_table
     SET (animal_info1, 
          animal_info2, 
          animal_info3) = (SELECT animal_nbr, animal_amount, '00'
                           FROM animal_table t2
                           WHERE t2.category_id = animal_table.category_id
                             AND t2.sumary_id = animal_table.summary_id
                             AND t2.animal_type = 'special'
                          )
  WHERE animal_type = 'cats'
    AND category_id = 'foo'

END;

もう1つのより一般的なPL/SQLのこと:取得する列ごとに1つのSELECTを実行する必要はありません。条件が同じであれば、単一のselect文で実行できます。

SELECT animal_nbr, animal_amount
    INTO base_animal_id, base_amount 
FROM animal_table 
WHERE category_id = :NEW.category_id 
  AND summary_id = :NEW.summary_id 
  AND animal_type = 'special';

(selectとintoリストの2つの列に注意してください)

于 2011-09-16T16:56:16.120 に答える