简体   繁体   English

Postgres INSERT触发“ ON CONFLICT DO NOTHING”

[英]Postgres INSERT triggers with 'ON CONFLICT DO NOTHING'

I have an INSERT statement in Postgres 9.5+, but the INSERT sometimes doesn't actually happen because of a key conflict (I've set ON CONFLICT DO NOTHING on the INSERT). 我在Postgres 9.5+中有一个INSERT语句,但是有时由于键冲突而实际上并没有发生INSERT(我在INSERT上设置了ON CONFLICT DO NOTHING )。

If the INSERT happens, then of course the trigger runs. 如果发生INSERT,则触发器当然会运行。 But if the INSERT doesn't happen because of a key conflict, will triggers still run? 但是,如果由于键冲突而没有发生INSERT,触发器是否仍将运行?

Does it depend on whether it's a BEFORE or AFTER trigger? 它是否取决于触发BEFORE还是AFTER

For an AFTER trigger there are more "opportunities" to cancel an INSERT (with other triggers) and thereby not fire the trigger. 对于AFTER触发器,还有更多“机会”可以取消INSERT (与其他触发器一起使用),从而触发触发器。 But this problem does not seem to depend on BEFORE or AFTER . 但是这个问题似乎并不取决于BEFOREAFTER If the row is skipped in an UPSERT command ( INSERT ... ON CONFLICT DO NOTHING ), then it is skipped before any ON INSERT triggers would fire. 如果在UPSERT命令中跳过了该行( INSERT ... ON CONFLICT DO NOTHING ),则触发任何ON INSERT触发器之前 ,将跳过该行。

You have to check the success of the INSERT and act upon the outcome - just like we discussed under your other question: 您必须检查INSERT的成功并根据结果采取行动-就像我们在您的另一个问题下讨论的那样:

You got solutions for the problem there. 您在那里找到了解决问题的方法。 If the commands in the trigger do not depend on the inserted row, you might just use a transaction with several separate commands - or wrap this in a function for convenience. 如果触发器中的命令不依赖于插入的行,则可以只使用带有多个单独命令的事务-或为了方便将其包装在函数中。

If the commands in the trigger depend on the inserted row, you want the involved row back in either case. 如果触发器中的命令取决于插入的行,则无论哪种情况,您都希望返回所涉及的行。 Then you have a classical case of INSERT or SELECT ... 那么您就拥有INSERT或SELECT的经典案例...

... and then use the result in additional commands. ...,然后在其他命令中使用结果。 You might chain that with data-modifying CTEs: 您可以将其与修改数据的CTE链接起来:


I thought of using a RULE instead, which can rewrite an INSERT to run additional commands, independent of the outcome. 我想到了改用RULE ,它可以重写INSERT来运行其他命令,而与结果无关。 More tricky than a trigger, but it kicks in before the INSERT might be cancelled. 比触发器更棘手,但是它可以在取消INSERT 之前启动。 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. 请注意,包含ON CONFLICT子句的INSERT不能用于具有INSERTUPDATE规则的表。 Consider using an updatable view instead. 考虑改用可更新的视图。

So, no dice. 所以,没有骰子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM