2016-02-28 6 views
2

Я написал запрос для моего API, где я должен вернуть , если ресурс не находится в допустимом состоянии для запроса или not found, если ресурс не существует.SQL UPDATE: return, если строка обновлена ​​и существует

Я не хочу отправлять 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 отличаются.

+0

Довольно умный. Также я не знал, что вы можете использовать FROM после утверждения обновления! –