ON DUPLICATE KEY UPDATE – INSERT ou UPDATE (MySQL)
Bonne lecture et bon apprentissage !
Junior TSAFACK – 08/08/2026
⏱️ Temps de lecture estimé : 5 minutes
L’instruction ON DUPLICATE KEY UPDATE est une fonctionnalité de MySQL (et MariaDB) qui permet de mettre à jour des données lorsqu’un enregistrement existe déjà dans une table. Cela permet d’effectuer en une seule requête SQL un INSERT ou un UPDATE selon la convenance. C’est ce qu’on appelle communément un UPSERT (contraction de UPDATE + INSERT).
Bon à savoir : Cette fonctionnalité est spécifique à MySQL et MariaDB. Les autres SGBD (PostgreSQL, Oracle, SQL Server) utilisent des approches différentes que nous verrons en fin de chapitre.
Syntaxe
Section titled “Syntaxe”Cette commande s’effectue au sein de la requête INSERT INTO avec la syntaxe suivante :
INSERT INTO table (a, b, c)VALUES (1, 20, 68)ON DUPLICATE KEY UPDATE a = a + 1;Traduction de la requête :
Insérer les données a, b et c avec les données respectives 1, 20 et 68.
Si la clé primaire (ou une clé unique) existe déjà pour ces valeurs, alors seulement faire une mise à jour de a = a + 1.
Exemple concret : Système de votes
Section titled “Exemple concret : Système de votes”Imaginons une application qui laisse les utilisateurs voter pour les produits qu’ils préfèrent. Le système de vote est très simple et est basé sur des +1. La table des votes contient le nombre de votes par produit avec la date du premier vote et la date du dernier vote.
Table « vote » :
| id | produit_id | vote_count | vote_first_date | vote_last_date |
|---|---|---|---|---|
| 1 | 46 | 2 | 2012-04-25 17:45:24 | 2013-02-16 09:47:02 |
| 2 | 39 | 4 | 2012-04-28 16:54:44 | 2013-02-14 21:04:35 |
| 3 | 49 | 1 | 2012-04-25 19:11:09 | 2013-01-06 20:32:57 |
Pour n’utiliser qu’une seule ligne qui permet d’ajouter des votes dans cette table, sans se préoccuper de savoir s’il faut faire un INSERT ou un UPDATE, il est possible d’utiliser la requête SQL suivante :
INSERT INTO vote (produit_id, vote_count, vote_first_date, vote_last_date)VALUES (50, 1, NOW(), NOW())ON DUPLICATE KEY UPDATE vote_count = vote_count + 1, vote_last_date = NOW();Dans cette requête, la date et l’heure sont générées automatiquement avec la fonction NOW().
Résultat après la première exécution de la requête :
| id | produit_id | vote_count | vote_first_date | vote_last_date |
|---|---|---|---|---|
| 1 | 46 | 2 | 2012-04-25 17:45:24 | 2013-02-16 09:47:02 |
| 2 | 39 | 4 | 2012-04-28 16:54:44 | 2013-02-14 21:04:35 |
| 3 | 49 | 1 | 2012-04-25 19:11:09 | 2013-01-06 20:32:57 |
| 4 | 50 | 1 | 2013-04-02 15:06:34 | 2013-04-02 15:06:34 |
Ce résultat montre bien l’ajout d’une ligne en fin de table ; la requête a donc été utilisée sous la forme d’un INSERT.
Après une deuxième exécution de cette même requête le lendemain :
| id | produit_id | vote_count | vote_first_date | vote_last_date |
|---|---|---|---|---|
| 1 | 46 | 2 | 2012-04-25 17:45:24 | 2013-02-16 09:47:02 |
| 2 | 39 | 4 | 2012-04-28 16:54:44 | 2013-02-14 21:04:35 |
| 3 | 49 | 1 | 2012-04-25 19:11:09 | 2013-01-06 20:32:57 |
| 4 | 50 | 2 | 2013-04-02 15:06:34 | 2013-04-03 10:12:45 |
Les résultats montrent bien qu’il y a eu un vote supplémentaire (le compteur est passé de 1 à 2) et que la date du dernier vote a été mise à jour.
Utilisation avec WHERE (condition supplémentaire)
Section titled “Utilisation avec WHERE (condition supplémentaire)”Grâce à la commande ON DUPLICATE KEY UPDATE, il est possible d’ajouter une condition pour la mise à jour.
INSERT INTO table (a, b, c, date_insert)VALUES (1, 20, 1, NOW())ON DUPLICATE KEY UPDATE date_update = NOW()WHERE c = 1;Traduction de la requête :
- Insérer les données
a,b,cetdate_insertavec les données respectives 1, 20, 1 ainsi que la date et l’heure actuelles. - Si la clé primaire existe déjà pour ces valeurs, alors mettre à jour la date et l’heure du champ
date_update. - Effectuer la mise à jour uniquement sur les champs où
c = 1.
Remarque : La condition
WHEREest facultative. Si elle est omise, la mise à jour s’effectue toujours en cas de duplication.
Insérer une ligne ou ne rien faire
Section titled “Insérer une ligne ou ne rien faire”Dans certains cas, il est intéressant d’utiliser un INSERT mais de ne rien faire si la ligne existe déjà. Malheureusement, si la clé primaire existe déjà, la requête retournera une erreur. Et s’il n’y a rien à mettre à jour, la commande ON DUPLICATE KEY UPDATE ne semble pas convenir. Toutefois, il y a une astuce qui consiste à utiliser une requête de ce type :
INSERT INTO table (a, b, c)VALUES (1, 45, 6)ON DUPLICATE KEY UPDATE id = id;Cette requête insère les données et ne produit aucune erreur si l’enregistrement existait déjà dans la table.
Bon à savoir : Théoriquement, il aurait été possible d’utiliser
INSERT IGNORE, mais malheureusement cela empêche de retourner des erreurs telles que des erreurs de conversion de données.
Compatibilité avec les autres SGBD
Section titled “Compatibilité avec les autres SGBD”Pour le moment, cette fonctionnalité n’est possible qu’avec MySQL (depuis la version 4.1, datant de 2003) et MariaDB. Les autres Systèmes de Gestion de Bases de Données (SGBD) n’intègrent pas cette syntaxe. Voici quelques alternatives :
| SGBD | Alternative recommandée |
|---|---|
| PostgreSQL | INSERT ... ON CONFLICT (colonne) DO UPDATE SET ... |
| Oracle | MERGE (ou MERGE INTO) |
| SQL Server | MERGE |
| SQLite | INSERT ... ON CONFLICT DO UPDATE (depuis la version 3.24.0) |
Exemple avec PostgreSQL (à partir de la version 9.5) :
INSERT INTO vote (produit_id, vote_count, vote_first_date, vote_last_date)VALUES (50, 1, NOW(), NOW())ON CONFLICT (produit_id) DO UPDATESET vote_count = vote_count + 1, vote_last_date = NOW();Exemple avec Oracle et SQL Server (MERGE) :
MERGE INTO vote USING (SELECT 50 AS produit_id FROM dual) AS srcON (vote.produit_id = src.produit_id)WHEN MATCHED THEN UPDATE SET vote_count = vote_count + 1, vote_last_date = SYSDATEWHEN NOT MATCHED THEN INSERT (produit_id, vote_count, vote_first_date, vote_last_date) VALUES (50, 1, SYSDATE, SYSDATE);Bonnes pratiques
Section titled “Bonnes pratiques”- Utilisez une clé unique (PRIMARY KEY ou UNIQUE) :
ON DUPLICATE KEY UPDATEne fonctionne que s’il y a une contrainte d’unicité violée. - Ne confondez pas avec INSERT IGNORE :
IGNOREsupprime l’erreur mais n’effectue aucune mise à jour. - Vérifiez les effets de bord : si votre table a plusieurs index uniques, la condition de duplication peut se déclencher sur l’un d’eux.
- Préférez les alternatives standard si votre application doit être portable sur plusieurs SGBD.
Prochain chapitre
Section titled “Prochain chapitre”Vous savez désormais comment insérer ou mettre à jour une ligne en une seule requête avec ON DUPLICATE KEY UPDATE. Passons maintenant à la commande UPDATE, qui permet de modifier des données existantes.
👉 Chapitre 22 : UPDATE – Modifier des données
Bonne continuation !
Junior TSAFACK – 08/08/2026