sql >> データベース >  >> RDS >> Oracle

Oracle-別のテーブルを更新するトリガーの作成に問題があります

    いくつかの問題は順不同です。

    まず、行レベルのトリガーの本体で、: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;
    


    1. Microsoft SQL Serverへのログインエラー:18456

    2. 巨大なMySQLテーブルをリモートデータベースからローカルデータベースにコピーします

    3. 不明なエラー:MySQLTransactionRollbackException 1213

    4. 一意でない場合のMySQLUUID()?