Uma maneira de referenciar o ID em uma transação de inserção múltipla? (postgres)


8

Supondo que a tabela "entity.eid" seja incrementada automaticamente, desejo poder fazer referência ao valor de incremento automático atribuído posteriormente na mesma transação. O jeito que eu tenho feito isso é fazendo várias transações, o que eu acho que não é o ideal.

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

Respostas:


11

Existem diferentes maneiras de fazer isso.

A maneira mais fácil é usar a lastval()função que retornará o valor gerado pela "última" sequência nextval.

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

Se você souber o nome da sequência para a entitytabela, também poderá usar a currvalfunção:

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

Isso pode ser escrito de uma maneira mais geral, usando a pg_get_serial_sequence()função, evitando codificar o nome da sequência:

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

Para mais detalhes, consulte o manual: http://www.postgresql.org/docs/current/static/functions-sequence.html


7

Você não especifica sua versão do Postgresql, mas se estiver usando o 8.4+, poderá usar a RETURNINGcláusula para retornar o ID (ou qualquer coluna) que acabou de ser inserido.

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

Exemplo:

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

Se você estiver usando o Postgresql versão 9.1+, também poderá usar as WITHcláusulas (aka Common Table Expressions) para inserir uma cláusula, em seguida, referenciar os valores da RETURNINGcláusula para executar mais ações (as cláusulas WITH podem ser encadeadas).

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


4

Vale a pena notar que SERIAL no Postgres é apenas uma INT com uma SEQUENCE como o valor padrão; você pode facilmente consultar o seqüenciador em uma transação, em vez de inserir na tabela permitindo que o padrão aconteça.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.