带有 'ON CONFLICT DO NOTHING' 的 Postgres INSERT 触发器

Postgres INSERT triggers with 'ON CONFLICT DO NOTHING'

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

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

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

对于 AFTER 触发器,有更多 "opportunities" 可以取消 INSERT(与其他触发器),因此 不会 触发触发器.但是这个问题好像不依赖于BEFORE或者AFTER。如果在 UPSERT 命令 (INSERT ... ON CONFLICT DO NOTHING) 中跳过了该行,那么它会在 之前被跳过 ,任何 ON INSERT 触发器都会触发。

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

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

如果触发器中的命令 依赖于插入的行,在任何一种情况下您都希望返回相关行。然后你有一个经典案例 INSERT 或 SELECT ...

  • Is SELECT or INSERT in a function prone to race conditions?

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

  • Insert inserted id to another table

我想到了使用 RULE instead, which can rewrite an INSERT to run additional commands, independent of the outcome. More tricky than a trigger, but it kicks in before the INSERT might be cancelled. However, the manual warns:

Note that an INSERT containing an ON CONFLICT clause cannot be used on tables that have either INSERT or UPDATE rules. Consider using an updatable view instead.

所以,没有骰子。