PostgreSQL - откатан ли триггер ENABLE / DISABLE? - PullRequest
1 голос
/ 22 мая 2019

У меня есть функция PL / pgSQL, тело которой содержит некоторые регулярные / нормальные операторы DML ... как UPDATE, DELETE и т. Д.

Но в теле этой функции есть такие выражения, как:

ALTER TABLE sc.TBL DISABLE TRIGGER TR_TBL_Delete; --- 1

, а также

ALTER TABLE sc.TBL ENABLE TRIGGER TR_TBL_Delete; --- 2

Теперь ... Я знаю, что если в теле функции произойдет ошибка, все изменения в БД, сделанные операторами UPDATE, DELETE и т. Д., Будут отменены. И это произойдет независимо от того, будет ли блок EXCEPTION (т.е. перехватывать исключение) частью основного функционального блока или нет.

Обратите внимание, что при входе в функцию все триггеры находятся в состоянии ВКЛЮЧЕНО. Поэтому я хочу быть на 100% уверенным, что при выходе из функции они также будут в состоянии ВКЛЮЧЕНО.

Итак ... У меня есть некоторые опасения по этому поводу ... Интересно, возможно ли, чтобы какой-то триггер оставался в состоянии DISABLED, потому что оператор формы --- 2 не был достигнут (из-за возникшей ошибки).

В некотором смысле мне интересно, участвуют ли операторы ENABLE TRIGGER/DISABLE TRIGGER в той транзакции, в которой выполняется тело функции.

Мне нужен авторитетный ответ с некоторыми ссылками на официальные документы, если это возможно.

1 Ответ

1 голос
/ 23 мая 2019

Я попробовал это сам с несколькими простыми тестами.

Эти операторы триггера ENABLE / DISABLE участвуют в транзакции.
Это означает, что он работает так, как я хотел / ожидал, чтобы он работал.

Тесты, которые я действительно показал, показывают, что если функция отключает триггер A, а затем сталкивается с ошибкой до достижения соответствующего оператора триггера разрешения A , эти изменения, сделанные в триггере, откатываются.Таким образом ... после того, как функция вернет триггер, он все еще находится во включенном состоянии.

BEGIN
    ALTER TABLE TBL DISABLE TRIGGER A;

    -- do some work (success) 

    -- more work here... but an error is raised

    ALTER TABLE TBL ENABLE TRIGGER A; -- (not executed)

    -- some other statements here (not executed) 

END;
...