Si potrebbe utilizzare una sottoquery o un CTE scrivibile per recuperare il valore dalla sequenza volta e utilizzarlo ripetutamente:
WITH i AS (
SELECT nextval('foo_id_seq') AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM i;
Data-modifying CTE richiede Postgres 9.1 o successivo.
Se non si è sicuri circa il nome della sequenza è possibile utilizzare pg_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 tutto lo schema nel DB, è possibile schema -equalizzarlo E se l'ortografia di qualsiasi nome è non standard, è necessario fare doppio citazione:
pg_get_serial_sequence('"My_odd_Schema".foo', 'id')
test rapidi indicati @Mark's idea con lastval()
poteva lavoro troppo:
INSERT INTO foo (ltree) VALUES ('1.' || lastval());
Puoi lasciare id
fuori dalla query, la colonna serial
verrà assegnata automaticamente. Non fa differenza.
Non dovrebbe esserci una condizione di competizione tra le file. I quote the manual:
currval
Return the value most recently obtained by nextval for this sequence in the current session. (An error is reported if nextval has never been called for this sequence in this session.) Because this is returning a session-local value, it gives a predictable answer whether or not other sessions have executed nextval since the current session did.
lastval
Return the value most recently returned by nextval in the current session. This function is identical to currval, except that instead of taking the sequence name as an argument it fetches the value of the last sequence used by nextval in the current session. It is an error to call lastval if nextval has not yet been called in the current session.
Bold sottolineatura mia.
Ma, come @Bernard commented, può fallire dopo tutto.A pensarci bene, questo ha senso: non vi è alcuna garanzia che il valore predefinito sia riempito (e nextval()
chiamato nel processo) prima dellastval()
viene chiamato per riempire la 2a colonna ltree
. Quindi attenersi alla prima soluzione e nextval()
per essere sicuro.
Quella strada non sembra molto queryable .. –
miei valori del percorso si basano su questo: http://stackoverflow.com/a/607379/39529 –
PostgreSQL ha ricorsione, espressione di tabella comune, molto più facile e più veloce di la soluzione del tuo percorso/soluzione alternativa. –