いくつかの問題は順不同です。
まず、行レベルのトリガーの本体で、:new
を使用する必要があります および:old
新旧のレコードを参照します。先頭のコロンが必要です。つまり、WHERE
句は次のようにする必要があります
WHERE PROJECTID = :new.PROJECTID
次に、CREATE TRIGGER
を実行している場合 SQL * Plusでは、SHOW ERRORS
を使用してエラーと警告のリストを取得できます。 コマンド、つまり
SQL> show errors
DBA_ERRORS
をクエリすることもできます テーブル(またはALL_ERRORS
またはUSER_ERRORS
特権レベルによって異なります)が、通常はそれを利用する必要はありません。
第3に、構文エラーが修正されたと仮定すると、変更が発生します。テーブルエラー
このロジックを使用する場合。テーブルAの行レベルのトリガー(TPM_TRAININGPLAN
この場合)テーブルが不整合な状態にある可能性があるため、テーブルAを照会できません。 Timが彼の記事で示しているように、コレクションを含むパッケージを作成し、そのコレクションをbeforeステートメントトリガーで初期化し、コレクション内のデータを行レベルのトリガーに入力してから、で変更された行を処理することで、この問題を回避できます。 afterステートメントトリガー。ただし、複数の異なるオブジェクトを管理する必要があるため、システムに追加するのはかなり複雑です。
一般に、TPM_TRAININGPLAN
を操作するために使用するAPIの一部としてこのロジックを実装することをお勧めします。 テーブル。それがストアドプロシージャである場合は、TPM_PROJECT
を更新するロジックを配置する方がはるかに理にかなっています。 トリガーに入れるのではなく、そのストアドプロシージャで。トリガーに多くのロジックが埋め込まれているアプリケーションをデバッグしようとすると、開発者が実行されている操作を正確に追跡することが非常に困難になるため、非常に苦痛です。または、TRAININGDELIVERYSTART
を削除することもできます。 TPM_PROJECT
の列 テーブルを作成し、実行時の最小開始日を計算するだけです。
第4に、挿入、更新、削除でトリガーが起動した場合、:new
を単純に参照することはできません。 値。 :new
は挿入と更新に有効ですが、削除を行う場合はNULLになります。 :old
は削除と更新に有効ですが、挿入を行う場合はNULLになります。つまり、おそらく(Timのパッケージソリューションを参照して)の方針に沿ったロジックが必要になるでしょう
BEGIN
IF inserting
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'INSERT');
ELSIF updating
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'UPDATE');
ELSIF deleting
THEN
trigger_api.tab1_row_change(p_id => :old.projectid, p_action => 'DELETE');
END IF;
END;