UPSERT : ON CONFLICT DO UPDATE (PostgreSQL)
Implémentez des insertions idempotentes avec ON CONFLICT DO UPDATE, utilisez EXCLUDED et choisissez la bonne cible de conflit.
UPSERT : ON CONFLICT DO UPDATE (PostgreSQL) est une leçon SQL Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage SQL Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours SQL Academy comprend 4 leçons au total.
Qu’est-ce qu’un UPSERT ?
UPSERT signifie : INSERT si la ligne n’existe pas, UPDATE si elle existe. PostgreSQL l’écrit INSERT ... ON CONFLICT.
ON CONFLICT DO NOTHING
Insérez la ligne si elle est absente, et ignorez silencieusement l’insertion si elle est en double :
INSERT INTO users (email, full_name)
VALUES ('alice@example.com', 'Alice')
ON CONFLICT (email) DO NOTHING;ON CONFLICT DO UPDATE
Insérez la ligne si elle est absente ; sinon, mettez à jour des colonnes précises :
INSERT INTO users (email, full_name, last_login)
VALUES ('alice@example.com', 'Alice', NOW())
ON CONFLICT (email)
DO UPDATE SET
full_name = EXCLUDED.full_name,
last_login = EXCLUDED.last_login;EXCLUDED : la ligne proposée
Dans DO UPDATE, EXCLUDED.col désigne « la valeur que INSERT a essayé d’insérer ». Le nom de colonne seul (ou users.col) désigne la ligne existante.
ON CONFLICT (email)
DO UPDATE SET visits = users.visits + 1,
last_seen = EXCLUDED.last_seen;La cible du conflit
Vous devez indiquer une contrainte UNIQUE ou une clé primaire :
ON CONFLICT (email) -- column with UNIQUE
ON CONFLICT (user_id, day) -- composite UNIQUE
ON CONFLICT ON CONSTRAINT users_email_key -- by nameUPSERT conditionnel (WHERE dans DO UPDATE)
Effectuez la mise à jour uniquement lorsqu’une condition est remplie :
INSERT INTO inventory (product_id, qty)
VALUES (42, 5)
ON CONFLICT (product_id)
DO UPDATE SET qty = inventory.qty + EXCLUDED.qty
WHERE inventory.qty + EXCLUDED.qty <= 1000;UPSERT multi-lignes
Insérez plusieurs lignes ; chaque ligne est traitée séparément :
INSERT INTO page_views (path, day, count)
VALUES ('/home', CURRENT_DATE, 1), ('/about', CURRENT_DATE, 1)
ON CONFLICT (path, day)
DO UPDATE SET count = page_views.count + EXCLUDED.count;RETURNING avec UPSERT
Récupérez la ligne obtenue, qu’elle ait été insérée ou mise à jour :
INSERT INTO users (email, full_name)
VALUES ('alice@example.com', 'Alice')
ON CONFLICT (email) DO UPDATE
SET full_name = EXCLUDED.full_name
RETURNING id, full_name;Flux de travail idempotents
UPSERT rend les nouvelles tentatives sûres. Si votre webhook est déclenché deux fois, le deuxième appel met à jour la même ligne au lieu de créer un doublon.
MERGE (norme SQL, PG15+)
PostgreSQL 15 a ajouté MERGE, conforme à la norme SQL, qui peut effectuer un INSERT, un UPDATE et un DELETE dans une seule instruction :
MERGE INTO users AS u
USING (VALUES ('alice@example.com','Alice')) AS src(email, name)
ON u.email = src.email
WHEN MATCHED THEN UPDATE SET full_name = src.name
WHEN NOT MATCHED THEN INSERT (email, full_name) VALUES (src.email, src.name);Quand ne pas utiliser UPSERT
UPSERT nécessite une contrainte UNIQUE. Si vous n’en avez pas, vous devez généralement effectuer un SELECT séparé, puis un INSERT ou un UPDATE — mais méfiez-vous des conditions de concurrence ; utilisez une transaction avec un verrouillage approprié.
Récapitulatif
ON CONFLICT est l’UPSERT propre et atomique de PostgreSQL.
- DO NOTHING pour « insérer si la ligne est absente »
- DO UPDATE pour un véritable UPSERT
EXCLUDED= la ligne proposée- Indiquez toujours une cible de conflit
Vérification rapide
Dans ON CONFLICT (email) DO UPDATE SET last_login = EXCLUDED.last_login, à quoi EXCLUDED fait-il référence ?
Questions Fréquemment Posées
La leçon « UPSERT : ON CONFLICT DO UPDATE (PostgreSQL) » est-elle gratuite ?
Oui — le texte complet de « UPSERT : ON CONFLICT DO UPDATE (PostgreSQL) » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours SQL Academy, passe à CoddyKit PRO. Le cours SQL Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « UPSERT : ON CONFLICT DO UPDATE (PostgreSQL) » ?
Implémentez des insertions idempotentes avec ON CONFLICT DO UPDATE, utilisez EXCLUDED et choisissez la bonne cible de conflit. Tu pratiques SQL Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer SQL Academy ?
Aucune expérience préalable n'est requise. SQL Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « UPSERT : ON CONFLICT DO UPDATE (PostgreSQL) » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon SQL Academy ?
Oui. Chaque leçon SQL Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- INSERT avec plusieurs lignes
- UPSERT : ON CONFLICT DO UPDATE (PostgreSQL)
- UPDATE avec FROM et mises à jour de type JOIN
- DELETE avec USING et modèles sûrs