Query failed: ERROR: duplicate key violates unique constraint

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Query failed: ERROR: duplicate key violates unique constraint

par laeti » 13 août 2007, 12:12

En fait, j'ai utilisé le logiciel MicroOlap pour générer mes tables dans PostgreSql donc je ne peux pas répondre à ta question.

Ce que je trouve bizarre, c'est que j'ai déjà utilisé le même code pour insérer un nouveau libellé dans une autre table et ça marchait très bien. de plus, les 2 tables sont construites de la même façon.

Il semblerait qu'il s'agisse d'un pb d'incrémentation. Je souhait insérer une nouvelle ligne dans une table qui contient déjà 23 éléments donc si l'insertion fonctionnait, j'aurai ma nouvelle ligne avec un identifiant à 24. Or, l'insertion ne se fait pas car je duplique un identifiant déjà existant. Comment puis-je faire mon insertion avec un identifiant qui n'existe pas encore. Je pense que c'est un problème à régler dans postgres et non dans mon code.
Quelqu'un a-t-il une petite idée?

par Sékiltoyai » 13 août 2007, 12:09

Oui mais tu les as fais les requètes ALTER juste après avoir créé ta table ?

par laeti » 13 août 2007, 12:07

si c'est un serial:
ref_spa_id serial NOT NULL,

par Sékiltoyai » 13 août 2007, 12:06

Si tu fais ca :

Code : Tout sélectionner

ALTER TABLE referentiel_spatial DROP COLUMN ref_spa_id; ALTER TABLE referentiel_spatial ADD COLUMN ref_spa_id int4;
Alors, c'est un int et non un serial.

par laeti » 13 août 2007, 12:03

Voici ma table:

Code : Tout sélectionner

CREATE TABLE referentiel_spatial ( ref_spa_id serial NOT NULL, ref_spa_nom varchar(100), CONSTRAINT referentiel_spatial_pkey PRIMARY KEY (ref_spa_id) ) WITHOUT OIDS; ALTER TABLE referentiel_spatial OWNER TO postgres;
Mon champ id:

Code : Tout sélectionner

Column: ref_spa_id -- ALTER TABLE referentiel_spatial DROP COLUMN ref_spa_id; ALTER TABLE referentiel_spatial ADD COLUMN ref_spa_id int4; ALTER TABLE referentiel_spatial ALTER COLUMN ref_spa_id SET STORAGE PLAIN; ALTER TABLE referentiel_spatial ALTER COLUMN ref_spa_id SET NOT NULL; ALTER TABLE referentiel_spatial ALTER COLUMN ref_spa_id SET DEFAULT nextval('referentiel_spatial_ref_spa_id_seq'::regclass);
C'est cool, j'ai plein de réponses!!! mais vous m'avez un peu embrouillé.
Mon id s'auto-increment étant donné qu'il est serial.

par Genova » 13 août 2007, 11:52

Ah, mes excuses alors, c'est bon à savoir :)

par Sékiltoyai » 13 août 2007, 11:49

Non, Genova, dans PostgreSQL, il y a aussi un champ qui se comporte comme le champ autoincrement. C'est le type de champ SERIAL.

par Genova » 13 août 2007, 11:35

en auto increment tu n'as pas besoin de gérer les identifiants, ils sont incrémentés automatiquement.
Quand tu veux insérer un élément, tu le fais comme ceci :
"INSERT INTO str_ref_spa(str_id) VALUES (".$str_id.")"; 
L'identifiant s'incrémentera à chaque insertion et chaque élement aura un identifiant différents aux autres.
Attention, ceci n'est pas valable en PostGreSQL. Il semble que laeti utilise justement une base de donnée PostGreSQL et non du MySQL. En Pgsql si je me rappel bien la gestion des auto increment est à faire via une séquence

Code : Tout sélectionner

CREATE SEQUENCE ma_seq; SELECT SETVAL('ma_seq', (SELECT CASE WHEN MAX(mon_champ) > 0 THEN MAX(mon_champ)+1 ELSE 1 END FROM ma_table));
et dans la déclaration du champ dans le CREATE TABLE :

Code : Tout sélectionner

mon_champ INT DEFAULT nextval('ma_seq')
Vérifie donc si tu as bien fait ça si tu as voulu créer une clef primaire qui s'auto incrémente.

par d0m » 13 août 2007, 11:15

tu n'aurais pas dans ta table referentiel_spatial le champ ref_spa_nom contenu dans la clé primaire?

par laeti » 13 août 2007, 11:09

C'est bien ce que j'ai fait. J'ai peut-être mis un peu trop de code, ça a donc peut-être embrouillé tout le monde.

La requête qui me pose pb est la suivante:
$sql = "INSERT INTO referentiel_spatial(ref_spa_nom) VALUES ('".$Ref_spa_autre."')";
				$req = pg_query($sql) or die('Erreur SQL !'.$sql.'<br>'.pg_result_error());
et le message d'erreur complet est le suivant:

Warning: pg_query() [function.pg-query]: Query failed: ERROR: duplicate key violates unique constraint "referentiel_spatial_pkey" in C:\Program Files\wamp\www\Site_enquete\traitement_saisie3.php on line 58
Erreur SQL !INSERT INTO referentiel_spatial(ref_spa_nom) VALUES ('bd geo')

par d0m » 13 août 2007, 10:55

en auto increment tu n'as pas besoin de gérer les identifiants, ils sont incrémentés automatiquement.
Quand tu veux insérer un élément, tu le fais comme ceci :
"INSERT INTO str_ref_spa(str_id) VALUES (".$str_id.")"; 
L'identifiant s'incrémentera à chaque insertion et chaque élement aura un identifiant différents aux autres.

par laeti » 13 août 2007, 10:51

En effet, d0m, il s'agit bien d'un id auto-incrément. Donc si je te suis bien quand je vais mon insert, il commence à 1, or comme ma table contient déjà des éléments le 1 existe déjà. Comment dois-je recalculer tout ça pour recommencer à 24 par exemple?

par Ryle » 13 août 2007, 10:50

Pis y a aussi un truc qui me chiffone... quand tu fais l'insertion uniquement du libellé, ça sous entends que c'est ta base qui va faire un auto-increment pour déterminer l'id à associer ?

Si par ailleurs tu spécifies toi même des id à insérer (cf. la requête pointée par zeus), il se peut qu'il y ait un décallage entre tes ids en bases et la valeur d'auto incrementation de la table.. du coup il risque d'utiliser des ids qui ont déjà été distribués ? ... :-k

par zeus » 13 août 2007, 10:46

Dans ce bout de code, tu ne testes pas la présence de l'identifiant de la base ... ;)
// On prépare la requête pour insérer les identifiants dans la table str_ref_spa et on exécute cette requête
        for ($i=0; isset($_POST['Ref_spa'][$i]); $i++) {
            $sql = "INSERT INTO str_ref_spa(ref_spa_id, str_id) VALUES (".$_POST['Ref_spa'][$i].",".$str_id.")";
            $req = pg_query($sql) or die('Erreur SQL !'.$sql.'<br>'.pg_result_error());
        } 

par laeti » 13 août 2007, 10:46

Il s'agit de cette requête là:
 // On prépare la requête pour insérer le libellé du reseau_sig de type autre saisi dans la textarea et on exécute cette requête
               $sql = "INSERT INTO referentiel_spatial(ref_spa_nom) VALUES ('".$Ref_spa_autre."')";
                $req = pg_query($sql) or die('Erreur SQL !'.$sql.'<br>'.pg_result_error());