web-dev-qa-db-fra.com

Sur la clé en double

J'ai cherché autour mais je n'ai pas trouvé si c'est possible.

J'ai cette requête MySQL:

INSERT INTO table (id,a,b,c,d,e,f,g) VALUES (1,2,3,4,5,6,7,8)

Le champ id a un "index unique", donc il ne peut y en avoir deux. Maintenant, si le même identifiant est déjà présent dans la base de données, j'aimerais le mettre à jour. Mais dois-je vraiment spécifier à nouveau tous ces champs, comme:

INSERT INTO table (id,a,b,c,d,e,f,g) VALUES (1,2,3,4,5,6,7,8) 
ON DUPLICATE KEY UPDATE a=2,b=3,c=4,d=5,e=6,f=7,g=8

Ou:

INSERT INTO table (id,a,b,c,d,e,f,g) VALUES (1,2,3,4,5,6,7,8) 
ON DUPLICATE KEY UPDATE a=VALUES(a),b=VALUES(b),c=VALUES(c),d=VALUES(d),e=VALUES(e),f=VALUES(f),g=VALUES(g)

J'ai tout spécifié déjà dans l'insert ...

Une note supplémentaire, je voudrais utiliser le travail autour pour obtenir l'ID à!

id=LAST_INSERT_ID(id)

J'espère que quelqu'un pourra me dire quel est le moyen le plus efficace.

144
Roy

Il n'y a pas d'autre moyen, je dois tout spécifier deux fois. D'abord pour l'insertion, ensuite dans le cas de la mise à jour.

20
Roy

L'instruction UPDATE permet de mettre à jour les anciens champs avec la nouvelle valeur. Si vos anciennes valeurs sont les mêmes que vos nouvelles, pourquoi devriez-vous la mettre à jour dans tous les cas?

Pour par exemple. si vos colonnes a à g sont déjà définies comme 2 à 8; il ne serait pas nécessaire de le réactualiser.

Alternativement, vous pouvez utiliser:

INSERT INTO table (id,a,b,c,d,e,f,g)
VALUES (1,2,3,4,5,6,7,8) 
ON DUPLICATE KEY
    UPDATE a=a, b=b, c=c, d=d, e=e, f=f, g=g;

Pour obtenir la id de LAST_INSERT_ID; vous devez spécifier l'application principale que vous utilisez pour la même chose.

Pour LuaSQL, une conn:getlastautoid() récupère la valeur.

73
hjpotter92

Il existe une extension SQL spécifique à MySQL qui peut être ce que vous voulez - REPLACE INTO

Cependant, cela ne fonctionne pas tout à fait comme "ON DUPLICATE UPDATE"

  1. Il supprime l'ancienne ligne qui entre en conflit avec la nouvelle ligne, puis insère la nouvelle. Tant que vous n'avez pas de clé primaire sur la table, tout ira bien, mais si vous en avez une, alors si une autre table fait référence à cette clé primaire

  2. Vous ne pouvez pas référencer les valeurs dans les anciennes lignes de sorte que vous ne pouvez pas faire un équivalent de

    _INSERT INTO mytable (id, a, b, c) values ( 1, 2, 3, 4) 
    ON DUPLICATE KEY UPDATE
    id=1, a=2, b=3, c=c + 1;
    _

Je voudrais utiliser le travail autour pour obtenir l'ID à!

Cela devrait fonctionner - last_insert_id () devrait avoir la valeur correcte tant que votre clé primaire est auto-incrémentée.

Cependant, comme je l’ai dit, si vous utilisez réellement cette clé primaire dans d’autres tables, _REPLACE INTO_ ne vous conviendra probablement pas, car elle supprime l’ancienne ligne en conflit avec la clé unique.

Quelqu'un d'autre suggéré auparavant vous pouvez réduire la saisie en faisant:

_INSERT INTO `tableName` (`a`,`b`,`c`) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE `a`=VALUES(`a`), `b`=VALUES(`b`), `c`=VALUES(`c`);
_
39
Danack

Voici une solution à votre problème:

J'ai essayé de résoudre un problème comme le vôtre et je voudrais suggérer de tester un aspect simple.

Suivez ces étapes: Apprenez d'une solution simple.

Étape 1: Créez un schéma de table à l'aide de cette requête SQL:

CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) NOT NULL,
  `password` varchar(32) NOT NULL,
  `status` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `no_duplicate` (`username`,`password`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

A table <code>user</code> with data

Étape 2: Créez un index de deux colonnes pour empêcher les données en double à l'aide de la requête SQL suivante:

ALTER TABLE `user` ADD INDEX no_duplicate (`username`, `password`);

ou, Créez un index de deux colonnes à partir de l'interface graphique comme suit: Create index from GUISelect columns to create indexIndexes of table <code>user</code>

Étape 3: Mettez à jour si existant, insérez sinon en utilisant les requêtes suivantes:

INSERT INTO `user`(`username`, `password`) VALUES ('ersks','Nepal') ON DUPLICATE KEY UPDATE `username`='master',`password`='Nepal';

INSERT INTO `user`(`username`, `password`) VALUES ('master','Nepal') ON DUPLICATE KEY UPDATE `username`='ersks',`password`='Nepal';

Table <code>user</code> after running above query

21
user5505982

Juste au cas où vous seriez en mesure d'utiliser un langage de script pour préparer vos requêtes SQL, vous pouvez réutiliser des paires champ = valeur en utilisant SET au lieu de (a,b,c) VALUES(a,b,c).

Un exemple avec PHP:

$pairs = "a=$a,b=$b,c=$c";
$query = "INSERT INTO $table SET $pairs ON DUPLICATE KEY UPDATE $pairs";

Exemple de tableau:

CREATE TABLE IF NOT EXISTS `tester` (
  `a` int(11) NOT NULL,
  `b` varchar(50) NOT NULL,
  `c` text NOT NULL,
  UNIQUE KEY `a` (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
7
Chris

Vous voudrez peut-être envisager d’utiliser la syntaxe REPLACE INTO, mais soyez averti en cas de duplication de la clé PRIMARY/UNIQUE, SUPPRIME la ligne et INSÈRE une nouvelle un.

Vous n'aurez pas besoin de spécifier à nouveau tous les champs. Cependant, vous devriez envisager une réduction possible des performances (dépend de la conception de votre table).

Mises en garde:

  • Si vous avez la clé primaire AUTO_INCREMENT, une nouvelle clé lui sera attribuée.
  • Les index devront probablement être mis à jour
4
code ninja

Je sais qu'il est tard, mais j'espère que cette réponse sera aidée

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6)
ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

Vous pouvez lire le tutoriel ci-dessous ici:

https://mariadb.com/kb/en/library/insert-on-duplicate-key-update/

http://www.mysqltutorial.org/mysql-insert-or-update-on-duplicate-key-update/

2
Galang Piliang