防止PostgreSQL中的递归触发器

Hao*_*Hao 23 postgresql recursion

如何防止触发器的递归执行?假设我想在账户图表上构建一个"树形"描述.所以我所做的是当插入/更新新记录时,我更新了父记录down_qty,因此这将以递归方式触发更新触发器.

现在,我的代码还可以 - 我把它放在UPDATE触发器的第一行:

-- prevents recursive trigger
if new.track_recursive_trigger <> old.track_recursive_trigger then
    return new;
end if;
Run Code Online (Sandbox Code Playgroud)

当我需要更新父记录的数量时,这是我的触发器的示例代码:

update account_category set 
    track_recursive_trigger = track_recursive_trigger + 1, -- i put this line to prevent recursive trigger
    down_qty = down_qty - (old.down_qty + 1)
where account_category_id = m_parent_account;
Run Code Online (Sandbox Code Playgroud)

我想如果PostgreSQL中有一种方法可以检测递归触发而不引入一个类似于MSSQL的新字段trigger_nestlevel.

[编辑]

我在树内循环,我需要将down_qty每个account_category回到它的根部.例如,我插入一个新的账户类别,它需要递增down_qty其父的account_category,同样,当我更改帐户类别的父母account_category,我需要递减down_qtyaccount_category的早先父account_category.虽然我认为它可以,但我不是让PostgreSQL做递归触发器.我之前使用的是MSSQL,其中触发递归深度级别仅限于16级别.

小智 77

这就是我在PostgreSQL 9.2中所做的,虽然我必须承认我没有发现这种方法记录在案.这里pg_trigger_depth() 记录了一个函数,我用它来区分触发器中的原始调用和嵌套调用.

CREATE TRIGGER trg_taxonomic_positions
AFTER INSERT OR UPDATE OF taxonomic_position
ON taxon_concepts
FOR EACH ROW
WHEN (pg_trigger_depth() = 0)
EXECUTE PROCEDURE trg_taxonomic_positions()
Run Code Online (Sandbox Code Playgroud)

  • 辉煌!不幸的是,这个功能不存在于9.1 :(.我想知道是否有替代它... (4认同)
  • 救星.确认它在9.4上工作就像一个魅力.有人应该帮助它进入文档.据我所知,在触发器`WHEN(condition)`子句中没有看到任何有意义的例子.这绝对是合格的. (4认同)
  • 在PostgreSQL 9.3.4中工作,谢谢 (3认同)
  • 它工作,但要注意,因为该功能不是衡量递归.如果其他触发器发出实际触发器,则该函数将产生1而不是0. (3认同)

tpd*_*pdi 9

在pg中,由你来跟踪触发器递归.

如果触发器函数执行SQL命令,则这些命令可能会再次触发触发器.这称为级联触发器.级联级别的数量没有直接限制.级联可能会导致同一触发器的递归调用; 例如,INSERT触发器可能会执行一个命令,该命令会将另一行插入同一个表中,从而导致再次触发INSERT触发器.在这种情况下,触发程序员有责任避免无限递归.

http://www.postgresql.org/docs/8.3/static/trigger-definition.html

  • 请不要停止阅读这个已接受的、勾选的答案。下面包含了一个流行的建议,许多读者(包括我自己)都发现它很有用! (9认同)