Chapter 16. トリガ

Table of Contents
16.1. トリガ定義
16.2. トリガマネージャとの関係
16.3. データ変更時の可視性
16.4.

PostgreSQLはさまざまなサーバーサイド関数のインターフェイスを持っています。 サーバサイド関数は、SQL、C、または任意の定義された手続き言語で記述することができます。 トリガ関数は、C や多くの手続き言語で記述することできますが、SQL では記述できません。 現バージョンでは、STATEMENT レベルのトリガイベントはサポートされていませんので注意してください。現在はタプルのINSERT、DELETE、UPDATEの前(BEFORE)または後(AFTER)をトリガイベントとして指定できます。

16.1. トリガ定義

トリガイベントが発生すると、(エクゼキュータによって呼び出される) トリガマネージャは、TriggerData 情報構造体 (後述) を設定し、そのイベントを扱うトリガ関数を呼び出します。

トリガ関数は、トリガ自体が作成されるまでに定義しておく必要があります。 また、トリガ関数は、引数をとらない、trigger 型を返す関数として宣言される必要があります。 (トリガ関数は、通常の関数で使用される引数の形ではなく、TriggerData 構造で入力を受け取ります。)もし関数がCで書かれている場合、"version 1" 関数マネージャインターフェイスを使わなくてはいけません。

トリガを生成するための構文は、次のとおりです。

CREATE TRIGGER trigger [ BEFORE | AFTER ] [ INSERT | DELETE | UPDATE [ OR ... ] ] ] ]
    ON relation FOR EACH [ ROW | STATEMENT ]
    EXECUTE PROCEDURE procedure
     (args);

引数は以下のとおりです。

trigger

トリガは、同じテーブルにある他のすべてのトリガと異なる名前を持つ必要があります。 その名前は、トリガを削除する際に必要です。

BEFORE
AFTER

関数がイベントが発生する前に呼ばれるのか後に呼ばれるのかを決定します。

INSERT
DELETE
UPDATE

コマンドの次の要素が、どのイベント (複数可) で関数を呼び出すかを決定します。複数のイベントをORで区切って指定できます。

relation

リレーション名は、どのテーブルにイベントを適用するかを示します。

ROW
STATEMENT

FOR EACH文はトリガを行が影響を受けるたびに発行するか、文全体が終了する前(または後)に発行するかを決定します。 現在は、行の場合のみサポートされています。

procedure

プロシージャ名は、呼び出される関数を示します。

args

TriggerData 構造体の中の関数に渡される引数です。 これは、空か、もしくは 1 つ以上のシンプルなリテラル定数 (文字列として関数へ渡される) のリストのいずれかです。

引数をトリガ定義に含める目的は、要求仕様が似ている異なるトリガで同一の関数を呼び出せるようにすることです。 たとえば、片方に現在のユーザを格納し、もう片方に現時刻を格納する 2 つのフィールド名を引数としてとる汎用トリガ関数を設定することが可能です。 正しく記述されていれば、このトリガ関数は、トリガ対象である特定のテーブルから独立したものとなります。 したがって、たとえば、適したフィールドを含む任意のテーブルに対する INSERT イベントに同じ関数を使用し、トランザクションテーブル内のレコード作成を自動的に記録することができます。 また、UPDATE トリガとして定義された場合、最後に更新されたイベントを記録することもできます。

トリガ関数は、呼び出したエクゼキュータに HeapTuple を返します。 この返り値は、操作の後で発行される AFTER トリガでは無視されますが、操作の前に発行される BEFORE トリガでは以下を行なうことができます。

これらの動作を行いたくない BEFORE トリガについては、渡されたタプルと同じ NEW タプルを返すように気をつける必要があります。

CREATE TRIGGERハンドラによって初期化は行われないことに注意してください。これも今後変更されるかもしれません。

同じリレーションの同じイベントに複数のトリガが定義された場合、トリガは名前のアルファベット順で発行されます。 BEFORE トリガの場合、各トリガによって返された変更可能なタプルが、次のトリガへの入力になります。 BEFORE トリガが NULL を返した場合、操作は中断され、後続のトリガは発行されません。

トリガ関数が(SPIを使用して)SQL問い合わせを処理する場合、これらの問い合わせがトリガを再度発行することがあります。これはカスケードされたトリガと呼ばれます。 カスケードの段数に直接的な制限はありません。 カスケードの場合、同じトリガを再帰的に呼び出すことが可能です。たとえば、INSERT トリガで同じテーブルに追加のタプルを挿入する問い合わせが実行された場合、その結果として INSERT トリガが再度発行されます。 このような場合、トリガを作成するプログラマは、無期限再帰にならないように気を付ける必要があります。