2011-06-29 15 views
2

Oracle 10g DBで作業していますが、トランザクション内でトリガーに問題があります。 Table Aには、挿入前、更新前、削除前の3つのトリガーがあります。トリガーが発砲されるたびに、ログのようなものがtable Bに書き込まれます。 すべてのトリガーは"before xxx""on each row"に設定されています。単一のクエリを使用して、私は彼らが働いているのを見ることができます。私は1つのトランザクション、(一般的に、私はラインを変更し、その後、私はそれを削除し、そうupdatedelete)中に同じラインを変更する2つのクエリを実行するときOracle:トランザクション内のトリガー(2ステートメント)

しかし、唯一の最初のトリガ(update)が実行されます。トランザクションの最後に、私はtable Aの私の行が削除されているのを見ることができますが、更新アクションを示すtable Bには1行しかありません。

設定ミスの可能性があります。それはトリガー設定から何か来ていますか?

答えて

6

第2のトリガーが発動しない理由はありません。何か他のことが起こっているわけではありません。 @Vincentマルグラットは、他の何かが起こっている、言うように

SQL> CREATE TABLE a (ID NUMBER); 

Table created 

SQL> CREATE TABLE b (action VARCHAR2(3), id_old NUMBER, id_new NUMBER); 

Table created 

SQL> CREATE TRIGGER trg_a_ins BEFORE INSERT ON a FOR EACH ROW 
    2 BEGIN 
    3  INSERT INTO b VALUES ('ins', :old.id, :new.id); 
    4 END; 
    5/

Trigger created 

SQL> CREATE TRIGGER trg_a_upd BEFORE UPDATE ON a FOR EACH ROW 
    2 BEGIN 
    3  INSERT INTO b VALUES ('upd', :old.id, :new.id); 
    4 END; 
    5/

Trigger created 

SQL> CREATE TRIGGER trg_a_del BEFORE DELETE ON a FOR EACH ROW 
    2 BEGIN 
    3  INSERT INTO b VALUES ('del', :old.id, :new.id); 
    4 END; 
    5/

Trigger created 

SQL> INSERT INTO a VALUES (1); 

1 row inserted 

SQL> UPDATE a SET ID = 2 WHERE ID = 1; 

1 row updated 

SQL> DELETE FROM a WHERE ID = 2; 

1 row deleted 

SQL> select * from b; 

ACTION  ID_OLD  ID_NEW 
------ ---------- ---------- 
ins      1 
upd    1   2 
del    2 
+0

お試しいただきありがとうございます。構造の写真は私たちに近いです(もちろんもっと複雑です)。私はそれを試して、それは働いた。だから確かに、他にも何かがあります。 – Ashygan

0

:ここ

は、単一のトランザクションが複数回、単一の行を変更したときに、すべてが正常に火をトリガーすることを示して少しテストケースです。表Bにはユニークなインデックスを持つ日付列がありますか?最初に考えられるのは、2つのレコードが同じ日付(監査)値で最も近い秒に挿入されていることです。インデックスの衝突により、削除から2番目の挿入にエラーが発生します。それは削除トリガーの内部で押しつぶされています。むしろ私が知っている投機的なもので、タイムスタンプの列はあまりありませんし、タイミングが間違っていれば期待どおりに動作することもあります。

+0

表Bには日付の列はありません(ただし、近い将来予定されていますが、索引付けされません)。代わりに、テーブルBのプライマリキーを持っています。その値は、テーブルBのトリガを使用してシーケンスから取得されます(各行の挿入前)。 2番目のトリガーから来るのでしょうか? 別の情報:私はデータベースにアクセスするためにHibernateを使用しています(挿入、更新、削除)。私は、Oracleがトリガから来るエラーを発生させるとき、私はJavaコードで例外があることを知っています。しかし、このケースではOracleから例外が発生することはありませんでした。 – Ashygan

+0

トリガの1つが例外を押しつぶしてHibernateがそれを見る機会を持たないようにすることができますが、それは単なる推測です。質問にテーブル構造とトリガコードを追加すると便利です。 –

0

ORMが複数の変更を1つのレコードに '圧縮'することは可能です(望ましい)。したがって、コードは3つの属性を更新し、ORMはキャッシュ内でレコード/インスタンスを複数回更新した可能性がありますが、トランザクションの最後には1つのUPDATEステートメントのみを送信します。また、レコードが削除された場合は、更新をスキップして元のレコードを削除するだけでもかまいません。

つまり、DELETEトリガーを起動しないとレコードを削除できる理由を説明できません。私はあなたが 'ソフトな'削除ではなく、実際の削除を使用していると仮定します(レコードを削除済みとしてマークし、それを表示から隠すだけです)。

関連する問題