PostgreSQL中ON CONFLICT WHERE条件不匹配仍更新问题求助
问题根源:混淆了ON CONFLICT中两个WHERE的作用
你当前SQL里的WHERE子句放在了ON CONFLICT (id)后面,这个位置的WHERE是部分唯一索引的谓词,仅用于匹配创建了部分唯一索引的场景,并不是用来控制是否执行DO UPDATE的条件。所以不管这个条件是否成立,只要发生主键冲突,就会执行更新操作。
正确写法:将条件移至DO UPDATE之后
要实现「冲突发生时仅满足特定条件才更新」的逻辑,需要把判断条件放在DO UPDATE SET ...的后面:
INSERT INTO books VALUES (12, 0, CURRENT_TIMESTAMP) ON CONFLICT (id) DO UPDATE SET version = books.version + 1, updated = CURRENT_TIMESTAMP WHERE books.version IS NULL OR books.updated + INTERVAL '2min' < CURRENT_TIMESTAMP;
这里的WHERE子句会在冲突发生后,检查现有行是否符合条件,只有满足条件时才会执行更新操作。
补充说明
ON CONFLICT (id) WHERE ...中的WHERE:仅用于定义部分唯一索引的过滤规则,比如你创建了CREATE UNIQUE INDEX idx_books_id ON books(id) WHERE version IS NULL;,这时候ON CONFLICT的WHERE才会生效,用来匹配这个部分索引的冲突场景。DO UPDATE ... WHERE ...中的WHERE:才是控制更新是否执行的条件,基于冲突发生时的现有行数据进行判断。
内容的提问来源于stack exchange,提问作者user122222
相关产品推荐
相关产品推荐

