トリガプロシージャをPL/Tclで作成することができます。
PostgreSQLでは、トリガとして呼び出されるプロシージャは、trigger型の戻り値を返す引数のない関数として宣言する必要があります。
トリガマネージャからの情報は、以下の変数内に格納されてプロシージャ本体に渡されます。
$TG_nameCREATE TRIGGER文によるトリガ名。
$TG_relidそのトリガプロシージャ呼び出しが発生したテーブルのオブジェクトID。
$TG_table_nameそのトリガプロシージャ呼び出しが発生したテーブルの名前。
$TG_table_schemaそのトリガプロシージャ呼び出しが発生したテーブルのスキーマ。
$TG_relatts先頭に空のリスト要素を持つ、テーブルの列名のTclリスト。
Tclのlsearchコマンドを使用して、そのリストから列名を検索することで、最初の列を1とした要素番号が返されます。
これは、PostgreSQLでの通常の列の番号付けと同じです。
(また空のリスト要素は、右側の列の属性番号を正しくするために、削除された列の位置に現れます。)
$TG_whenトリガイベントの種類に応じた、BEFORE、AFTERまたはINSTEAD OFという文字列。
$TG_levelトリガイベントの種類に応じた、ROWまたはSTATEMENTという文字列。
$TG_opトリガイベントの種類に応じた、INSERT、UPDATE、DELETE、またはTRUNCATEの文字列。
$NEWINSERT/UPDATE動作の場合は新しいテーブル行の値を、DELETE動作の場合は空を持つ連想配列。
配列のインデックスは列名です。
NULLの列はこの配列内には現れません。
文レベルのトリガに対しては設定されません。
$OLDUPDATE/DELETE動作の場合は古いテーブル行の値を、INSERT動作の場合は空を持つ連想配列。
配列のインデックスは列名です。
NULLの列はこの配列内には現れません。
文レベルのトリガに対しては設定されません。
$argsCREATE TRIGGER文で指定された、プロシージャへの引数のTclリスト。
この引数は、プロシージャ本体から$1 ... $としてもアクセスすることができます。
n
トリガプロシージャからの戻り値は、OKという文字列、SKIPという文字列、列名/値の組のリスト、の内の1つを取ることができます。
戻り値がOKの場合、トリガを発行した操作(INSERT/UPDATE/DELETE)は正常に処理されます。
SKIPはトリガマネージャにこの行に対する操作を何も出力せずに中止するように通知します。
リストが返された場合は、PL/Tclに対し、変更した行をトリガマネージャに返すことを通知します。変更行の内容はリスト内の列名と値により指定されます。
リストで言及されなかった列は全てNULLが置かれます。
変更された行を返すことは、$NEW内で与えられる行ではなく変更された行が挿入される、行レベルのBEFORE INSERTまたはUPDATEトリガ、または、返される行がINSERT RETURNINGおよびUPDATE RETURNING句の元データとして使われる、行レベルのINSTEAD OF INSERTまたはUPDATEトリガでのみ有意です。
行レベルのBEFORE DELETEまたはINSTEAD OF DELETEトリガでは、変更された行が返されることがOKが返されるのと同じ効果を持ち、その操作は処理されます。
この他の種類のトリガでは戻り値は無視されます。
結果リストはarray get Tclコマンドによる変更されたタプルの配列表現から作ることができます。
ここで、テーブル内の整数値としてその行に対する更新数を記録させる、小さめのトリガプロシージャの例を示します。 新規の行が挿入された場合は、その値はゼロに初期化され、その後の各更新操作時に1が加算されます。
CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS $$
switch $TG_op {
INSERT {
set NEW($1) 0
}
UPDATE {
set NEW($1) $OLD($1)
incr NEW($1)
}
default {
return OK
}
}
return [array get NEW]
$$ LANGUAGE pltcl;
CREATE TABLE mytab (num integer, description text, modcnt integer);
CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
FOR EACH ROW EXECUTE PROCEDURE trigfunc_modcount('modcnt');トリガプロシージャ自身は列名を認識していない点に注目してください。 これはトリガの引数として与えられます。 これにより、このトリガプロシージャを別のテーブルで再利用することができます。