無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

CREATE TRIGGER

名前

CREATE TRIGGER -- 新しいトリガを定義する

概要

CREATE [ CONSTRAINT ] TRIGGER 

name

 { BEFORE | AFTER | INSTEAD OF } { 

event

 [ OR ... ] }
    ON 

table_name


    [ FROM 

referenced_table_name

 ]
    { NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } }
    [ FOR [ EACH ] { ROW | STATEMENT } ]
    [ WHEN ( 

condition

 ) ]
    EXECUTE PROCEDURE 

function_name

 ( 

arguments

 )



ここで

event

は以下のいずれかを取ることができます。


    INSERT
    UPDATE [ OF 

column_name

 [, ... ] ]
    DELETE
    TRUNCATE

説明

CREATE TRIGGER は新しいトリガを作成します。 作成したトリガは指定したテーブルまたはビューと関連付けられ、特定のイベントが発生した時に指定した関数 function_name を実行します。

トリガでは、起動のタイミングとして、行への操作が開始される前(制約条件のチェックと INSERT UPDATE または DELETE が行われる前)、操作が完了した後(制約条件がチェックされ、 INSERT UPDATE または DELETE が完了した後)、操作の代わり(ビューにおける挿入、更新、削除の場合)のいずれかを指定することができます。 イベントの前または代わりにトリガが起動する場合、そのトリガは対象行に対する操作を省略したり、( INSERT UPDATE の操作時のみ)挿入する行を変更したりすることができます。 イベントの後にトリガが起動する場合、他のトリガの影響を含む全ての変更が、トリガに対して "可視" 状態となります。

FOR EACH ROW 付きのトリガは、その操作によって変更される行ごとに1回ずつ呼び出されます。 例えば、10行に影響を与える DELETE 操作は、対象リレーション上の ON DELETE トリガを、行が削除される度に1回ずつ、個別に10回呼び出すことになります。 反対に、 FOR EACH STATEMENT 付きのトリガは、その操作によって何行変更されたかにかかわらず、任意の操作ごとに1回のみ実行されます (変更対象が0行となる操作でも、適用できる FOR EACH STATEMENT トリガがあれば実行されます)。

トリガイベントの INSTEAD OF として発行されるように指定されたトリガは FOR EACH ROW 印を付けなければなりません。 このためビュー上にのみ定義することができます。 ビューに対する BEFORE および AFTER トリガは FOR EACH STATEMENT 印を付けなければなりません。

さらに、 FOR EACH STATEMENT のみですが、トリガを TRUNCATE で発行するように定義することができます。

以下の表にどの種類のトリガがテーブルとビューに対して使用できるかをまとめます。

いつ イベント 行レベル 文レベル
BEFORE INSERT / UPDATE / DELETE テーブル テーブルおよびビュー
TRUNCATE テーブル
AFTER INSERT / UPDATE / DELETE テーブル テーブルおよびビュー
TRUNCATE テーブル
INSTEAD OF INSERT / UPDATE / DELETE ビュー
TRUNCATE

またトリガ定義では、トリガを発行すべきかどうかを判定する、論理値の WHEN 条件を指定することができます。 行レベルのトリガでは、 WHEN 条件は行の列の古い値、新しい値、またはその両方で検証することができます。 文レベルのトリガでも WHEN 条件を持たせることができますが、条件としてテーブル内の何らかの値を参照することができませんので、この機能はあまり有用ではありません

同一イベントに同じ種類の複数のトリガが定義された場合、名前のアルファベット順で実行されます。

CONSTRAINT オプションが指定された場合、このコマンドは 制約トリガ を作成します。 これは、 SET CONSTRAINTS を使用してトリガを発行するタイミングを調整することができるという点を除き、通常のトリガと同じです。 制約トリガは AFTER ROW トリガでなければなりません。 トリガイベントを引き起こした文の最後、またはそれを含むトランザクションの最後のいずれかで発行することができます。 後者の場合、 遅延 と呼ばれます。 SET CONSTRAINTS を使用することで、強制的に待機中の遅延トリガの発行を即座に行わせることができます。 制約トリガは、実装する制約に違反した時に例外を発生するものと想定しています。

SELECT はまったく行を変更しないため、 SELECT トリガを作成することはできません。 この場合は、ルールやビューの方が適しています。

トリガに関するより詳細については、 第36章 を参照してください。

パラメータ

name

新しいトリガに付与する名前です。 同じテーブルの他のトリガと異なる名前にする必要があります。 名前をスキーマ修飾することはできません。 トリガはそのテーブルのスキーマを引き継ぎます。 制約トリガの場合、この名前が SET CONSTRAINTS を使用してトリガの動作を変更する時に使用されます。

BEFORE
AFTER
INSTEAD OF

関数の呼び出しをイベントの前に行うか後に行うか、それとも代替として行うかを決定します。 制約トリガでは AFTER としてしか指定することができません。

event

INSERT UPDATE DELETE TRUNCATE のいずれかが入ります。 このパラメータは、トリガを起動するイベントを指定します。 OR を使用して、複数のイベントを指定することができます。

UPDATE イベントでは、以下の構文を使用して列リストを指定することができます。

UPDATE OF 

column_name1

 [, 

column_name2

 ... ]

このトリガは UPDATE コマンドの対象として列挙された列のいずれか少なくとも1つの列が指定された場合に発行されます。

INSTEAD OF UPDATE イベントは列リストをサポートしません。

table_name

トリガを作成するテーブルまたはビューの名前です(スキーマ修飾名も可)。

referenced_table_name

制約で参照される(おそらくスキーマ修飾された)他のテーブルの名前です。 このオプションは外部キー制約で使用されるものであり、一般利用を推奨しません。 これは制約トリガでのみ指定することができます。

DEFERRABLE
NOT DEFERRABLE
INITIALLY IMMEDIATE
INITIALLY DEFERRED

トリガのデフォルトのタイミングです。 これらの制約オプションについては CREATE TABLE 文書を参照してください。 これは制約トリガでのみ指定することができます。

FOR EACH ROW
FOR EACH STATEMENT

このパラメータは、トリガプロシージャを、トリガイベントによって影響を受ける行ごとに1回起動するか、SQL文ごとに1回のみ起動するかを指定します。 どちらも指定されない場合は、 FOR EACH STATEMENT がデフォルトです。 制約トリガでは FOR EACH ROW のみ指定することができます。

condition

トリガ関数を実際に実行するか否かを決定する論理式です。 WHEN が指定された場合、 condition true を返す場合のみ関数が呼び出されます。 FOR EACH ROW トリガでは、 WHEN 条件で、それぞれ OLD. column_name NEW. column_name と記述することで、古い行値、新しい行値、またはその両方の列を参照することができます。 当然ながら INSERT トリガでは OLD を参照することはできませんし、 DELETE トリガでは NEW を参照することはできません。

INSTEAD OF トリガは WHEN 条件をサポートしません。

現時点では WHEN 条件に副問い合わせを含めることはできません。

制約トリガでは、 WHEN 条件の評価は遅延されず、行の更新操作が行われた直後に発生することに注意してください。 この条件が真と評価されなかった場合、トリガは遅延実行ようのキューに入りません。

function_name

ユーザが提供する関数です。この関数は、引数を取らず trigger 型を返すよう定義します。トリガが起動した時に実行されます。

arguments

トリガ実行時に関数に渡される引数をカンマで区切ったリストです。このパラメータは省略可能です。 引数として指定するのは、リテラル文字列定数です。 単純な名前および数値定数を記述できますが、全て文字列に変換されます。 関数内でこれらの引数にアクセスする方法について調べるためには、トリガ関数を実装した言語の説明を参照してください。 通常の関数引数とは異なる場合があります。

注釈

テーブルにトリガを作成するには、ユーザがそのテーブルに対し TRIGGER 権限を持っている必要があります。 またユーザはトリガ関数に対し EXECUTE 権限を持たなければなりません。

トリガを削除するためには DROP TRIGGER を使用してください。

列指定のトリガ( UPDATE OF column_name 構文で定義されたトリガ)は、列挙された列のいずれかかが UPDATE コマンドの SET リスト内に対象として指定された場合に発行されます。 BEFORE UPDATE トリガにより行の内容になされた変更が考慮されないため、トリガが発行されない場合であっても、列の値を変更することができます。 反対に、 UPDATE ... SET x = x ... のようなコマンドは、列の値が変更されていない場合であっても、 x 列に対するトリガは発行されます。

BEFORE トリガにおいて WHEN 条件は関数が実行される、またはされそうな場合のみ評価されます。 このため WHEN の使用はトリガ関数の先頭で同一の条件を試験することと実質違いはありません。 この条件で確認できる NEW 行が現在の値であり、それまでのトリガで変更されている可能性があることに、特に注意して下さい。 また BEFORE トリガの WHEN 条件では、まだ設定されていませんので、 NEW 行のシステム列( oid など)を検査することができません。

AFTER トリガにおいて、 WHEN 条件は行の更新を行った直後に評価され、文の最後でトリガを発行するためにイベントを保持すべきかどうかを決定します。 このため AFTER トリガの WHEN 条件は真を返さない場合、イベントを保持する必要もありませんし、文の最後の行を再度取り出す必要もありません。 これにより、トリガをわずかな行のみに対して発行する必要がある場合、多くの行を変更する文を非常に高速にすることができます。

PostgreSQL 7.3より前のバージョンでは、トリガ関数の戻り値の型を、 trigger 型ではなくプレースホルダである opaque 型として宣言する必要がありました。 古いダンプファイルのロードをサポートするため、 CREATE TRIGGER では opaque 型を返すよう宣言された関数を受け入れます。 しかし、注意を促すメッセージを表示し、宣言された関数の戻り値型を trigger に変換します。

accounts テーブルの行が更新される直前に check_account_update 関数を実行します。

CREATE TRIGGER check_update
    BEFORE UPDATE ON accounts
    FOR EACH ROW
    EXECUTE PROCEDURE check_account_update();

上と同じです。 しかし、 balance 列が UPDATE コマンドの対象として使用された場合のみ実行されます。

CREATE TRIGGER check_update
    BEFORE UPDATE OF balance ON accounts
    FOR EACH ROW
    EXECUTE PROCEDURE check_account_update();

以下の構文では、 balance 列が実際に変更された場合のみ関数が実行されます。

CREATE TRIGGER check_update
    BEFORE UPDATE ON accounts
    FOR EACH ROW
    WHEN (OLD.balance IS DISTINCT FROM NEW.balance)
    EXECUTE PROCEDURE check_account_update();

何か変更された場合のみに accounts の更新のログを取る関数を呼び出します。

CREATE TRIGGER log_update
    AFTER UPDATE ON accounts
    FOR EACH ROW
    WHEN (OLD.* IS DISTINCT FROM NEW.*)
    EXECUTE PROCEDURE log_account_update();

ビューの背後にあるテーブルに行を挿入するために、各行に対して view_insert_row 関数を実行します。

CREATE TRIGGER view_insert
    INSTEAD OF INSERT ON my_view
    FOR EACH ROW
    EXECUTE PROCEDURE view_insert_row();

項36.4 には、C言語で作成されたトリガ関数の完全な例があります。

互換性

PostgreSQL における CREATE TRIGGER 文は標準 SQL のサブセットを実装したものです ただし、 PostgreSQL には、次の機能がありません。

SQLでは、複数のトリガは、作成時刻順に起動すべきであると規定しています。 PostgreSQL では名前順であり、より簡単に判断することができます。

SQLでは、数珠繋ぎの削除に対する BEFORE DELETE は、数珠繋ぎの DELETE が完了した 後に 発行するものと規定しています。 PostgreSQL では、 BEFORE DELETE は常に削除操作よりも後に行われます。 この方がより一貫性があると考えています。 また、参照整合性に関する動作により引き起こる更新を実行している間に、 BEFORE トリガが行を更新し、更新を妨げるような場合の動作は非標準的です。 これは、制約違反となるかもしれませんし、参照整合性制約に合わないデータを格納してしまうかもしれません。

OR を使用して単一トリガに複数の動作を指定する機能は、標準SQLに対する PostgreSQL の拡張です。

TRUNCATE でのトリガ発行機能、および、ビューに対する文レベルトリガの定義機能は標準SQLに対する PostgreSQL の拡張です。

CREATE CONSTRAINT TRIGGER は標準 SQL に対する PostgreSQL の拡張です。

関連項目

ALTER TRIGGER , DROP TRIGGER , CREATE FUNCTION , SET CONSTRAINTS

powered by SEO.CUG.NET