No PostgreSQL, como obtenho o último ID inserido em uma tabela?
No MS SQL, há SCOPE_IDENTITY ().
Por favor, não me aconselhe a usar algo como isto:
select max(id) from table
postgresql
insert
lastinsertid
Anton
fonte
fonte
Respostas:
(
tl;dr
: goto opção 3: INSERT com RETURNING)Lembre-se de que no postgresql não existe um conceito de "id" para tabelas, apenas seqüências (que geralmente são usadas, mas não necessariamente, como valores padrão para chaves primárias substitutas, com o pseudo-tipo SERIAL ).
Se você estiver interessado em obter o ID de uma linha recém-inserida, há várias maneiras:
Opção 1:
CURRVAL(<sequence name>);
.Por exemplo:
O nome da sequência deve ser conhecido, é realmente arbitrário; neste exemplo, assumimos que a tabela
persons
tenha umaid
coluna criada com oSERIAL
pseudo-tipo. Para evitar confiar nisso e se sentir mais limpo, você pode usarpg_get_serial_sequence
:Advertência:
currval()
só funciona após umINSERT
(que foi executadonextval()
), na mesma sessão .Opção 2:
LASTVAL();
Isso é semelhante ao anterior, mas você não precisa especificar o nome da sequência: ele procura a sequência modificada mais recente (sempre dentro da sua sessão, a mesma ressalva acima).
Ambos
CURRVAL
eLASTVAL
são totalmente simultâneos seguros. O comportamento da sequência no PG é projetado para que uma sessão diferente não interfira, portanto não há risco de condições de corrida (se outra sessão inserir outra linha entre o meu INSERT e meu SELECT, ainda assim recebo meu valor correto).No entanto, eles têm um problema potencial sutil. Se o banco de dados tiver algum TRIGGER (ou RULE) que, ao ser inserido na
persons
tabela, faça algumas inserções extras em outras tabelas ...LASTVAL
provavelmente nos fornecerá o valor errado. O problema pode até acontecerCURRVAL
se as inserções extras forem feitas na mesmapersons
tabela (isso é muito menos usual, mas o risco ainda existe).Opção 3:
INSERT
comRETURNING
Essa é a maneira mais limpa, eficiente e segura de obter o ID. Não tem nenhum dos riscos do anterior.
Desvantagens? Quase nenhum: você pode precisar modificar a maneira como chama sua instrução INSERT (na pior das hipóteses, talvez sua camada API ou DB não espere que uma INSERT retorne um valor); não é SQL padrão (quem se importa); está disponível desde o Postgresql 8.2 (dez 2006 ...)
Conclusão: Se puder, vá para a opção 3. Em outros lugares, prefira 1.
Nota: todos esses métodos são inúteis se você pretende obter o último ID inserido globalmente (não necessariamente pela sua sessão). Para isso, você deve recorrer a
SELECT max(id) FROM table
(é claro, isso não lerá inserções não confirmadas de outras transações).Por outro lado, você nunca deve usar
SELECT max(id) FROM table
uma das três opções acima para obter o ID gerado apenas por suaINSERT
declaração, porque (além do desempenho) isso não é seguro simultaneamente: entre vocêINSERT
e suaSELECT
outra sessão pode ter inserido outro registro.fonte
SELECT max(id)
infelizmente não faz o trabalho assim que você começa a excluir linhas.1,2,3,4,5
e excluir as linhas 4 e 5, o último ID inserido ainda é 5, masmax()
retorna 3.RETURNING id;
para inserir isso em outra tabela seria bem-vinda!RETURNING id
dentro de um script SQL alimentado para apsql
ferramenta de linha de comando?Consulte a cláusula RETURNING da instrução INSERT . Basicamente, o INSERT funciona como uma consulta e devolve o valor que foi inserido.
fonte
insert into names (firstname, lastname) values ('john', 'smith') returning id;
, então ele simplesmente saídas id como se você correuselect id from names where id=$lastid
diretamente. Se você deseja salvar o retorno em uma variável ,insert into names (firstname, lastname) values ('john', 'smith') returning id into other_variable;
se a declaração que contém o retorno é a última em uma função , o ID sendoreturning
retornado é retornado pela função como um todo.você pode usar a cláusula RETURNING na instrução INSERT, da seguinte maneira
fonte
A resposta de Leonbloy é bastante completa. Eu acrescentaria apenas o caso especial em que é necessário obter o último valor inserido de uma função PL / pgSQL em que a OPÇÃO 3 não se encaixa exatamente.
Por exemplo, se tivermos as seguintes tabelas:
Se precisarmos inserir um registro de cliente, devemos nos referir a um registro de pessoa. Mas digamos que desejamos criar uma função PL / pgSQL que insira um novo registro no cliente, mas também cuide da inserção do novo registro de pessoa. Para isso, devemos usar uma pequena variação da OPÇÃO 3 de leonbloy:
Observe que existem duas cláusulas INTO. Portanto, a função PL / pgSQL seria definida como:
Agora podemos inserir os novos dados usando:
ou
E obtemos o ID recém-criado.
fonte
Para aqueles que precisam obter o registro de todos os dados, você pode adicionar
até o final da sua consulta para obter o objeto all, incluindo o ID.
fonte
Veja o exemplo abaixo
Para obter o último ID inserido, use-o na tabela "user" seq nome da coluna "id"
fonte
Você precisa fornecer o nome da tabela e o nome da coluna, é claro.
Isso será para a sessão / conexão atual http://www.postgresql.org/docs/8.3/static/functions-sequence.html
fonte
Tente o seguinte:
Se isso retornar 1 (ou qualquer que seja o valor inicial da sua sequência), redefina a sequência novamente para o valor original, passando o sinalizador falso:
De outra forma,
Isso restaurará o valor da sequência para o estado original e "setval" retornará com o valor da sequência que você está procurando.
fonte
O Postgres possui um mecanismo embutido para o mesmo, que na mesma consulta retorna o ID ou o que você deseja que a consulta retorne. aqui está um exemplo. Considere que você criou uma tabela que possui 2 colunas column1 e column2 e deseja que a coluna1 seja retornada após cada inserção.
fonte
Eu tive esse problema com Java e Postgres. Corrigi-o atualizando uma nova versão do Connector-J.
postgresql-9.2-1002.jdbc4.jar
https://jdbc.postgresql.org/download.html : Versão 42.2.12
https://jdbc.postgresql.org/download/postgresql-42.2.12.jar
fonte