メモです。
(使用している PostgreSQL は PostgreSQL 9.3.12 です)
PostgreSQL で できるだけ他に影響を与えないように 一時的に全てのトリガーを無効にしたいと思っていたら 次のような方法がありました。
[参考]
PostgreSQLで一時的にtriggerを全て無効する方法 - Qiita
SET session_replication_role = replica;
クライアント接続の変数「session_replication_role」を変更する方法で この変数は、トリガおよびルールの発行を制御するそうです。
[参考]
18.11. クライアント接続デフォルト - PostgreSQL 9.3.2文書
実際に試してみます。
まず、table1 と table2 を作成。
CREATE TABLE table1 ( field1 INTEGER , field2 INTEGER ); CREATE TABLE table2 ( field1 INTEGER );
table1 の INSERT 時に field1 の値を field2 にセットする BEFORE トリガーを作成。
CREATE FUNCTION before_func1()
RETURNS TRIGGER AS $$
BEGIN
NEW.field2 := NEW.field1;
RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';
CREATE TRIGGER before_trigger1
BEFORE INSERT ON table1
FOR EACH ROW EXECUTE PROCEDURE before_func1();
table1 の INSERT 時に table2 にレコードを INSERT する AFTER トリガーを作成。
CREATE FUNCTION after_function1()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO table2 (field1) VALUES (NEW.field1);
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
CREATE TRIGGER after_trigger1
AFTER INSERT ON table1
FOR EACH ROW EXECUTE PROCEDURE after_function1();
テーブルとトリガーを作成したら、次の SQL を実行します。
INSERT INTO table1 (field1) VALUES (1);
table1 に INSERT 。
db=# INSERT INTO table1 (field1) VALUES (1);
INSERT 0 1
table1 を確認。
db=# SELECT * FROM table1;
field1 | field2
--------+--------
1 | 1
(1 row)
BEFORE トリガーで field2 に値がセットされています。
table2 を確認。
db=# SELECT * FROM table2;
field1
--------
1
(1 row)
AFTER トリガーで レコードが INSERT されています。
次にクライアント接続の変数「session_replication_role」を試しますが まず初期値を確認。
db=# SHOW session_replication_role;
session_replication_role
--------------------------
origin
(1 row)
初期値は「origin」でした。
クライアント接続の変数「session_replication_role」に 「replica」を設定します。
db=# SET session_replication_role = replica;
SET
db=# SHOW session_replication_role;
session_replication_role
--------------------------
replica
(1 row)
ちゃんと変更されてます。
さっきと同じ INSERT 文を実行。
(テーブルのレコードはクリア済です)
db=# INSERT INTO table1 (field1) VALUES (1);
INSERT 0 1
table1 を確認。
db=# SELECT * FROM table1;
field1 | field2
--------+--------
1 |
(1 row)
BEFORE トリガーが実行されなかったため field2 に値がセットされていません。
table2 を確認。
db=# SELECT * FROM table2;
field1
--------
(0 rows)
AFTER トリガーが実行されなかったため レコードが INSERT されていません。
トリガーは実行されませんでした。
これは便利ですね。
もちろん他のセッションでは通常通りの動作をします。
ただし、整合性が保たれなくなる可能性があるので 当然ながら慎重に実行する必要があります。