【发布时间】:2011-04-25 22:18:44
【问题描述】:
我正在批量加载数据,并且可以在事后重新计算所有触发器修改,这比逐行计算要便宜得多。
如何暂时禁用 PostgreSQL 中的所有触发器?
【问题讨论】:
标签: postgresql triggers bulkinsert
我正在批量加载数据,并且可以在事后重新计算所有触发器修改,这比逐行计算要便宜得多。
如何暂时禁用 PostgreSQL 中的所有触发器?
【问题讨论】:
标签: postgresql triggers bulkinsert
用于禁用触发器
ALTER TABLE table_name DISABLE TRIGGER trigger_name
用于启用触发器
ALTER TABLE table_name ENABLE TRIGGER trigger_name
【讨论】:
ALTER TABLE table_name DISABLE TRIGGER all
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 disable_triggers(true,'public');
SELECT disable_triggers(true,'Adempiere');
【讨论】:
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 ... - 触发器将始终触发(显然)
【讨论】:
您还可以在 pgAdmin (III) 中禁用触发器:
【讨论】:
或者,如果您想禁用所有触发器,而不仅仅是 USER 表上的触发器,您可以使用:
SET session_replication_role = replica;
这会禁用当前会话的触发器。
为同一会话重新启用:
SET session_replication_role = DEFAULT;
来源:http://koo.fi/blog/2013/01/08/disable-postgresql-triggers-temporarily/
【讨论】:
ENABLE REPLICA 或ENABLE ALWAYS 设置的触发器。
10.4,它似乎忽略了上述声明。
PostgreSQL 知道ALTER TABLE tblname DISABLE TRIGGER USER 命令,这似乎可以满足我的需要。见ALTER TABLE。
【讨论】:
ALTER TABLE ... DISABLE TRIGGER USER 需要对表进行排他锁。