Skip to content

Instantly share code, notes, and snippets.

@johnchristopher
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnchristopher/31f495ea558a1d2f3962 to your computer and use it in GitHub Desktop.
Save johnchristopher/31f495ea558a1d2f3962 to your computer and use it in GitHub Desktop.
Update field if it exists or insert it if it doesn't (with MySQL ON DUPLICATE KEY UPDATE)
mysql > CREATE TABLE `mytable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`myvalue` int(11) NOT NULL,
`myothervalue` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `myvalue_unique` (`myvalue`), -- C'est le champ qui s'il existe alors on le met à jour,
KEY `myvalue_idx` (`myvalue`) -- sinon on crée un nouvel enregistrement
)
Query OK, 0 rows affected (0.09 sec)
mysql> desc mytable;
+--------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| myvalue | int(11) | NO | UNI | NULL | |
| myothervalue | int(11) | NO | | NULL | |
+--------------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> INSERT INTO mytable (myvalue, myothervalue) VALUES (1, 1);
INSERT INTO mytable (myvalue, myothervalue) VALUES (2, 2);
INSERT INTO mytable (myvalue, myothervalue) VALUES (3, 3);
Query OK, 3 row affected (0.04 sec)
mysql> SELECT * FROM mytable;
+----+---------+--------------+
| id | myvalue | myothervalue |
+----+---------+--------------+
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
+----+---------+--------------+
3 rows in set (0.00 sec)
mysql> INSERT INTO mytable (myvalue,myothervalue) VALUES (1,1) ON DUPLICATE KEY UPDATE myothervalue=1;
Query OK, 0 rows affected (0.05 sec)
mysql> SELECT * FROM mytable;
+----+---------+--------------+
| id | myvalue | myothervalue |
+----+---------+--------------+
| 1 | 1 | 1 | -- Rien n'a changé
| 2 | 2 | 2 |
| 3 | 3 | 3 |
+----+---------+--------------+
3 rows in set (0.00 sec
mysql> INSERT INTO mytable (myvalue,myothervalue) VALUES (1,4) ON DUPLICATE KEY UPDATE myothervalue=4;
Query OK, 2 rows affected (0.05 sec)
mysql> SELECT * FROM mytable;
+----+---------+--------------+
| id | myvalue | myothervalue |
+----+---------+--------------+
| 1 | 1 | 4 | -- Magie !
| 2 | 2 | 2 |
| 3 | 3 | 3 |
+----+---------+--------------+
3 rows in set (0.00 sec)
mysql> INSERT INTO mytable (myvalue,myothervalue) VALUES (4,4) ON DUPLICATE KEY UPDATE myothervalue=4;
Query OK, 1 row affected (0.04 sec)
mysql> SELECT * FROM mytable;
+----+---------+--------------+
| id | myvalue | myothervalue |
+----+---------+--------------+
| 1 | 1 | 4 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 9 | 4 | 4 | -- Et voilà un nouvel enregistrement puisque `myvalue=4' n'existe pas
+----+---------+--------------+
4 rows in set (0.00 sec)
mysql> INSERT INTO mytable (myvalue,myothervalue) VALUES (1,1) ON DUPLICATE KEY UPDATE myothervalue=1;
Query OK, 2 rows affected (0.20 sec)
mysql> SELECT * FROM mytable;
+----+---------+--------------+
| id | myvalue | myothervalue |
+----+---------+--------------+
| 1 | 1 | 1 | -- Remettons le premier enregistrement à l'origine
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 9 | 4 | 4 |
+----+---------+--------------+
4 rows in set (0.00 sec)
-- Attention, tu vois la clé primaire `id' qui est passée à 9 ? C'est parce que même
-- si on ne fait qu'UPDATER une ligne la requête commence par `INSERT' qui incrémente
-- le compteur automatiquement.
-- Note le découplage dans la requête où il faut indiquer deux fois la valeur du champ
-- à modifier (une fois si on UPDATE, une fois si on INSERT).
-- Plusieurs lignes peuvent être modifées ou ajoutées en une passe:
mysql> INSERT INTO mytable (myvalue,myothervalue)
VALUES (5,5),(1,100)
ON DUPLICATE KEY
UPDATE myothervalue=VALUES(myothervalue);
Query OK, 3 rows affected (0.07 sec)
Records: 2 Duplicates: 1 Warnings: 0
mysql> SELECT * FROM mytable;
+----+---------+--------------+
| id | myvalue | myothervalue |
+----+---------+--------------+
| 1 | 1 | 100 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 9 | 4 | 4 |
| 15 | 5 | 5 |
+----+---------+--------------+
5 rows in set (0.00 sec)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment