我为我的API写了一个查询,如果资源不是请求的有效状态,我必须返回conflict
,如果资源不存在,我必须返回not found
。
我不想向数据库发送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
可以在status
之前提供原始UPDATE
,我就会知道你可以这样做。这是不可能的,但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
列会有所不同。