S'il peut y avoir un accès en écriture simultané aux tables impliquées, il existe des conditions de concurrence dans les requêtes suivantes. Considérez :
Votre exemple peut utilisez une CTE (expression de table commune), mais cela ne vous donnera rien qu'une sous-requête ne puisse faire :
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 ligne retournée sera la mise à jour version.
Si vous voulez insérer la ligne retournée dans une autre table, c'est là qu'un WITH
clause devient indispensable :
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;
Des requêtes de modification de données utilisant des CTE ont été ajoutées avec PostgreSQL 9.1.
Le manuel sur WITH
requêtes (CTE).