我想知道是否可以使用以下语句进行带过滤的upsert。也就是说,我可以先尝试使用where子句更新,如果失败,然后插入,而不是相反?我想在Postgres中做到这一点。
插入...在冲突时不做/更新
我确实看到了这一点,但这肯定有点复杂 https://dba.stackexchange.com/questions/13468/idiomatic-way-to-implement-upsert-in-postgresql
答案 0 :(得分:1)
也就是说,我可以先尝试使用where子句进行更新(如果失败),然后再插入,而不是相反吗?
目前尚不清楚为什么要这么做。
UPSERT的目的是确保数据库恰好包含具有给定键和给定一组其他列值的一行。 Postgres首先尝试INSERT,因为当键与重复的行发生冲突时INSERT将会失败(因此它可以回退到更新冲突的行而不是引发异常)。如果WHERE子句不匹配,则UPDATE不会失败。它将successfully update zero rows。如果您违反约束(例如CHECK或NOT NULL约束),则UPDATE可能会失败,但它不会因为您没有匹配任何行而失败。
另一方面,如果您的UPDATE会更改现有行,那么INSERT必然会因唯一性冲突而失败(因为该行存在)。因此,在这种情况下,首先尝试执行INSERT并不会真正改变结果。
可以使用INSERT... ON CONFLICT DO UPDATE... WHERE...
格式的语法在PostgreSQL的UPSERT上挂起条件。这将:
我认为这在功能上等同于您的要求,因为: