Un moyen de référencer l'ID dans une transaction multi-insert? (postgres)

8

En supposant que la table "entity.eid" est incrémentée automatiquement, je veux pouvoir faire référence à la valeur d'auto-incrémentation attribuée plus tard dans la même transaction. J'ai fait cela en effectuant plusieurs transactions qui, à mon avis, ne sont pas optimales.

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

Réponses:

11

il y a différentes facons de faire cela.

La manière la plus simple est d'utiliser la lastval()fonction qui retournera la valeur générée par la "dernière" séquence nextval.

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

Si vous connaissez le nom de la séquence de la entitytable, vous pouvez également utiliser la currvalfonction:

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

Cela peut être écrit d'une manière plus générale en utilisant la pg_get_serial_sequence()fonction, en évitant de coder en dur le nom de la séquence:

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

Pour plus de détails, veuillez consulter le manuel: http://www.postgresql.org/docs/current/static/functions-sequence.html

un cheval sans nom
la source
7

Vous ne spécifiez pas votre version Postgresql, mais si vous utilisez 8.4+, vous pouvez utiliser la RETURNINGclause pour renvoyer l'identifiant (ou n'importe quelle colonne) qui vient d'être inséré.

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

Exemple:

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

Si vous utilisez Postgresql version 9.1+, vous pouvez également utiliser des WITHclauses (aka Common Table Expressions) pour effectuer l'insertion dans une clause, puis référencer les valeurs de la RETURNINGclause pour effectuer plus d'actions (les clauses WITH peuvent s'enchaîner).

Documents sur la WITHclause: http://www.postgresql.org/docs/current/static/queries-with.html

bma
la source
4

Il est à noter que SERIAL dans Postgres est juste un INT avec une SEQUENCE comme valeur par défaut, vous pouvez facilement interroger le séquenceur vous-même dans une transaction au lieu de l'insérer dans le tableau permettant à la valeur par défaut de se produire.

xénoterracide
la source