PostgreSQLでトリガーを一時的に無効にするにはどうすればよいですか?


131

私はデータを一括でロードしており、すべてのトリガーの変更を、行ごとに比べて、事後的にはるかに安価に再計算できます。

PostgreSQLのすべてのトリガーを一時的に無効にするにはどうすればよいですか?

回答:


162

または、USERテーブルのトリガーだけでなく、すべてのトリガーを無効にしたい場合は、以下を使用できます。

SET session_replication_role = replica;

これにより、現在のセッションのトリガーが無効になります。

同じセッションで再度有効にするには:

SET session_replication_role = DEFAULT;

ソース:http : //koo.fi/blog/2013/01/08/disable-postgresql-triggers-temporarily/


2
驚くばかり。大量削除を30分から1秒未満に変更しました:)
Dan Lenski 2014

7
このコマンドが制約トリガーを無効にしないことも便利です
bartolo-otrit

2
私のテスト環境で「外部キー制約違反」エラーを回避する方法を探すのに無駄な時間を費やして、この30分を費やしました。
アマルゴビナス2015年

1つの注意点:ランタイム構成ドキュメントALTER TABLEドキュメントによると、これは通常のトリガーでは機能しますが、ENABLE REPLICAまたはで設定されたトリガーでは機能しませんENABLE ALWAYS
beldaz 2018

私はオン10.4になっており、上記のステートメントを無視しているようです。
ステファン

129

PostgreSQLはALTER TABLE tblname DISABLE TRIGGER USERコマンドを知っています。このコマンドは、私が必要としていることを行うようです。ALTER TABLEを参照してください


そして、どのように「すべてのトリガー修正を再計算」しますか?
Wojtek Kruszewski

15
同時ロードに注意:ALTER TABLE ... DISABLE TRIGGER USERテーブルに排他ロックが必要です。
Erwin Brandstetter、2014年

3
@WojtekKruszewski、私はいくつかの事前知識を使用して、トリガーによって行われるはずの変更を手動で再計算できることを意味したと思います(たとえば、トリガーがすべての行で同じ変更を行う場合、より効率的になる可能性があります)単一のUPDATEによって処理されます)。私は彼があなたがあらゆる状況でこれを行うことができることを意味したとは思いません。
Rauni Lillemets 2014

1
@zyzofのソリューションは、すべてのトリガーを無効にするのに適しています。
uthomas 2017年

48

トリガーを無効にする

ALTER TABLE table_name DISABLE TRIGGER trigger_name

トリガーを有効にする

ALTER TABLE table_name ENABLE TRIGGER trigger_name

1
:また、このため、「すべて」を使用することができますALTER TABLE table_name DISABLE TRIGGER all
DenisNovac

8
SET session_replication_role = replica; 

LinuxマシンのPostgreSQL 9.4では、pgAdminのテーブルエディターでテーブルを変更すると機能せず、通常のクエリでテーブルを変更すると機能します。pg_triggerテーブルの手動変更もサーバーの再起動なしでは機能しませんが、postgresql.nabble.comのような動的クエリは機能しますENABLE / DISABLE ALL TRIGGERS IN DATABASEは機能します。チューニングが必要な場合に役立ちます。

たとえば、特定の名前空間にテーブルがある場合、次のようになります。

create or replace function disable_triggers(a boolean, nsp character varying) returns void as
$$
declare 
act character varying;
r record;
begin
    if(a is true) then
        act = 'disable';
    else
        act = 'enable';
    end if;

    for r in select c.relname from pg_namespace n
        join pg_class c on c.relnamespace = n.oid and c.relhastriggers = true
        where n.nspname = nsp
    loop
        execute format('alter table %I %s trigger all', r.relname, act); 
    end loop;
end;
$$
language plpgsql;

特定のトリガー機能を持つすべてのトリガーを無効にする場合は、次のようになります。

create or replace function disable_trigger_func(a boolean, f character varying) returns void as
$$
declare 
act character varying;
r record;
begin
    if(a is true) then
        act = 'disable';
    else
        act = 'enable';
    end if;

    for r in select c.relname from pg_proc p 
        join pg_trigger t on t.tgfoid = p.oid
        join pg_class c on c.oid = t.tgrelid
        where p.proname = f
    loop
        execute format('alter table %I %s trigger all', r.relname, act); 
    end loop;
end;
$$
language plpgsql;

システムカタログの PostgreSQLドキュメント


トリガーの発火プロセスには別の制御オプションがあります。

ALTER TABLE ... ENABLE REPLICA TRIGGER ...-トリガーはレプリカモードでのみ起動します。

ALTER TABLE ... ENABLE ALWAYS TRIGGER ...-トリガーは常に起動します(明らかに)


7

pgAdmin(III)でトリガーを無効にすることもできます。

  1. テーブルを探す
  2. +を展開します
  3. トリガーでトリガーを見つける
  4. 右クリックして[トリガーを有効にしますか?]チェックボックスをオフにします

4
SET session_replication_role = replica;  

また、Postgres 9.1では、私にとって重要な作業です。bartolo-otritで説明されている2つの関数をいくつか変更して使用します。テーブルを正しく識別するには、名前空間またはスキーマが存在している必要があるため、最初の関数を変更して機能させました。新しいコードは次のとおりです。

CREATE OR REPLACE FUNCTION disable_triggers(a boolean, nsp character varying)
  RETURNS void AS
$BODY$
declare 
act character varying;
r record;
begin
    if(a is true) then
        act = 'disable';
    else
        act = 'enable';
    end if;

    for r in select c.relname from pg_namespace n
        join pg_class c on c.relnamespace = n.oid and c.relhastriggers = true
        where n.nspname = nsp
    loop
        execute format('alter table %I.%I %s trigger all', nsp,r.relname, act); 
    end loop;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION disable_triggers(boolean, character varying)
  OWNER TO postgres;

次に、すべてのスキーマに対して選択クエリを実行します:

SELECT disable_triggers(true,'public');
SELECT disable_triggers(true,'Adempiere');
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.