Eu tenho uma pequena tabela (~ 30 linhas) em meu banco de dados Postgres 9.0 com um campo de ID de inteiro (a chave primária) que atualmente contém inteiros sequenciais únicos começando em 1, mas que não foi criado usando a palavra-chave 'serial'.
Como posso alterar esta tabela de modo que a partir de agora inserções nesta tabela façam com que este campo se comporte como se tivesse sido criado com 'serial' como um tipo?
postgresql
nicolaskruchten
fonte
fonte
SERIAL
pseudo-tipo agora é legado , suplantado pelo novoGENERATED … AS IDENTITY
recurso definido no SQL: 2003 , no Postgres 10 e posterior. Veja a explicação .Respostas:
Observe os seguintes comandos (especialmente o bloco comentado).
fonte
ALTER TABLE foo ADD PRIMARY KEY (a)
.ALTER TABLE foo OWNER TO current_user;
primeiro.MAX(a)+1
em setval?SELECT MAX(a)+1 FROM foo; SELECT setval('foo_a_seq', 6);
Você também pode usar
START WITH
para iniciar uma sequência a partir de um ponto específico, embora setval realize a mesma coisa, como na resposta de Euler, por exemplo,fonte
TL; DR
Aqui está uma versão em que você não precisa de um ser humano para ler um valor e digitá-lo por conta própria.
Outra opção seria empregar o reaproveitável
Function
compartilhado ao final desta resposta.Uma solução não interativa
Apenas adicionando as outras duas respostas, para aqueles de nós que precisam ter esses
Sequence
s criados por um script não interativo , enquanto corrige um banco de dados live-ish, por exemplo.Isto é, quando você não quer
SELECT
o valor manualmente e o digita em umaCREATE
instrução subsequente .Resumindo, você não pode fazer:
... já que a
START [WITH]
cláusula emCREATE SEQUENCE
espera um valor , não uma subconsulta.No entanto,
setval()
sim! Portanto, o seguinte está absolutamente correto:Se não houver dados e você não (quiser) saber sobre eles, use
coalesce()
para definir o valor padrão:No entanto, ter o valor da sequência atual definido como
0
é desajeitado, se não ilegal.Usar a forma de três parâmetros de
setval
seria mais apropriado:Definir o terceiro parâmetro opcional de
setval
parafalse
evitará que o próximonextval
avance na sequência antes de retornar um valor e, portanto:- desta entrada na documentação
Em uma nota não relacionada, você também pode especificar a coluna proprietária de
Sequence
diretamente comCREATE
, você não precisa alterá-la mais tarde:Em suma:
Usando um
Function
Como alternativa, se você planeja fazer isso para várias colunas, pode optar por usar um real
Function
.Use-o assim:
fonte
coalesce(max(a), 0))
que não funcionará na maioria das vezes, já que os IDs geralmente começam em 1. A maneira mais correta seriacoalesce(max(a), 1))
setval
função, na verdade, define apenas o "último valor usado" atual para a sequência. O próximo valor disponível (o primeiro a ser realmente usado) será mais um! Usarsetval(..., coalesce(max(a), 1))
em uma coluna vazia configuraria para "começar" com2
(o próximo valor disponível), conforme ilustrado na documentação .currval
nunca deveria haver0
, mesmo que não fosse refletido no conjunto de dados real. Usando o formulário três parâmetros desetval
seria mais apropriado:setval(..., coalesce(max(a), 0) + 1, false)
. Resposta atualizada em conformidade!