Podría usar un CTE para recuperar el valor de la secuencia una vez y usarlo repetidamente :
WITH cte AS (
SELECT nextval('foo_id_seq') AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM cte;
El CTE con un comando de modificación de datos requiere Postgres 9.1 o posterior.
Si no está seguro del nombre de la secuencia, use pg_get_serial_sequence()
en cambio:
WITH i AS (
SELECT nextval(pg_get_serial_sequence('foo', 'id')) AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM i;
Si el nombre de la tabla "foo" puede no ser único en todos los esquemas de la base de datos, califique el esquema. Y si la ortografía de cualquier nombre no es estándar, debe escribir comillas dobles:
pg_get_serial_sequence('"My_odd_Schema".foo', 'id')
Las pruebas rápidas indicaron la idea de @Mark con lastval()
podría trabajar también:
INSERT INTO foo (ltree) VALUES ('1.' || lastval());
-
Puedes dejar
id
fuera de la consulta, elserial
la columna se asignará automáticamente. No hace ninguna diferencia. -
No debería haber una condición de carrera entre las filas. Cito el manual:
currval
Devuelve el valor obtenido más recientemente por nextval
para esta secuencia en la sesión actual. (Se informa un error si nextval
nunca ha sido llamado para esta secuencia en esta sesión.) Debido a que esto está devolviendo un valor local de sesión, da una respuesta predecible si otras sesiones han ejecutado o no nextval
desde la sesión actual.
Esta función requiere USAGE
o SELECT
privilegio en la secuencia.
lastval
Devuelve el valor devuelto más recientemente por nextval
en la sesión actual. Esta función es idéntica a currval
, excepto que en lugar de tomar el nombre de la secuencia como argumento, se refiere a la secuencia nextval
se aplicó más recientemente en la sesión actual. Es un error llamar a lastval
si nextval
aún no ha sido llamado en la sesión actual.
Esta función requiere USAGE
o SELECT
privilegio en la última secuencia utilizada.
Énfasis en negrita mío.
Pero , como comentó @Bernard, puede fallar después de todo:no hay garantía de que se complete el valor predeterminado (y nextval()
llamado en el proceso) antes lastval()
se llama para llenar la segunda columna ltree
. Así que quédese con la primera solución y nextval()
para estar seguro.