【问题标题】:Row is not being deleted because of cascade trigger updates this row由于级联触发器更新了此行,因此未删除行
【发布时间】:2011-04-13 18:52:27
【问题描述】:

我在删除具有触发器的表中的行时遇到问题,该触发器调用第二个表的触发器,该触发器会更新第一个表中的行。这是描述:

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 语句,然后最终删除行。在第一次 DELTE 之后,表 B 中只删除了连接的 ROWS,但表 A 中正在删除的行仍然存在。

你有答案吗?我怀疑 pgsql 不允许更新触发器中被删除的行,但我在 pgsql 文档中没有找到任何关于它的信息。 解决办法是什么?

【问题讨论】:

  • 为什么不使用ON DELETE CASCADE 而不是第一个触发器?

标签: sql postgresql triggers cascade sql-delete


【解决方案1】:

我遇到了类似的问题,但只有一张桌子。从给定表中删除行会触发一个触发器(在删除之前),该触发器在同一个表中搜索相关行(通过给定条件),如果找到它们,这些行将得到更新。现在,如果要通过相同的删除命令删除更新的行,那么它不会被删除。

所以基本上,如果你创建一个触发器,它总是更新被删除的同一行,从现在开始你不能删除任何东西。

我不知道这是不是故意的。从某种意义上说,这似乎是合乎逻辑的,这是肯定的。如果您更新了一条记录,则它与要删除的记录不同。

(抱歉英语不好)

【讨论】:

    【解决方案2】:

    所以基本上你有一个 A -> 触发器 -> B -> 触发器 -> A 情况,这实际上是设计上不正确的事情,我认为 postgres 锁定了正在执行触发器的行或 A 行被锁定但我'不确定 postgres 的所有内部行为。

    所以你可以先尝试 DELETE FROM B WHERE a_id = %Row_to_delete_id% 然后 DELETE FROM A WHERE a_id = %Row_to_delete_id%,在事务中,

    但我强烈建议您修改触发器依赖项

    【讨论】:

    • 起初我没有触发器依赖项(表 A 中没有触发器),因为我在删除级联时在表 B (a_table_id_fk) 中有外键。这是不正确的,当我从表 A 中删除行时出现锁。我更改为我在帖子中描述的解决方案,但它仍然不正确。那么我是否必须从表 A 中的触发器中辞职?也许准备一些替代品,比如特殊的 pl/pgsql 函数来删除表 A 中的行,这也会删除表 B 中的行?
    猜你喜欢
    • 1970-01-01
    • 2016-12-24
    • 2019-02-25
    • 2021-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多