Quando usei esta consulta para ver a semente de chave primária atual da minha tabela PostgreSQL 13:
select CURRVAL(pg_get_serial_sequence('rss_sub_source', 'id'))
disse-me:
SQL Error [55000]: ERROR: currval of sequence "rss_sub_source_id_seq" is not yet defined in this session
A id
coluna é definida assim:
ALTER TABLE rss_sub_source
ALTER id SET NOT NULL, -- optional
ALTER id ADD GENERATED ALWAYS AS IDENTITY
(START WITH 1233);
Definição da tabela:
CREATE TABLE public.rss_sub_source (
id int8 NOT NULL GENERATED ALWAYS AS IDENTITY,
sub_url varchar NOT NULL,
created_time int8 NOT NULL DEFAULT date_part('epoch'::text, now()),
-- ... many more columns
CONSTRAINT rss_sub_source_pkey PRIMARY KEY (id),
CONSTRAINT unique_sub_url UNIQUE (sub_url)
);
Como ver a semente de incremento automático atual para a chave primária?
As funções
currval(regclass)
elastval()
só fazem sentido depoisnextval()
de terem sido usadas na mesma sessão (não transação!). O controle de simultaneidade no PostgreSQL é a razão por trás desse comportamento.Se você está apenas curioso sobre o estado atual da sequência (não o último ID serial realmente usado na sessão), você pode sempre chamar
nextval()
:Retorna o próximo ID serial, que ainda não foi usado. Isso traz a falha de realmente consumir o ID retornado (o que não deve importar em um design relacional adequado). Mas esse efeito colateral pode ser evitado. No Postgres,
serial
e asIDENTITY
colunas são implementadas usando umSEQUENCE
internamente, que é um objeto semelhante a uma tabela que pode ser consultado como uma tabela. Se você está curioso sobre o estado atual de umSEQUENCE
, basta usarSELECT
:(Requer o
SELECT
privilégio na seqüência, enquanto as funções de seqüência mencionadas acima requerem oUSAGE
privilégio.)Você precisa saber o nome da seqüência para isso, e você já sabe como obtê-lo:
pg_get_serial_sequence('rss_sub_source', 'id')
. Também é fácil adivinhar. Ver:Para uso ad-hoc, basta compilar a consulta manualmente. Ou você pode usar
\gexec
no psql:Ver:
Para uso automatizado (ou regular), você precisa de SQL dinâmico para usar o valor de texto retornado pela função como identificador SQL. Aqui está uma função personalizada simples para fazer isso. Também fatorado em
is_called
:Ligar:
Isso é seguro contra SQLi porque
pg_get_serial_sequence()
retorna o identificador com segurança entre aspas duplas conforme necessário.A função retorna o último valor que foi consumido dessa sequência. (Não significa que tenha entrado na mesa.) O próximo será maior. (Assume uma sequência padrão com
INCREMENT
1!)Não consome um serial ID e não requer que
nextval()
tenha sido chamado na mesma sessão.Considere esta demonstração:
db<>fiddle aqui
Normalmente você quer o valor da sequência de valor que você acabou de gerar, ou faz com que seja gerado, e então usar lastval é o caminho certo para obtê-lo, mas você precisa ter provocado uma chamada nextval para fornecer um valor para lastval.
Se por algum motivo você não precisa saber esse valor. mas só quero algum valor recente, possivelmente de outra sessão ou até mesmo de uma transação que foi revertida.
select * from rss_sub_source_id_seq;
Fornecerá algumas informações sobre o estado atual da sequência sem avançá-la.
invoque nextval primeiro:
então pode usar este comando: