PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Valor de referência da coluna serial em outra coluna durante o mesmo INSERT


Você pode usar um CTE para recuperar o valor da sequência uma vez e usá-lo repetidamente :
WITH cte AS (
   SELECT nextval('foo_id_seq') AS id
   )
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM   cte;

O CTE com um comando de modificação de dados requer o Postgres 9.1 ou posterior.

Se você não tiver certeza sobre o nome da sequência, use pg_get_serial_sequence() em vez de:
WITH i AS (
   SELECT nextval(pg_get_serial_sequence('foo', 'id')) AS id
   )
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM   i;

Se o nome da tabela "foo" não for exclusivo em todos os esquemas no banco de dados, qualifique-o pelo esquema. E se a ortografia de qualquer nome não for padrão, você deve usar aspas duplas:
pg_get_serial_sequence('"My_odd_Schema".foo', 'id')




Testes rápidos indicaram a ideia de @Mark com lastval() pode trabalhar também:
INSERT INTO foo (ltree) VALUES ('1.' || lastval());

  • Você pode simplesmente deixar id fora da consulta, o serial coluna será atribuída automaticamente. Não faz diferença.

  • Não deve haver uma condição de corrida entre as linhas. Cito o manual:

currval

Retorna o valor obtido mais recentemente por nextval para esta sequência na sessão atual. (Um erro é relatado se nextval nunca foi chamado para esta sequência nesta sessão.) Como isso está retornando um valor de sessão local, ele fornece uma resposta previsível se outras sessões executaram ou não nextval desde a sessão atual.

Esta função requer USAGE ou SELECT privilégio na sequência.

lastval

Retorna o valor retornado mais recentemente por nextval na sessão atual. Esta função é idêntica a currval , exceto que ao invés de tomar o nome da sequência como um argumento ele se refere a qualquer sequência nextval foi aplicado mais recentemente na sessão atual. É um erro chamar lastval se nextval ainda não foi chamado na sessão atual.

Esta função requer USAGE ou SELECT privilégio na última sequência usada.

Minha ênfase em negrito.

Mas , como @Bernard comentou, ele pode falhar afinal:não há garantia de que o valor padrão seja preenchido (e nextval() chamado no processo) antes lastval() é chamado para preencher a 2ª coluna ltree . Então fique com a primeira solução e nextval() para ter certeza.