J'ai une table qui est créée de cette façon:
--
-- 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")
);
Plus tard, certaines lignes sont insérées en spécifiant l'id:
INSERT INTO "jos_content" VALUES (1,36,'About',...)
À un moment plus tard certains enregistrements sont insérés sans id et ils échouent avec l'erreur:
Error: duplicate key value violates unique constraint
.
Apparemment, l'id a été défini comme une séquence:
Chaque insertion ayant échoué augmente le pointeur dans la séquence jusqu'à ce qu'il augmente jusqu'à une valeur qui n'existe plus et que les requêtes réussissent.
SELECT nextval('jos_content_id_seq'::regclass)
Quel est le problème avec la définition de la table? Quelle est la manière intelligente de résoudre ce problème?
postgresql
database-design
insert
auto-increment
sequence
Valentin Despa
la source
la source
Réponses:
Rien ne va mal avec la définition de votre table.
(Sauf chapeau j'utiliser
jos_content_id
ou quelque chose au lieu du nom de la colonne non-descriptiveid
.Et je ne serais probablement utiliser au
text
lieu devarchar(50)
.Votre
INSERT
déclaration est le problème.Avec votre
id
colonne définie commeserial
, vous ne devez pas insérer de valeurs manuelles pourid
. Ceux-ci peuvent entrer en collision avec la valeur suivante de la séquence associée.Fournissez une liste explicite des colonnes cibles (ce qui est presque toujours une bonne idée pour les
INSERT
instructions persistantes ) et omettez complètement les colonnes série .Si vous avez immédiatement besoin de la ou des valeurs des colonnes générées automatiquement, utilisez la
RETURNING
clause :Plus de détails dans cette réponse connexe sur SO:
Si vous avez des entrées manuelles dans les
serial
colonnes qui pourraient entrer en conflit plus tard, définissez votre séquence au maximum actuelid
pour corriger cela une fois :Où
jos_content_id_seq
est le nom par défaut d'une séquence appartenant àjos_content.id
, que vous avez déjà trouvé dans la colonne par défaut. Semble êtrexhzt8_content_id_seq
dans votre cas;Mise à jour: Un problème similaire est apparu sur SO et j'ai trouvé une nouvelle solution:
la source