sql >> Base de Datos >  >> RDS >> PostgreSQL

Valor de referencia de la columna serial en otra columna durante el mismo INSERTAR

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, el serial 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.