UPSERT的实现非常复杂,以确保不会发生并发写访问。看一下这个Postgres
Wiki,它在最初的开发过程中用作日志。Postgres黑客决定
RETURNING在Postgres
9.5的第一个发行版的子句中不包括“排除”行。他们可能会为下一个版本构建一些内容。
这是手册中解释您的情况的重要说明:
该
RETURNING列表的语法与的输出列表的语法相同SELECt。 仅返回成功插入或更新的行。 例如,如果某行被锁定但由于onCONFLICT DO UPDATE ... WHERe不满足子句条件而未更新,则不会返回该行。
大胆强调我的。
对于要插入的 单行 :
在同一表上没有并发写入负载
WITH ins AS ( INSERT INTO users(name) VALUES ('new_usr_name') -- input value ON ConFLICT(name) DO NOTHING RETURNING users.id )SELECT id FROM insUNIOn ALLSELECt id FROM users -- 2nd SELECT never executed if INSERT successfulWHERe name = 'new_usr_name' -- input value a 2nd timeLIMIT 1;在表上可能存在并发写入负载
考虑一下(对于 单行
INSERT)
要插入一 组行 :
- 如何在从INSERT …发生冲突时将排除的行包括在内
所有这三个都有非常详细的说明。



