Postgresql-triggers
PostgreSQL-トリガー
PostgreSQL *トリガー*はデータベースコールバック関数で、指定されたデータベースイベントが発生すると自動的に実行/呼び出されます。
以下は、PostgreSQLのトリガーに関する重要なポイントです-
- PostgreSQLトリガーを起動するように指定できます
- 行に対して操作が試行される前(制約がチェックされ、INSERT、UPDATE、またはDELETEが試行される前)
- 操作が完了した後(制約がチェックされ、INSERT、UPDATE、またはDELETEが完了した後)
- 操作の代わりに(ビューでの挿入、更新、または削除の場合)
- FOR EACH ROWとマークされたトリガーは、操作が変更するすべての行に対して1回呼び出されます。 対照的に、FOR EACH STATEMENTとマークされたトリガーは、変更する行数に関係なく、特定の操作に対して1回だけ実行されます。
- WHEN句とトリガーアクションの両方は、 NEW.column-name および OLD.column-name という形式の参照を使用して、挿入、削除、または更新される行の要素にアクセスできます。column-nameは名前ですトリガーが関連付けられているテーブルの列の
- WHEN句が指定されている場合、指定されたPostgreSQLステートメントは、WHEN句がtrueである行に対してのみ実行されます。 WHEN句が指定されていない場合、PostgreSQLステートメントはすべての行に対して実行されます。
- 同じイベントに対して同じ種類のトリガーが複数定義されている場合、それらは名前のアルファベット順に起動されます。
- BEFORE、AFTER、またはINSTEAD OFキーワードは、関連する行の挿入、変更、または削除に関連してトリガーアクションがいつ実行されるかを決定します。
- トリガーは、関連付けられているテーブルが削除されると自動的に削除されます。
- 変更するテーブルは、トリガーがアタッチされるテーブルまたはビューと同じデータベースに存在する必要があり、 database.tablename ではなく tablename のみを使用する必要があります。
- CONSTRAINTオプションを指定すると、_constraint trigger_が作成されます。 これは、SET CONSTRAINTSを使用してトリガーを起動するタイミングを調整できることを除いて、通常のトリガーと同じです。 制約トリガーは、実装する制約に違反した場合に例外を発生させることが期待されています。
構文
- トリガー*を作成する基本的な構文は次のとおりです-
CREATE TRIGGER trigger_name [BEFORE|AFTER|INSTEAD OF] event_name
ON table_name
[
-- Trigger logic goes here....
];
ここで、 event_name は、前述の表 table_name に対する_INSERT、DELETE、_ UPDATE、、および_TRUNCATE_データベース操作です。 オプションで、テーブル名の後にFOR EACH ROWを指定できます。
以下は、次のようにテーブルの1つ以上の指定された列のUPDATE操作でトリガーを作成する構文です-
CREATE TRIGGER trigger_name [BEFORE|AFTER] UPDATE OF column_name
ON table_name
[
-- Trigger logic goes here....
];
例
COMPANYテーブルに挿入されているすべてのレコードの監査トライアルを保持したい場合を考えてみましょう。次のように新しく作成します(既にある場合はCOMPANYテーブルを削除します)。
testdb=# CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
監査トライアルを維持するために、新しいレコードのCOMPANYテーブルにエントリがあるたびにログメッセージが挿入されるAUDITという新しいテーブルを作成します-
testdb=# CREATE TABLE AUDIT(
EMP_ID INT NOT NULL,
ENTRY_DATE TEXT NOT NULL
);
ここで、IDはAUDITレコードID、EMP_IDはCOMPANYテーブルから取得されるIDです。DATEは、レコードがCOMPANYテーブルに作成されるときにタイムスタンプを保持します。 それでは、次のようにCOMPANYテーブルにトリガーを作成しましょう-
testdb=# CREATE TRIGGER example_trigger AFTER INSERT ON COMPANY
FOR EACH ROW EXECUTE PROCEDURE auditlogfunc();
auditlogfunc()はPostgreSQLの procedure であり、次の定義があります-
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テーブルにレコードを挿入してみましょう。これにより、AUDITテーブルに監査ログレコードが作成されます。 それでは、次のようにCOMPANYテーブルに1つのレコードを作成しましょう-
testdb=# INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Paul', 32, 'California', 20000.00 );
これにより、次のようなCOMPANYテーブルに1つのレコードが作成されます-
id | name | age | address | salary
----+------+-----+--------------+--------
1 | Paul | 32 | California | 20000
同時に、AUDITテーブルに1つのレコードが作成されます。 このレコードは、COMPANYテーブルのINSERT操作で作成したトリガーの結果です。 同様に、要件に基づいてUPDATEおよびDELETE操作でトリガーを作成できます。
emp_id | entry_date
--------+-------------------------------
1 | 2013-05-05 15:49:59.968+05:30
(1 row)
トリガーのリスト
次のように pg_trigger テーブルから現在のデータベースのすべてのトリガーをリストできます-
testdb=# SELECT * FROM pg_trigger;
上記のPostgreSQLステートメントは、すべてのトリガーをリストします。
特定のテーブルのトリガーを一覧表示する場合は、次のようにテーブル名でAND句を使用します-
testdb=# SELECT tgname FROM pg_trigger, pg_class WHERE tgrelid=pg_class.oid AND relname='company';
上記のPostgreSQLステートメントは、次のように1つのエントリのみをリストします-
tgname
-----------------
example_trigger
(1 row)
トリガーのドロップ
以下は、既存のトリガーを削除するために使用できるDROPコマンドです-
testdb=# DROP TRIGGER trigger_name;