★PostgreSQLカンファレンス2024 12月6日開催/チケット販売中★
他のバージョンの文書 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

41.6. PL/Tclのトリガプロシージャ

トリガプロシージャをPL/Tclで作成することができます。 PostgreSQLでは、トリガとして呼び出されるプロシージャは、trigger型の戻り値を返す引数のない関数として宣言する必要があります。

トリガマネージャからの情報は、以下の変数内に格納されてプロシージャ本体に渡されます。

$TG_name

CREATE TRIGGER文によるトリガ名。

$TG_relid

そのトリガプロシージャ呼び出しが発生したテーブルのオブジェクトID。

$TG_table_name

そのトリガプロシージャ呼び出しが発生したテーブルの名前。

$TG_table_schema

そのトリガプロシージャ呼び出しが発生したテーブルのスキーマ。

$TG_relatts

先頭に空のリスト要素を持つ、テーブルの列名のTclリスト。 Tcllsearchコマンドを使用して、そのリストから列名を検索することで、最初の列を1とした要素番号が返されます。 これは、PostgreSQLでの通常の列の番号付けと同じです。 (また空のリスト要素は、右側の列の属性番号を正しくするために、削除された列の位置に現れます。)

$TG_when

トリガイベントの種類に応じた、BEFOREAFTERまたはINSTEAD OFという文字列。

$TG_level

トリガイベントの種類に応じた、ROWまたはSTATEMENTという文字列。

$TG_op

トリガイベントの種類に応じた、INSERTUPDATEDELETE、またはTRUNCATEの文字列。

$NEW

INSERT/UPDATE動作の場合は新しいテーブル行の値を、DELETE動作の場合は空を持つ連想配列。 配列のインデックスは列名です。 NULLの列はこの配列内には現れません。 文レベルのトリガに対しては設定されません。

$OLD

UPDATE/DELETE動作の場合は古いテーブル行の値を、INSERT動作の場合は空を持つ連想配列。 配列のインデックスは列名です。 NULLの列はこの配列内には現れません。 文レベルのトリガに対しては設定されません。

$args

CREATE TRIGGER文で指定された、プロシージャへの引数のTclリスト。 この引数は、プロシージャ本体から$1 ... $nとしてもアクセスすることができます。

トリガプロシージャからの戻り値は、OKという文字列、SKIPという文字列、array get Tclコマンドによって返されるリストの内の1つを取ることができます。 戻り値がOKの場合、トリガを発行した操作(INSERT/UPDATE/DELETE)は正常に処理されます。 SKIPはトリガマネージャにこの行に対する操作を何も出力せずに中止するように通知します。 リストが返された場合は、PL/Tclに対し、変更した行を挿入するようにトリガマネージャに返すことを通知します。 これは、$NEW内で与えられる行ではなく変更された行が挿入される、行レベルのBEFORE INSERTまたはUPDATEトリガ、または、返される行がINSERT RETURNINGおよびUPDATE RETURNINGコマンドをサポートするために使用される、行レベルのINSTEAD OF INSERTまたはUPDATEトリガでのみ有意です。 この他の種類のトリガでは戻り値は無視されます。

ここで、テーブル内の整数値としてその行に対する更新数を記録させる、小さめのトリガプロシージャの例を示します。 新規の行が挿入された場合は、その値はゼロに初期化され、その後の各更新操作時に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');

トリガプロシージャ自身は列名を認識していない点に注目してください。 これはトリガの引数として与えられます。 これにより、このトリガプロシージャを別のテーブルで再利用することができます。