如何在PostgreSQL中暂时禁用触发器?

时间:2010-10-15 12:36:31

标签: postgresql triggers bulkinsert

我正在批量加载数据,并且可以在事后更便宜地重新计算所有触发器修改,而不是逐行。

如何暂时禁用PostgreSQL中的所有触发器?

6 个答案:

答案 0 :(得分:131)

或者,如果您想要禁用所有触发器,而不仅仅是USER表上的触发器,您可以使用:

SET session_replication_role = replica;

这会禁用当前会话的触发器。

要为同一会话重新启用:

SET session_replication_role = DEFAULT;

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

答案 1 :(得分:106)

PostgreSQL知道ALTER TABLE tblname DISABLE TRIGGER USER命令,它似乎做我需要的。请参阅ALTER TABLE

答案 2 :(得分:21)

用于禁用触发器

ALTER TABLE table_name DISABLE TRIGGER trigger_name

用于启用触发器

ALTER TABLE table_name ENABLE TRIGGER trigger_name

答案 3 :(得分:6)

您还可以在pgAdmin(III)中禁用触发器:

  1. 找到你的桌子
  2. 展开+
  3. 在触发器中找到触发器
  4. 右键单击,取消选中“Trigger Enabled?”

答案 4 :(得分:5)

SET session_replication_role = replica; 

如果我通过pgAdmin中的表编辑器更改表,它在我的Linux机器上不能与PostgreSQL 9.4一起使用,如果我通过普通查询更改表,则无效。 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;

system catalogs

的PostgreSQL文档

触发器触发过程还有另一个控制选项:

ALTER TABLE ... ENABLE REPLICA TRIGGER ... - 触发器仅以复制模式触发。

ALTER TABLE ... ENABLE ALWAYS TRIGGER ... - 触发器将始终触发(显然)

答案 5 :(得分:3)

SET session_replication_role = replica;  
在Postgres 9.1中,我也能为我工作。 我使用bartolo-otrit描述的两个函数进行了一些修改。 我修改了第一个函数,使其适用于我,因为必须存在命名空间或模式才能正确识别表。 新代码是:

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查询:

SELECT disable_triggers(true,'public');
SELECT disable_triggers(true,'Adempiere');