PostgreSQL Programmer's Guide
PrevChapter 12. TriggersNext

Trigger Creation

もし、トリガー・イベントが起きると トリガー管理(エグゼキュータ: Executor と呼ばれる)が大域構造体 TriggerData *CurrentTriggerData (以下 に述べる)を初期化し、イベントを処理するためのトリガー関数を呼び出しま す。

トリガー関数は、引数無しでトリガーがつくられて不明瞭なものを返さな いように、前もってつくられなければなりません。

トリガーをつくる構文は以下の通りです:

   CREATE TRIGGER <trigger name> <BEFORE|AFTER> <INSERT|DELETE|UPDATE>
       ON <relation name> FOR EACH <ROW|STATEMENT>
       EXECUTE PROCEDURE <procedure name> (<function args>);

トリガー名(trigger name)はもしトリガーを削除しなければならなくなっ たときに使われます。それは、DROP TRIGGER コマンドの引数として使われま す。

その次の単語は関数が呼び出されるのがイベントの前(BEFORE)か後(AFTER) かを決定します。

その次の要素は、どのコマンドのイベント(複数可) で関数をトリガーする を決定します。複数イベントを OR で区切って指定できます。

関係名(relation name)はどのテーブルにイベントを適用するかを決定しま す。

FOR EACH 文はトリガーがかかるのが、各行(row)毎か、あるいは、すべて の文が終了する前か(または後か)を定義します。

手続き名(procedure name)は呼び出される C の関数です。

その関数の引数(function args)は CurrentTriggerData 構造体の中に入れ られて関数に渡されます。引数を関数に渡す目的は、同じ関数を呼ぶのに似た ようなものを要求する異なるトリガーを許すためです。

また、関数は異なる関係のトリガー(これらの関数は "汎用トリガー関数" と名付けられます) として使われるかもしれません。

上記の両方の機能を使う例題として、引数として一方に現在のユーザと他 方に現在の時刻とを二つのフィールド名としてとり汎用関数となるようなもの があります。これは例として、トリガーに INSERT イベントでトランザクショ ン・テーブル内のレコードの作成を検知して自動的に書き込まれます。それは、 UPDATE イベントの中で使われれば、"最終更新" ファンクションとして使うこ ともできるでしょう。

トリガー関数は HeapTuple を、呼び出したエグゼキュータへ返します。こ れは、挿入(INSERT), 削除(DELETE) または、更新(UPDATE) 操作の後(AFTER) で実行されるトリガーでは無視されますが、前(BEFORE)トリガーでは以下を許 します: - NULL を返し、現在のタップルに操作をスキップさせます。(そのためタッ プルの 挿入/更新/削除は行なわれないでしょう。) - もとのタップルのかわりに挿入される他のタップルの(UPDATE の場合は アップデートされたタップルの新しいバージョンとして)ポインタを返し ます(INSERT と UPDATE のみ)。

注意、CREATE TRIGGER ハンドラによっては初期化はなされません。これは、 将来変更となるでしょう。また、同じイベント対し二つ以上のトリガーが定義 されると、トリガーの起動のかかる順番は予期できません。これも将来変更と なるでしょう。

もし、トリガー関数が(SPI を使って) SQL-問い合わせを実行するとしたら、 これらの問い合わせは、トリガーをもう一度起動するでしょう。このことは、 カスケーディング・トリガーとして知られています。カスケードのレベルに明 確な制限はありません。

もし、トリガーが挿入(INSERT)により起動されて新しいタップルを同じ関係 に挿入すると、このトリガーがもう一度起動されます。現状では、このような 場合に同期を取ったり(その他)することは何も用意されていませんが、これは 変更されるでしょう。それまでの間は、あるテクニックを使って自分自身への 再帰(カスケーディング)を止める関数 funny_dup17() が regress テストの中 にあります。


PrevHomeNext
TriggersUpInteraction with the Trigger Manager