web-dev-qa-db-fra.com

INSÉRER ... LA MISE À JOUR DE LA DUPLICATE KEY ne fonctionne pas comme je m'y attendais

J'ai une table appelée "Exemple"

CREATE TABLE IF NOT EXISTS `example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) NOT NULL,
  `b` int(11) NOT NULL,
  `c` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

Je veux insérer des valeurs si elles n'existent pas et si la valeur existe, puis mettre à jour, donc j'utilise l'instruction suivante:

INSERT INTO example (a, b, c) VALUES (1,2,3) 
  ON DUPLICATE KEY UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);

Après l'exécution des requêtes ci-dessus, le tableau ressemble à ceci:

enter image description here

Encore une fois, j'exécute l'instruction ci-dessus, le résultat ressemble à ceci:

enter image description here

Quel est le problème avec ma déclaration?

7
Relax

Votre requête d'origine

INSERT INTO example (a, b, c) VALUES (1,2,3) ON DUPLICATE KEY
UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);

Si vous considérez (a,b,c) une clé unique, il y a deux choses que vous devez faire

Tout d'abord, ajoutez un index unique

ALTER TABLE example ADD UNIQUE KEY abc_ndx (a,b,c);

de sorte que la structure de la table deviendrait

CREATE TABLE IF NOT EXISTS `example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) NOT NULL,
  `b` int(11) NOT NULL,
  `c` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY abc_ndx (a,b,c)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

Deuxièmement, vous devez modifier complètement la requête. Pourquoi ?

Si (a,b,c) est unique, le, en cours d'exécution

INSERT INTO example (a, b, c) VALUES (1,2,3) ON DUPLICATE KEY
UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);

conserverait les valeurs de (a,b,c) exactement le même. Rien ne changerait.

Par conséquent, je recommande de modifier la requête comme suit

INSERT IGNORE INTO example (a, b, c) VALUES (1,2,3);

La requête est plus simple et a le même résultat final.

7
RolandoMySQLDBA

Eh bien, c'est le bit d'insertion que vous utilisez:

INSÉRER DANS l'exemple (a, b, c) VALEURS (1,2,3) ....

ici, vous ne spécifiez pas le id (la clé primaire à vérifier pour la duplication). Étant donné qu'il est défini sur incrémentation automatique, il définit automatiquement l'ID de la ligne suivante avec uniquement les valeurs des colonnes a, b et c.

Dans ce cas, la ligne est mise à jour lorsque vous fournissez un clé primaire (que vous souhaitez vérifier est en double ou non), avec le reste des données de ligne. Si vous devez vérifier et mettre à jour en fonction de l'ID d'enregistrement, vous devez également fournir le KEY, qui dans votre cas est id.

Essayez quelque chose comme ceci:

INSERT INTO example (id, a, b, c) VALUES (1,1,2,3) ON DUPLICATE KEY UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);

Maintenant, si le id est en double, la ligne sera mise à jour.

8
Shaheer Ahmed