小编典典

从条件INSERT获取ID

sql

对于这样的表:

CREATE TABLE Users(
    id SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

什么是正确的一次查询插入以下操作:

给定用户name,插入新记录并返回新记录id。但是,如果name已经存在,则只需返回id

我知道PostgreSQL 9.5中针对的新语法ON CONFLICT(column) DO UPDATE/NOTHING,但是鉴于我需要id返回,因此我无法弄清楚它是否有帮助(如果有的话)。

似乎RETURNING idON CONFLICT不属于在一起。


阅读 184

收藏
2021-03-23

共1个答案

小编典典

UPSERT的实现非常复杂,以确保不会发生并发写访问。看一下这个Postgres
Wiki
,它在最初的开发过程中用作日志。Postgres黑客决定RETURNING在Postgres
9.5的第一个发行版的子句中不包括“排除”行。他们可能会为下一个版本构建一些内容。

这是手册中解释您的情况的重要说明:

RETURNING列表的语法与的输出列表的语法相同SELECT仅返回成功插入或更新的行。 例如,如果某行被锁定但由于ON CONFLICT 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 ins
UNION  ALL
SELECT id FROM users          -- 2nd SELECT never executed if INSERT successful
WHERE  name = 'new_usr_name'  -- input value a 2nd time
LIMIT  1;

在表上可能存在并发写入负载

考虑一下(对于 单行 INSERT

要插入一 组行

所有这三个都有非常详细的说明。

2021-03-23