LUPSERT : insérer ou mettre à jour en une seule instruction
Oracle implémente la fonctionnalité dUPSERT à laide de linstruction MERGE définie par le standard SQL :
PostgreSQL intègre depuis la 9.5 la fonctionnalité d'UPSERT gràce à une extension propriétaire à l'instruction INSERT, la clause ON CONFLICT :
Le mot clé EXCLUDED est un alias désignant les lignes proposées à l'insertion. Vous pouvez l'utiliser dans une clause DO UPDATE pour réaliser une mise à jour de tout ou partie des colonnes pour la ligne en conflit. Il serait aussi possible de ne rien faire en cas de conflit (DO NOTHING).
A noter qu'une contrainte d'unicité, ici la clé primaire définie au niveau de c1 pour t1, est nécessaire pour générer un conflit et assurer l'arbitrage.
INSERT ... ON CONFLICT est une instruction sûre au niveau du A (atomicité) de ACID. Elle est donc adaptée pour une utilisation transactionnelle.
Depuis la version 15, PostgreSQL intègre également MERGE. Démonstration :
Dans une utilisation basique, vous pouvez à présent utiliser MERGE sous PostgreSQL comme vous le faites avec Oracle Database. Une contrainte n'est pas nécessaire et la syntaxe est quasi identique. Il faut juste faire attention à ne pas préfixer la colonne à mettre à jour avec le nom de la table sur laquelle s'opère le MERGE dans la clause UPDATE. Le comportement du MERGE de PostgreSQL est à ce niveau cohérent avec celui de sa commande UPDATE et conforme au standard SQL.
La communauté PostgreSQL a longtemps été réticente à implémenter la commande MERGE, délicate à manipuler au niveau de la concurrence transactionnelle. Cependant, cette commande fait partie de la norme SQL et il était important de l'implémenter. C'est à présent chose faite et vous pouvez l'utiliser dans vos programmes transactionnels et décisionnels, dès maintenant en test, puis en production dès la sortie officielle de PostgreSQL 15 prévue avant la fin de l'année 2022.
Mise à jour : 28/03/2022