【问题标题】:Postgres: Insert if not exists, otherwise return the row [duplicate]Postgres:如果不存在则插入,否则返回行[重复]
【发布时间】:2014-05-09 20:54:57
【问题描述】:

在一个 SQL 语句中,我尝试插入一行,如果由于约束而失败,则返回现有行。

我有:

INSERT INTO session (token, expiry) SELECT 'abcdefg', '2014-05-14 20:25:12.279667' WHERE  NOT EXISTS (SELECT * FROM session where token= 'abcdefg');

token 列具有唯一约束。我尝试在末尾附加RETURNING *,但这仍然没有返回现有行。

这是为什么?我以为我最后的SELECT 语句将被执行并返回。有什么想法吗?

注意:由于一些复杂的竞争条件,我不能使用 Postgres 函数或多个 SQL 语句。

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:
    WITH d(t, e) AS ( VALUES ('abcdefg', '2014-05-14 20:25:12.279667')),
      t AS (SELECT token FROM session, d WHERE token=t),
      i AS (INSERT INTO session (token, expiry) 
               SELECT t, e FROM d WHERE t NOT IN (SELECT token FROM t))
    SELECT t,e FROM d WHERE t IN (SELECT token FROM t);
    

    查询首先使用您要插入的数据创建一个 CTE d

    然后它使用会话中的令牌创建一个 CTE t,与 d 中的令牌匹配(如果不匹配,则为空)。

    然后它使用 CTE id 中的行插入 t 中没有匹配的行到 session.

    如果在 t 中确实有匹配项,它最后会返回来自 d 的行。

    顺便说一句,这也适用于多行。

    【讨论】:

      猜你喜欢
      • 2013-06-18
      • 1970-01-01
      • 2013-08-14
      • 2013-02-18
      • 2011-05-03
      • 2014-11-29
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      相关资源
      最近更新 更多