Postgres:如果不存在则插入,否则返回该行

时间:2014-05-09 20:54:57

标签: sql postgresql

在一个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语句。

1 个答案:

答案 0 :(得分:3)

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

然后它会使会话中的令牌与 d 中的令牌匹配(或者如果不匹配则为空),则会使CTE t

然后使用CTE i d 中的行插入 t 会话 >

最后,如果确实在 t 中匹配,则返回 d 中的行。

BTW这也适用于多行。