現在、私はテンプレートのいくつかの関連テーブルにいくつかの行を作成するプロシージャを実装しています。したがって、私のプロシージャはSAVEPOINT
と、異なるテーブルにあるINSERT
ステートメントと、新しく作成された主キーを参照しながら他のテーブルにいくつかの行を挿入するためのCursorで構成されています。ネストされたBEFORE INSERT/UPDATEトリガーでのアトミックトランザクション
これらのテーブルは、それぞれに目的がある定義されたBEFORE INSERT/UPDATEトリガーがあります。
- それがINSERT文で定義されていない場合は、シーケンサからの新しい主キーを取得します(がある場合はどこに彼らはNULL
- 設定監査フィールド(last_change_date、last_change_user、等。)
トランザクションがORA-04091で失敗します。表には、変異され、トリガー/関数はそれを
が表示されないことがあり、私は、各トリガーにPRAGMA自律型トランザクションを宣言することで、この問題を回避できることを、理解していますが、私のトランザクションだろうそれらのデータセット全体を作成/挿入する必要があるという要件であるため、これ以上原子的ではありません。
私は自分のデータベースの設計において何が間違っていますか?
UPDATE:これは、あなたがこのようなことが、よりコンパクト書くことができますトリガ
CREATE TRIGGER TRG_AUFTRAG_B_IU
BEFORE INSERT OR UPDATE
ON AUFTRAG
FOR EACH ROW
BEGIN
IF INSERTING THEN
IF :new.id is NULL or :new.id = 0 THEN
SELECT SEQ_AUFTRAG.nextval into :new.id from dual;
END IF;
IF :new.nummer is NULL or :new.nummer = 0 THEN
SELECT nvl(MAX(NUMMER),0)+1 INTO :new.nummer FROM AUFTRAG WHERE EXTRACT(YEAR from DATUM) = EXTRACT(YEAR from :new.DATUM);
END IF;
--DEFAULT Values
IF :new.BETR_GRENZWERTE_RELEVANT is NULL THEN
SELECT 0 INTO :new.BETR_GRENZWERTE_RELEVANT FROM dual;
END IF;
IF :new.DOKUMENTE_ABGELEGT is NULL THEN
SELECT 0 INTO :new.DOKUMENTE_ABGELEGT FROM dual;
END IF;
IF :new.EXT_ORG is NULL or :new.EXT_ORG < 1 THEN
SELECT 1 INTO :new.EXT_ORG FROM dual;
END IF;
:new.ERSTELLT_VON := nvl(:new.ERSTELLT_VON,user);
:new.ERSTELLT_DATUM := nvl(:new.ERSTELLT_DATUM,sysdate);
END IF;
:new.GEAENDERT_VON := user;
:new.GEAENDERT_DATUM := sysdate;
END;
トリガーのコードを表示してください。実際には、あなたが挙げた行動は非常に典型的でトリガーに役立ちますが、問題なく動作するはずです。 –
トリガー内の同じテーブルから 'select'を実行しているようです。引き金が必要としていることに基づいて、「選択」の必要はありません。そして、あなたは正しいのです。「プラグマ自律型トランザクション」は、この種の問題に対する解決策ではありません。 –
ああ!私はすでに問題が何かを見ていると思う....それは:新しい:NUMMERの部分ではないですか?これは、ビジネス要件である識別番号を作成するためのものです。それは、後にINSERT TRIGGERでこれを行うための解決策でしょうか? –