在一个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
对了,这也适用于多行。