[英]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
. 但是这个问题似乎并不取决于BEFORE
或AFTER
。 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 anON CONFLICT
clause cannot be used on tables that have eitherINSERT
orUPDATE
rules. 请注意,包含ON CONFLICT
子句的INSERT
不能用于具有INSERT
或UPDATE
规则的表。 Consider using an updatable view instead. 考虑改用可更新的视图。
So, no dice. 所以,没有骰子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.