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

PostgreSQL 8.4.1文書
前のページ | 巻戻し | 第 39章PL/Tcl - Tcl手続き型言語 | 早送り | 次のページ

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

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

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

`$TG_name`

  `CREATE TRIGGER`文によるトリガ名。

`$TG_relid`

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

`$TG_table_name`

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

`$TG_table_schema`

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

`$TG_relatts`

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

`$TG_when`

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

`$TG_level`

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

`$TG_op`

  トリガイベントの種類に応じた、`INSERT`、`UPDATE`、`DELETE`、または`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`ではなく、変更した行を挿入するようにトリガマネージャに返すことを通知します （これは`INSERT`/`UPDATE`の場合のみ動作します）。 言うまでもありませんが、これらは全て、トリガが`BEFORE`かつ`FOR EACH ROW`の時にのみ意味があります。 さもなければ、戻り値は無視されます。

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

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

前のページ | ホーム | 次のページ
PL/Tclからのデータベースアクセス | 上に戻る | モジュールと`unknown`コマンド