Строка не удаляется из-за каскадного триггера, обновляющего эту строку - PullRequest
2 голосов
/ 13 апреля 2011

У меня проблема с удалением строк в таблице, которая имеет триггер, который вызывает триггер второй таблицы, который обновляет строку в первой таблице.Вот описание:

Table A (id,b_table_count) 
Table B (id,a_table_id_fk)

Таблица A имеет триггер BEFORE DELETE, в котором есть инструкции:

BEGIN  
DELETE FROM b where a_table_fk = OLD.id;  
RETURN OLD;  
END;

Таблица B имеет триггер AFTER DELETE с инструкцией:

UPDATE a SET b_table_count = b_table_count-1 WHERE OLD.a_table_id_fk = a.id;  

Когда я удаляю строку из таблицы A, у которой нет связанных строк в B, все правильно.
Но когда я удаляю строку из таблицы A, у которой есть связанные строки в таблице B, оператор DELETE возвращает "Запрос возвращен успешно: затронуто 0 строк ".Я должен выполнить DELETE statment второй раз, затем строка окончательно удаляется.После первого удаления только связанные строки удаляются в таблице B, но строка, удаляемая в таблице A., остается.

У вас есть ответ на этот вопрос?Я подозреваю, что pgsql не позволяет обновить строку, удаляемую в триггере, но я не нашел ничего об этом в документации pgsql.Какое решение?

Ответы [ 2 ]

2 голосов
/ 24 мая 2011

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

Таким образом, в основном, если вы создаете триггер, он всегда обновляет одну и ту же строку, которая являетсябудучи удаленным, вы не можете ничего удалять с этого момента.

Я не знаю, намеренно это или нет.С одной стороны, это кажется логичным, это точно.Если вы обновляете запись, это не та запись, которая была предназначена для удаления.

(извините за плохой английский)

0 голосов
/ 13 апреля 2011

Таким образом, в основном у вас есть A -> триггер -> B -> триггер -> ситуация, которая на самом деле некорректна, и я думаю, что postgres блокирует строку, которая выполняет триггер, или строка заблокирована, но яЯ не уверен во всем внутреннем поведении postgres.

, поэтому вы можете сначала попробовать УДАЛИТЬ ИЗ Б, ГДЕ a_id =% Row_to_delete_id%, а затем УДАЛИТЬ ИЗ ГДЕ a_id =% Row_to_delete_id%, в транзакции,

но я настоятельно рекомендую вам пересмотреть ваши триггерные зависимости

...