2016-02-28 100 views
2

我为我的API编写了查询,如果资源不处于请求的有效状态,则必须返回,如果资源不存在,则返回not foundSQL更新:如果行已更新并且存在,则返回

我不想向数据库发送2个查询(以检查资源是否先存在,然后更新它)。因为只是检查行是否更新是不够的,也许资源不存在。

我总想返回行看起来是这样的:

exists | updated 
--------+--------- 
t  | t 
(1 row) 

我查询的工作,我只是不知道是否有一个简单的方法来...

WITH updates AS (
    UPDATE abc 
    SET status = 'cancelled' 
    WHERE id = $1 AND status = 'active' RETURNING 1 
) 
SELECT 
    EXISTS(SELECT 1 FROM abc WHERE id = $1) as exists, 
    EXISTS(SELECT 1 FROM updates) as updated 
+0

你的方法看起来不错。 –

回答

3

它发生,我认为你可以这样做,如果只有RETURNING可以在UPDATE之前提供原始status。这是不可能的,但another question指出了一个诀窍:加入到同一张表的另一个副本,并返回其他表的列!

因此,这将出现在您的情况下工作:

UPDATE t 
SET  status = (CASE WHEN t.status = 'active' THEN 'canceled' ELSE t.status END) 
FROM t AS t2 
WHERE t.id = t2.id 
AND  t.id = 1 
RETURNING t.id, t.status, t2.status 
; 

当然,你可以调整该RETURNING给更具描述性的,例如CASE WHEN t2.status = 'active' THEN 'updated' ELSE 'invalid' END),但我展示了如何在这里返回所有“有趣”的值来证明什么是可能的。因此:如果缺少id,则不会得到结果。如果id存在但已经是非active,则两个status列匹配。如果更新,则status列有所不同。

+0

很聪明。此外,我不知道你可以在更新声明后使用FROM! –

相关问题