Eu tenho uma tabela que é criada desta maneira:
--
-- Table: #__content
--
CREATE TABLE "jos_content" (
"id" serial NOT NULL,
"asset_id" bigint DEFAULT 0 NOT NULL,
...
"xreference" varchar(50) DEFAULT '' NOT NULL,
PRIMARY KEY ("id")
);
Posteriormente, algumas linhas são inseridas especificando o ID:
INSERT INTO "jos_content" VALUES (1,36,'About',...)
Em um ponto mais tarde alguns registros são inseridos sem ID e eles falhar com o erro:
Error: duplicate key value violates unique constraint
.
Aparentemente, o id foi definido como uma sequência:
Cada inserção com falha aumenta o ponteiro na sequência até aumentar para um valor que não existe mais e as consultas tiverem êxito.
SELECT nextval('jos_content_id_seq'::regclass)
O que há de errado com a definição da tabela? Qual é a maneira inteligente de corrigir isso?
postgresql
database-design
insert
auto-increment
sequence
Valentin Despa
fonte
fonte
Respostas:
Nada está errado com sua definição de tabela.
(Exceto o chapéu que eu usaria
jos_content_id
ou algo assim, em vez do nome não descritivo da colunaid
.E provavelmente usaria em
text
vez devarchar(50)
.Sua
INSERT
afirmação é o problema.Com sua
id
coluna definida comoserial
, você não deve inserir valores manuais paraid
. Aqueles podem colidir com o próximo valor da sequência associada.Forneça uma lista explícita de colunas de destino (o que quase sempre é uma boa idéia para
INSERT
instruções persistentes ) e omita completamente as colunas seriais .Se você precisar dos valores das colunas geradas automaticamente imediatamente, use a
RETURNING
cláusula :Mais detalhes nesta resposta relacionada ao SO:
Se você tiver entradas manuais em
serial
colunas que podem entrar em conflito posteriormente, configure sua sequência para o máximo atualid
para corrigir isso uma vez :Onde
jos_content_id_seq
é o nome padrão para uma sequência de propriedadejos_content.id
, que você já encontrou na coluna padrão. Parece estarxhzt8_content_id_seq
no seu caso;Atualização: Um problema semelhante apareceu no SO e eu vim com uma nova solução:
fonte