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
UPDATE
OLD
NEW
WHEN
INSERT
DELETE
そしてそれに応じてトリガー関数を根本的に単純化します:
...
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
を調べることはできません。これは、それらがまだ設定されていないためです。NEW
oid
AFTER
トリガーでは、WHEN
行の更新が発生した直後に条件が評価され、ステートメントの最後にトリガーを起動するためにイベントがキューに入れられているかどうかが判別されます。したがって、AFTER
トリガーの
WHEN
条件がtrueを返さない場合、イベントをキューに入れたり、ステートメントの最後で行を再フェッチしたりする必要はありません。これにより、トリガーをいくつかの行に対してのみ起動する必要がある場合、多くの行を変更するステートメントの速度が大幅に向上する可能性があります。
関連している:
質問のタイトルにも対処する
テーブルの列を動的にループすることは可能ですか?
はい。例: