È possibile utilizzare un CTE per recuperare il valore dalla sequenza una volta e usalo ripetutamente :
WITH cte AS (
SELECT nextval('foo_id_seq') AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM cte;
Il CTE con un comando di modifica dei dati richiede Postgres 9.1 o successivo.
Se non sei sicuro del nome della sequenza, usapg_get_serial_sequence() invece:
WITH i AS (
SELECT nextval(pg_get_serial_sequence('foo', 'id')) AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM i;
Se il nome della tabella "foo" potrebbe non essere univoco in tutti gli schemi nel database, qualificalo per lo schema. E se l'ortografia di un nome non è standard, devi virgolette:
pg_get_serial_sequence('"My_odd_Schema".foo', 'id')
Test rapidi hanno indicato l'idea di @Mark con lastval() potrebbe lavora anche tu:
INSERT INTO foo (ltree) VALUES ('1.' || lastval());
-
Puoi semplicemente lasciare
idfuori dalla query, ilserialla colonna verrà assegnata automaticamente. Non fa differenza. -
Non dovrebbe esserci una race condition tra le righe. Cito il manuale:
currval
Restituisce il valore ottenuto più di recente da nextval per questa sequenza nella sessione corrente. (Viene segnalato un errore se nextval non è mai stato chiamato per questa sequenza in questa sessione.) Poiché restituisce un valore locale della sessione, fornisce una risposta prevedibile indipendentemente dal fatto che altre sessioni abbiano eseguito o meno nextval dalla sessione corrente.
Questa funzione richiede USAGE o SELECT privilegio sulla sequenza.
lastval
Restituisce l'ultimo valore restituito da nextval nella sessione corrente. Questa funzione è identica a currval , tranne che invece di prendere il nome della sequenza come argomento si riferisce a qualesequenza nextval è stato applicato più di recente nella sessione corrente. È un errore chiamare lastval se nextval non è stato ancora chiamato nella sessione corrente.
Questa funzione richiede USAGE o SELECT privilegio sull'ultima sequenza utilizzata.
Enfasi in grassetto la mia.
Ma , come ha commentato @Bernard, dopotutto può fallire:non vi è alcuna garanzia che il valore predefinito sia riempito (e nextval() chiamato nel processo) prima lastval() viene chiamato per riempire la seconda colonna ltree . Quindi attieniti alla prima soluzione e nextval() certo.