Aller au contenu
Modification (DML)

UPSERT (ON CONFLICT)

Un UPSERT insère une ligne ou, si sa clé existe déjà, met à jour la ligne en place. C'est la façon sûre de synchroniser un catalogue ou un import sans tester l'existence au préalable.

  • upsert
  • ON CONFLICT
  • DO UPDATE
  • DO NOTHING
  • excluded
  • MERGE

Syntaxe

Modèle
INSERT INTO table (cle, col)VALUES (v1, v2)ON CONFLICT (cle) DO UPDATE SET col = excluded.col;-- ou : ON CONFLICT (cle) DO NOTHING

Exemple

Exemple concret
INSERT INTO products (id, name, price, category)VALUES (2, 'Souris sans fil', 24.99, 'Informatique'),       (6, 'Tapis de souris', 12.50, 'Informatique')ON CONFLICT (id) DO UPDATE SET price = excluded.price;SELECT id, name, priceFROM productsWHERE id IN (2, 6)ORDER BY id;-- Jeu de données : boutique-- Le produit 2 existe : son prix est mis à jour. Le produit 6 est créé.-- Résultat attendu :-- 2 | Souris sans fil | 24.99-- 6 | Tapis de souris | 12.5

À retenir

  1. excluded désigne la ligne qu'on tentait d'insérer : SET price = excluded.price reprend la nouvelle valeur, SET stock = stock + excluded.stock cumule.
  2. La cible du conflit (id) doit correspondre à une clé primaire ou à une contrainte UNIQUE, sinon la requête est refusée.
  3. Piège : INSERT OR REPLACE n'est pas un UPSERT. Il supprime puis réinsère la ligne : les colonnes non fournies repassent à leur valeur par défaut et les actions ON DELETE se déclenchent.
  4. Même syntaxe ON CONFLICT dans PostgreSQL (9.5+). MySQL utilise ON DUPLICATE KEY UPDATE, SQL Server et Oracle l'instruction MERGE.
  5. Dans SQLite, INSERT … SELECT … ON CONFLICT demande un WHERE dans le SELECT (WHERE true suffit) pour lever une ambiguïté d'analyse.

Voir aussi