Se pode haver acesso simultâneo de gravação para tabelas envolvidas, há condições de corrida nas consultas a seguir. Considerar:
Seu exemplo pode use um CTE (expressão de tabela comum), mas não fornecerá nada que uma subconsulta não possa fazer:
WITH x AS (
SELECT psp_id
FROM global.prospect
WHERE status IN ('new', 'reset')
ORDER BY request_ts
LIMIT 1
)
UPDATE global.prospect psp
SET status = status || '*'
FROM x
WHERE psp.psp_id = x.psp_id
RETURNING psp.*;
A linha retornada será a atualizada versão.
Se você deseja inserir a linha retornada em outra tabela, é aí que um
WITH
cláusula torna-se essencial:WITH x AS (
SELECT psp_id
FROM global.prospect
WHERE status IN ('new', 'reset')
ORDER BY request_ts
LIMIT 1
)
, y AS (
UPDATE global.prospect psp
SET status = status || '*'
FROM x
WHERE psp.psp_id = x.psp_id
RETURNING psp.*
)
INSERT INTO z
SELECT *
FROM y;
As consultas de modificação de dados usando CTEs foram adicionadas com o PostgreSQL 9.1.
O manual sobre
WITH
consultas (CTEs).