Як тимчасово відключити тригери в PostgreSQL?


131

Я групових даних завантажую і можу перерахувати всі модифікації тригера набагато дешевше за фактом, ніж на основі рядка за рядком.

Як я можу тимчасово відключити всі тригери в PostgreSQL?

Відповіді:


163

Крім того, якщо ви хочете вимкнути всі тригери, не лише ті, які знаходяться в таблиці USER, ви можете використовувати:

SET session_replication_role = replica;

Це вимикає тригери для поточного сеансу.

Щоб повторно увімкнути той самий сеанс:

SET session_replication_role = DEFAULT;

Джерело: http://koo.fi/blog/2013/01/08/disable-postgresql-triggers-temporary/


2
Дивовижно. Змусив моє масове вилучення тривати від 30 хвилин до <1 секунди :)
Ден Ленскі

7
Також зручно, що ця команда не відключає тригери обмеження
bartolo-otrit

2
Останні півгодини я даремно шукав спосіб обходу помилки "порушує закордонні ключі" в моєму тестовому середовищі, і саме це!
Амальговінус

Одне застереження: згідно з документами config runtime та документами ALTER TABLE, це працюватиме з звичайними тригерами, але не з тими, що встановлені з ENABLE REPLICAабо ENABLE ALWAYS.
beldaz

Я ввімкнув 10.4і, здається, ігнорує це вищезазначене твердження.
Стефан

129

PostgreSQL знає ALTER TABLE tblname DISABLE TRIGGER USERкоманду, яка, здається, виконує те, що мені потрібно. Див. НАЗАД ТАБЛ .


І як тоді ви «перераховуєте всі модифікації тригера»?
Войтек Крушевський

15
Обережно з одночасним навантаженням: ALTER TABLE ... DISABLE TRIGGER USERвимагає ексклюзивного замка на столі.
Ервін Брандштетер

3
@WojtekKruszewski, я думаю, що Девід мав на увазі, що він може перерахувати зміни вручну, які були б зроблені за допомогою тригера, використовуючи деякі попередні знання (наприклад, якщо тригер внесе однакові зміни в кожному рядку, що може бути ефективніше обробляється одним ОНОВЛЕННЯМ). Я не думаю, що Він мав на увазі, що Ви можете це робити в будь-якій ситуації.
Рауні Ліллемець

1
@ рішення zyzof краще для відключення всіх тригерів.
утоми

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; 

Він не працює з PostgreSQL 9.4 на моїй машині Linux, якщо я змінюю таблицю через редактор таблиць у pgAdmin і працює, якщо я змінюю таблицю за допомогою звичайного запиту. Ручні зміни в таблиці pg_trigger також не працюють без перезапуску сервера, але динамічний запит, як на postgresql.nabble.com ENABLE / DISABLE ВСІ ТРИГІНГЕРИ В БАНКІ . Це може бути корисно, коли вам потрібна певна настройка.

Наприклад, якщо у вас є таблиці в певному просторі імен, це може бути:

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 ... - тригер спрацює лише в режимі реплікації.

АЛЬТЕР ТАБЛИЦІ ... РОЗВИЩАЙТЕ ЗАВЖДИ ТРИГІГЕР ... - тригер буде спрацьовувати завжди (очевидно)


7

Ви також можете відключити тригери в pgAdmin (III):

  1. Знайдіть свій стіл
  2. Розгорніть +
  3. Знайдіть спусковий гачок у триггерах
  4. Клацніть правою кнопкою миші, зніміть прапорець "Увімкнено тригер?"

4
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');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.