【问题标题】:Postgres INSERT triggers with 'ON CONFLICT DO NOTHING'Postgres INSERT 触发器与 'ON CONFLICT DO NOTHING'
【发布时间】:2017-01-02 22:51:46
【问题描述】:

我在 Postgres 9.5+ 中有一个 INSERT 语句,但由于键冲突,INSERT 有时实际上并没有发生(我在 INSERT 上设置了 ON CONFLICT DO NOTHING)。

如果 INSERT 发生,那么触发器当然会运行。但是如果由于键冲突而没有发生 INSERT,触发器还会运行吗?

是否取决于它是BEFORE 还是AFTER 触发器?

【问题讨论】:

  • insert 触发器不会运行,因为没有要运行的行。如果您执行了update,则会运行更新触发器。

标签: sql postgresql triggers sql-insert


【解决方案1】:

对于AFTER 触发器,有更多“机会”可以取消INSERT(与其他触发器一起使用),从而不会触发触发器。但是这个问题似乎并不依赖于BEFOREAFTER。如果在 UPSERT 命令 (INSERT ... ON CONFLICT DO NOTHING) 中跳过该行,则会在任何ON INSERT 触发器触发之前跳过该行。

您必须检查 INSERT 是否成功并根据结果采取行动 - 就像我们在您的其他问题下讨论的那样:

您在那里找到了问题的解决方案。 如果触发器中的命令不依赖插入的行,您可以只使用带有多个单独命令的事务 - 或者为了方便将其包装在一个函数中。

如果触发器中的命令依赖插入的行,则无论哪种情况,您都希望返回所涉及的行。然后你有一个经典案例 INSERT or SELECT ...

... 然后在其他命令中使用结果。您可以将其与数据修改 CTE 链接起来:


我想改用RULE,它可以重写INSERT 来运行其他命令,而与结果无关。比触发器更棘手,但它会在INSERT 可能被取消之前启动。 然而the manual warns:

请注意,包含ON CONFLICT 子句的INSERT 不能用于 具有INSERTUPDATE 规则的表。考虑使用一个 而是可更新的视图。

所以,没有骰子。

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 2018-08-02
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 2018-09-10
    • 2020-12-22
    相关资源
    最近更新 更多