8

MySQLを残してPostgreSQLを支持しましたが、トリガーに関して質問があります。このトリガーは、「プロセス」テーブルの行が削除された場合に「ワークフロー」テーブルのフィールドを更新するように設計されています。

CREATE OR REPLACE FUNCTION fn_process_delete() RETURNS TRIGGER AS $$
BEGIN
    UPDATE workflow SET deleted_process_name = OLD.process_name
    WHERE process_id = OLD.process_id;
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS process_delete ON processes;
CREATE TRIGGER process_delete
AFTER DELETE ON processes
FOR EACH ROW 
EXECUTE PROCEDURE fn_process_delete();

私の質問は2つあります。

  1. 上記のようにAFTERDELETEを使用すると、行は削除されますが、updateステートメントは「ワークフロー」テーブルのフィールドを更新しません。

  2. BEFORE DELETEを使用すると、プロセステーブルは削除をまったく実行せず、「この行に一意の識別子がありません」というエラーが表示されます。

誰かアドバイスできますか?

4

1 に答える 1

17

質問2:

トリガー関数は次のように終了します。

RETURN NULL;

これで、トリガーイベントの実行をスキップします。トリガー手順に関するドキュメントごと

起動された行レベルのトリガーBEFOREはnullを返し、トリガーマネージャーにこの行の残りの操作をスキップするように通知できます(つまり、後続のトリガーは起動されず、この行では//はINSERT発生しません)。UPDATEDELETE

これを次のように置き換える必要があります。

RETURN OLD;

システムが行の削除を続行するため。理由は次のとおりです。

のビフォアトリガーの場合DELETE、戻り値は直接的な影響はありませんが、トリガーアクションを続行するにはnull以外である必要があります。NEWトリガーではnullでDELETEあるため、通常はそれを返すことは意味がありません。トリガーの通常のイディオムDELETEは、を返すことOLDです。

大胆な強調鉱山。

質問1

トリガーとトリガー関数がとして機能しない理由はわかりませんAFTER DELETE。言うまでもなく、一致する行がprocess_idテーブルに存在する必要がありますworkflow

于 2012-05-21T15:16:15.197 に答える