Postgres 9.0以降では、トリガー定義(ステートメント)にWHEN句を追加します。CREATE TRIGGER
CREATE TRIGGER foo
BEFORE UPDATE
FOR EACH ROW
WHEN (OLD IS DISTINCT FROM NEW) -- parentheses required!
EXECUTE PROCEDURE ...;
とが両方とも定義されているトリガーBEFORE/でのみ可能です。またはトリガーでこの句を使用しようとすると、例外が発生します。AFTER UPDATEOLDNEWWHENINSERTDELETE
そしてそれに応じてトリガー関数を根本的に単純化します:
...
IF OLD.locked > 0 THEN
RAISE EXCEPTION 'Message';
END IF;
...
IF TG_OP='UPDATE' ...このトリガーはとにかくのみ機能するため、テストする必要はありませんUPDATE。
または、その条件をWHEN句でも移動します。
CREATE TRIGGER foo
BEFORE UPDATE
FOR EACH ROW
WHEN (OLD.locked > 0
AND OLD IS DISTINCT FROM NEW)
EXECUTE PROCEDURE ...;
RAISE EXCEPTIONトリガー関数に無条件のみを残します。これは、最初に必要な場合にのみ呼び出されます。
詳細の閲覧:
BEFOREトリガーでは、WHEN関数が実行される直前または実行される直前に条件が評価されるため、を使用することWHENは、トリガー関数の開始時に同じ条件をテストすることと実質的に違いはありません。NEW特に、条件によって表示される行は現在の値であり、以前のトリガーによって変更された可能性があることに注意してください。また、BEFOREトリガーの条件では、行のシステム列(など)WHENを調べることはできません。これは、それらがまだ設定されていないためです。NEWoid
AFTERトリガーでは、WHEN行の更新が発生した直後に条件が評価され、ステートメントの最後にトリガーを起動するためにイベントがキューに入れられているかどうかが判別されます。したがって、AFTERトリガーの
WHEN条件がtrueを返さない場合、イベントをキューに入れたり、ステートメントの最後で行を再フェッチしたりする必要はありません。これにより、トリガーをいくつかの行に対してのみ起動する必要がある場合、多くの行を変更するステートメントの速度が大幅に向上する可能性があります。
関連している:
質問のタイトルにも対処する
テーブルの列を動的にループすることは可能ですか?
はい。例: