È 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
id
fuori dalla query, ilserial
la 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.