¿Una forma de hacer referencia a la ID en una transacción de inserción múltiple? (postgres)

8

Suponiendo que la tabla "entity.eid" se incremente automáticamente, quiero poder hacer referencia al valor de incremento automático asignado más adelante en la misma transacción. La forma en que he estado haciendo esto es haciendo múltiples transacciones que creo que no son óptimas.

START TRANSACTION;
INSERT INTO entity ...;
INSERT INTO t2 (eid, ...) VALUES (?NEW EID REF HERE?, ...), (...), (...);
COMMIT;
Tony
fuente

Respuestas:

11

Hay maneras diferentes de hacer esto.

La forma más fácil es usar la lastval()función que devolverá el valor generado por la "última" secuencia nextval.

START TRANSACTION;
INSERT INTO entity ...;
INSERT INTO t2 (eid, ...) VALUES (lastval(), ...), (...), (...);
COMMIT;

Si conoce el nombre de la secuencia de la entitytabla, también puede usar la currvalfunción:

START TRANSACTION;
INSERT INTO entity ...;
INSERT INTO t2 (eid, ...) VALUES (currval('entity_eid_seq'), ...), (...), (...);
COMMIT;

Esto se puede escribir de una manera más general usando la pg_get_serial_sequence()función, evitando codificar el nombre de la secuencia:

START TRANSACTION;
INSERT INTO entity ...;
INSERT INTO t2 (eid, ...) VALUES (currval(pg_get_serial_sequence('entity', 'eid')), ...), (...);
COMMIT;

Para obtener más detalles, consulte el manual: http://www.postgresql.org/docs/current/static/functions-sequence.html

un caballo sin nombre
fuente
7

No especifica su versión de Postgresql, pero si está utilizando 8.4+ puede usar la RETURNINGcláusula para devolver la identificación (o cualquier columna) que acaba de insertar.

Documentos: http://www.postgresql.org/docs/current/static/sql-insert.html

Ejemplo:

INSERT INTO t2 (eid, ...) VALUES (...) RETURNING eid;

Si está utilizando Postgresql versión 9.1+, también puede usar WITHcláusulas (aka Common Table Expressions) para insertar en una cláusula, luego haga referencia a los valores de la RETURNINGcláusula para realizar más acciones (las cláusulas WITH pueden encadenarse).

Documentos sobre la WITHcláusula: http://www.postgresql.org/docs/current/static/queries-with.html

bma
fuente
4

Vale la pena señalar que SERIAL en Postgres es solo un INT con una SECUENCIA como valor predeterminado, puede consultar fácilmente el secuenciador usted mismo en una transacción en lugar de insertarlo en la tabla permitiendo que ocurra el valor predeterminado.

xenoterracida
fuente