Eu tenho uma mesa:
CREATE TABLE names (id serial, name varchar(20))
Eu quero o "último ID inserido" dessa tabela, sem usar RETURNING id
na inserção. Parece haver uma função CURRVAL()
, mas não entendo como usá-la.
Eu tentei com:
SELECT CURRVAL() AS id FROM names_id_seq
SELECT CURRVAL('names_id_seq')
SELECT CURRVAL('names_id_seq'::regclass)
mas nenhum deles funciona. Como posso usar currval()
para obter o último ID inserido?
postgresql
sequence
Jonas
fonte
fonte
currval()
Definitivamente, o uso de não é desencorajado.Respostas:
Se você criar uma coluna, o
serial
PostgreSQL criará automaticamente uma sequência para isso.O nome da sequência é gerado automaticamente e sempre é tablename_columnname_seq; no seu caso, a sequência será nomes
names_id_seq
.Depois de inserir na tabela, você pode chamar
currval()
com esse nome de sequência:Em vez de codificar o nome da sequência, você também pode usar
pg_get_serial_sequence()
:Dessa forma, você não precisa confiar na estratégia de nomes que o Postgres usa.
Ou, se você não quiser usar o nome da sequência, use
lastval()
fonte
currval()
em uma configuração multiusuário. Por exemplo, em um servidor da web.currval()
é "local" para sua conexão atual. Portanto, não há problema em usá-lo em um ambiente multiusuário. Esse é o objetivo de uma sequência.Isso é direto do Stack Overflow
Como foi apontado por @a_horse_with_no_name e @Jack Douglas, o currval funciona apenas com a sessão atual. Portanto, se você concorda com o fato de que o resultado pode ser afetado por uma transação não confirmada de outra sessão e ainda deseja algo que funcione entre as sessões, você pode usar o seguinte:
Use o link para SO para obter mais informações.
A partir da documentação do Postgres , é claramente afirmado que
Então, eu acho que, estritamente falando, para usar corretamente currval ou last_value para uma sequência entre sessões, você precisaria fazer algo assim?
Supondo, é claro, que você não terá uma inserção ou qualquer outra maneira de usar o campo serial na sessão atual.
fonte
nextval()
é necessário definir manualmente a sequência para corresponder ao número de registros de fixação que você inseriu com os IDs codificados. Além disso, a maneira de resolver o problema de currval () / lastval () não estar disponível pré-nextval é apenasSELECT
na sequência diretamente.Você precisa chamar
nextval
essa sequência nesta sessão antes decurrval
:portanto, você não pode encontrar o 'último ID inserido' da sequência, a menos que isso
insert
seja feito na mesma sessão (uma transação pode reverter, mas a sequência não)como apontado na resposta de a_horse,
create table
com uma coluna do tiposerial
criará automaticamente uma sequência e a usará para gerar o valor padrão da coluna; portanto, uminsert
normalmente acessanextval
implicitamente:fonte
Portanto, existem alguns problemas com esses vários métodos:
Currval obtém apenas o último valor gerado na sessão atual - o que é ótimo se você não tiver mais nada gerando valores, mas nos casos em que você pode chamar um gatilho e / ou ter a sequência avançada mais de uma vez na transação atual, é não retornará o valor correto. Isso não é um problema para 99% das pessoas por aí - mas é algo que se deve levar em consideração.
A melhor maneira de obter o identificador exclusivo atribuído após uma operação de inserção é usando a cláusula RETURNING. O exemplo abaixo assume que a coluna vinculada à sequência é chamada "id":
Observe que a utilidade da cláusula RETURNING vai muito além de apenas obter a sequência, pois ela também:
Retorne os valores que estavam sendo excluídos:
excluir da tabela A onde id> 100 retornando *
Retorne as linhas modificadas após um UPDATE:
atualizar tabela Um conjunto X = 'y' onde blah = 'blech' retornando *
Use o resultado de uma exclusão para uma atualização:
WITH A como (excluir * da tabela A como id de retorno) atualização B set delete = true onde id (selecione id de A);
fonte
RETURNING
cláusula - mas não há nada errado em tornar os benefícios de usá-la mais clara para os outros.Eu tive que executar uma consulta, apesar de usar SQLALchemy, porque não tive sucesso usando currval.
Este foi um projeto python flask + postgresql.
fonte
Se você deseja obter o valor das seqüências sem ter chamado
nextval()
e sem precisar modificar a sequência, juntei uma função PL / pgSQL para lidar com isso: Encontre o valor de todas as sequências do banco de dadosfonte
Você precisa
GRANT
usar no esquema, assim:e
fonte
currval()
função para torná-la um pouco mais relevante para esse segmento.No PostgreSQL 11.2, você pode tratar a sequência como uma tabela:
Exemplo se você tiver uma sequência chamada: 'names_id_seq'
Isso deve fornecer o último ID inserido (4 neste caso), o que significa que o valor atual (ou o valor que deve ser usado para o próximo ID) deve ser 5.
fonte
Versões diferentes do PostgreSQL podem ter funções diferentes para obter o ID da sequência atual ou a próxima.
Primeiro, você precisa conhecer a versão do seu Postgres. Usando a versão selecionada (); para obter a versão.
No PostgreSQL 8.2.15, você obtém o ID da sequência atual usando
select last_value from schemaName.sequence_name
.Se a declaração acima não funcionar, você pode usar
select currval('schemaName.sequence_name');
fonte