Come disabilitare temporaneamente i trigger in PostgreSQL?


131

Sto caricando i dati in blocco e posso ricalcolare tutte le modifiche del trigger molto più a buon mercato dopo il fatto che su base riga per riga.

Come posso disabilitare temporaneamente tutti i trigger in PostgreSQL?

Risposte:


163

In alternativa, se si desidera disabilitare tutti i trigger, non solo quelli nella tabella USER, è possibile utilizzare:

SET session_replication_role = replica;

Ciò disabilita i trigger per la sessione corrente.

Per riattivare la stessa sessione:

SET session_replication_role = DEFAULT;

Fonte: http://koo.fi/blog/2013/01/08/disable-postgresql-triggers-temporarily/


2
Eccezionale. La mia cancellazione di massa è passata da 30 minuti a <1 secondo :)
Dan Lenski,

7
È anche utile che questo comando non disabiliti i trigger di vincolo
bartolo-otrit

2
Ho trascorso l'ultima mezz'ora a cercare invano un modo per aggirare l'errore "viola i vincoli di chiave esterna" nel mio ambiente di test, e questo è esattamente!
Amalgovinus,

Un avvertimento: secondo i documenti di configurazione di runtime e i documenti ALTER TABLE questo funzionerà con trigger normali ma non quelli impostati con ENABLE REPLICAo ENABLE ALWAYS.
Beldaz,

Sono attivo 10.4e sembra ignorare questa affermazione di cui sopra.
Stephane,

129

PostgreSQL conosce il ALTER TABLE tblname DISABLE TRIGGER USERcomando, che sembra fare ciò di cui ho bisogno. Vedi ALTER TABLE .


E poi come "ricalcoli tutte le modifiche del trigger"?
Wojtek Kruszewski,

15
Attento al carico simultaneo: ALTER TABLE ... DISABLE TRIGGER USERrichiede un blocco esclusivo sul tavolo.
Erwin Brandstetter,

3
@WojtekKruszewski, penso che David volesse dire che poteva ricalcolare manualmente le modifiche che avrebbero fatto il trigger, usando alcune conoscenze precedenti (ad esempio, se il trigger farà la stessa modifica in ogni riga, il che può essere più efficiente gestito da un singolo AGGIORNAMENTO). Non penso che intendesse dire che puoi farlo in ogni situazione.
Rauni Lillemets,

1
La soluzione di @ zyzof è migliore per disabilitare tutti i trigger.
uthomas

48

Per disabilitare il trigger

ALTER TABLE table_name DISABLE TRIGGER trigger_name

Per abilitare il trigger

ALTER TABLE table_name ENABLE TRIGGER trigger_name

1
Puoi anche usare "tutto" per questo:ALTER TABLE table_name DISABLE TRIGGER all
DenisNovac il

8
SET session_replication_role = replica; 

Non funziona con PostgreSQL 9.4 sul mio computer Linux se cambio una tabella tramite l'editor di tabelle in pgAdmin e funziona se cambio tabella tramite query ordinaria. Anche le modifiche manuali nella tabella pg_trigger non funzionano senza il riavvio del server, ma la query dinamica come su postgresql.nabble.com ABILITA / DISATTIVA TUTTI I TRIGGER IN DATABASE funziona. Potrebbe essere utile quando hai bisogno di qualche sintonizzazione.

Ad esempio, se hai tabelle in un determinato spazio dei nomi, potrebbe essere:

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;

Se si desidera disabilitare tutti i trigger con una determinata funzione di trigger, potrebbe essere:

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;

Documentazione PostgreSQL per cataloghi di sistema


Esistono altre opzioni di controllo del processo di attivazione del trigger:

ALTER TABLE ... ENABLE REPLICA TRIGGER ... - il trigger si attiverà solo in modalità replica.

ALTER TABLE ... ABILITARE SEMPRE IL GRILLETTO ... - il grilletto sparerà sempre (ovviamente)


7

Puoi anche disabilitare i trigger in pgAdmin (III):

  1. Trova il tuo tavolo
  2. Espandi il +
  3. Trova il tuo trigger in Trigger
  4. Fare clic con il tasto destro, deselezionare "Trigger abilitato?"

4
SET session_replication_role = replica;  

anche il lavoro con i dosaggi per me in Postgres 9.1. io uso le due funzioni descritte da bartolo-otrit con qualche modifica. Ho modificato la prima funzione per farlo funzionare perché lo spazio dei nomi o lo schema devono essere presenti per identificare correttamente la tabella. Il nuovo codice è:

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;

quindi faccio semplicemente una query di selezione per ogni schema:

SELECT disable_triggers(true,'public');
SELECT disable_triggers(true,'Adempiere');
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.