Un modo per fare riferimento all'ID in una transazione con più inserti? (Postgres)


8

Supponendo che la tabella "entity.eid" stia incrementando automaticamente, voglio poter fare riferimento al valore di incremento automatico assegnato successivamente nella stessa transazione. Il modo in cui l'ho fatto è fare più transazioni che non credo siano ottimali.

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

Risposte:


11

Esistono diversi modi per farlo.

Il modo più semplice è utilizzare la lastval()funzione che restituirà il valore generato dall'ultima "sequenza" del valore successivo.

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

Se conosci il nome della sequenza per la entitytabella puoi anche usare la currvalfunzione:

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

Questo può essere scritto in un modo più generale usando la pg_get_serial_sequence()funzione, evitando di codificare il nome della sequenza:

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

Per maggiori dettagli, consultare il manuale: http://www.postgresql.org/docs/current/static/functions-sequence.html


7

Non specifichi la tua versione di Postgresql, ma se stai usando 8.4+ puoi usare la RETURNINGclausola per restituire l'id (o qualsiasi colonna) appena inserita.

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

Esempio:

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

Se stai usando Postgresql versione 9.1+ puoi anche usare le WITHclausole (aka Common Table Expressions) per fare l'inserimento in una clausola, quindi fare riferimento ai valori della RETURNINGclausola per eseguire più azioni (le clausole WITH possono concatenarsi).

Documenti sulla WITHclausola: http://www.postgresql.org/docs/current/static/queries-with.html


4

Vale la pena notare che SERIAL in Postgres è solo un INT con una SEQUENZA come valore predefinito, puoi facilmente interrogare tu stesso il sequencer in una transazione invece di inserirlo nella tabella permettendo che avvenga il default.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.