PostgreSQL トリガー
PostgreSQL トリガーはデータベースのコールバック関数であり、指定されたデータベースイベントが発生したときに自動的に実行・呼び出しされます。
以下は PostgreSQL トリガーに関するいくつかの重要なポイントです:
-
PostgreSQL トリガーは次の場合に発動できます:
- 操作を実行する前(制約をチェックし、挿入・更新・削除を試みる前)。
- 操作を実行した後(制約をチェックし、挿入・更新・削除が完了した後)。
- 更新操作(ビューに対して挿入、更新、削除を行う場合)。
-
トリガーの FOR EACH ROW 属性はオプションです。これを選択すると、操作が行を変更するたびに1回呼び出されます。逆に、FOR EACH STATEMENT を選択すると、変更された行数に関係なく、各ステートメントでトリガーが1回実行されます。
-
WHEN 句とトリガー操作は、NEW.column-name および OLD.column-name を参照することで、挿入、削除、更新の際に各行の要素にアクセスできます。ここで column-name は、トリガーが関連付けられているテーブルの列の名前です。
-
WHEN 句が存在する場合、PostgreSQL ステートメントは WHEN 句が成立する行に対してのみ実行されます。WHEN 句がない場合、PostgreSQL ステートメントはすべての行で実行されます。
-
BEFORE または AFTER キーワードは、トリガーアクションをいつ実行するかを決定します。関連する行の挿入、変更、削除の前か後かを決定します。
-
変更対象のテーブルは、トリガーが追加されているテーブルまたはビューと同じデータベース内に存在する必要があり、database.tablename ではなく tablename のみを使用する必要があります。
-
制約トリガーを作成するときは、制約オプションを指定します。これは通常のトリガーと同じですが、この制約を使用してトリガーが発動するタイミングを調整できます。制約トリガーによって実装された制約が違反されると、例外がスローされます。
構文
トリガーを作成するときの基本構文は次のとおりです:
CREATE TRIGGER trigger_name [BEFORE|AFTER|INSTEAD OF] event_name ON table_name [ -- 触发器逻辑.... ];
ここで、event_name は、指定されたテーブル table_name に対する INSERT、DELETE、UPDATE のデータベース操作です。テーブル名の後に FOR EACH ROW をオプションで指定できます。
以下は、UPDATE 操作でテーブルの1つ以上の指定列に対してトリガーを作成する構文です:
CREATE TRIGGER trigger_name [BEFORE|AFTER] UPDATE OF column_name ON table_name [ -- 触发器逻辑.... ];
例
新しく作成した COMPANY テーブル(既に存在する場合は削除して再作成)に挿入される各レコードについて監査証跡を維持したいと仮定しましょう:
サンプルdb=# CREATE TABLE COMPANY( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL );
監査証跡を維持するために、AUDIT という名前の新しいテーブルを作成します。COMPANY テーブルに新しいレコードが追加されるたびに、ログメッセージがそのテーブルに挿入されます。
サンプルdb=# CREATE TABLE AUDIT( EMP_ID INT NOT NULL, ENTRY_DATE TEXT NOT NULL );
ここで、ID は AUDIT レコードの ID、EMP_ID は COMPANY テーブルの ID、DATE は COMPANY でレコードが作成されたときのタイムスタンプを保持します。それでは、COMPANY テーブルにトリガーを作成しましょう:
サンプルdb=# CREATE TRIGGER example_trigger AFTER INSERT ON COMPANY FOR EACH ROW EXECUTE PROCEDURE auditlogfunc();
auditlogfunc() は PostgreSQL のプログラムで、その定義は次のとおりです:
CREATE OR REPLACE FUNCTION auditlogfunc() RETURNS TRIGGER AS $example_table$
BEGIN
INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, current_timestamp);
RETURN NEW;
END;
$example_table$ LANGUAGE plpgsql;
では、COMPANY テーブルにデータを挿入してみましょう:
サンプルdb=# INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (1, 'Paul', 32, 'California', 20000.00 );
このとき、COMPANY テーブルに1つのレコードが挿入されました:
同時に、AUDIT テーブルにもレコードが挿入されました。COMPANY テーブルに挿入するときにトリガーを作成したためです。同様に、必要に応じて更新時や削除時のトリガーも作成できます:
emp_id | entry_date
--------+-------------------------------
1 | 2013-05-05 15:49:59.968+05:30
(1 row)
トリガーの一覧表示
pg_trigger テーブルから現在のデータベースのすべてのトリガーを一覧表示できます:
サンプルdb=# SELECT * FROM pg_trigger;
特定のテーブルのトリガーを一覧表示したい場合は、構文は次のとおりです:
サンプルdb=# SELECT tgname FROM pg_trigger, pg_class WHERE tgrelid=pg_class.oid AND relname='company';
結果は次のとおりです:
tgname ----------------- example_trigger (1 row)
トリガーの削除
トリガーを削除する基本構文は次のとおりです:
drop trigger ${trigger_name} on ${table_of_trigger_dependent};
この記事の上記の company テーブル上のトリガー example_trigger を削除するコマンドは次のとおりです:
drop trigger example_trigger on company;その他の拡張