Se può esserci un accesso in scrittura simultaneo alle tabelle coinvolte, ci sono condizioni di competizione nelle seguenti query. Considera:
Il tuo esempio può usa un CTE (espressione di tabella comune), ma non ti darà nulla che una sottoquery non potrebbe fare:
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.*;
La riga restituita sarà quella aggiornata versione.
Se vuoi inserire la riga restituita in un'altra tabella, ecco dove un WITH
la clausola diventa essenziale:
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;
Le query di modifica dei dati che utilizzano CTE sono state aggiunte con PostgreSQL 9.1.
Il manuale su WITH
query (CTE).