回答

收藏

Postgres:如果没有,插入,否则返回

技术问答 技术问答 277 人阅读 | 0 人回复 | 2023-09-14

在一个SQL在句子中,我试着插入一行。如果我因为约束而失败,我会回到现有的行。3 h% M$ W& n6 U# J
我有:
7 W% R2 x  `4 s" H, @+ }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 *最后加,但还是不回现有行。
( K, [' ^' j" B, b0 z8 A为什么会这样?我以为我的最后一个SELECT句子将被执行并返回。你有什么想法吗?1 y* ?, C, B1 `. f" X& S3 O
注:由于一些复杂的竞争条件,我不能使用它Postgres函数或多个SQL语句。8 c5 p( A, {+ K
                                                               
. i3 t8 R7 k: D' ^# z    解决方案:                                                                , M5 w1 Q  R  k( r' B
                                                                WITH d(t,e) AS ( VALUES (‘abcdefg’,‘2014-05-14 20:25:12.279667’)),8 K$ n/ f; ]# I1 h
                        t AS (SELECT token FROM session,d WHERE token=t),
6 J( o% `" s. i5 w+ i* J                        i AS (INSERT INTO session (token,expiry) ( i, E9 x1 b0 i9 Z6 g+ A- H
                                                            SELECT t,e FROM d WHERE t NOT IN (SELECT token FROM t))
* {) C$ F8 Y1 l* T; y) U                SELECT t,e FROM d WHERE t IN (SELECT token FROM t);
3 `. K" ?9 a3 ~5 x+ Z首先,使用您想要插入的数据进行查询CTE d; a: k( u; M% L: {4 S
然后,它使用会话中的令牌和 d*    创建令牌匹配(如果不匹配,则为空)CTE t    。*3 B+ P8 a' G1 M+ `; b
如果它在 t中*    如果没有匹配项,则使用CTE i    将 d中    的行插入到 session中    。    ***7 Y. |+ j) `! A6 E8 V9 ^" E, Q; y. t
最后,如果是 t中*    有匹配项,则从 d    返回行。*" s! w! R, X( V$ _9 V8 z: n
对了,这也适用于多行。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则