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 nimplémente pas MERGE. Cest un choix délibéré : la communauté a notamment jugé que le standard SQL nétait pas suffisamment explicite au niveau de la gestion de la concurrence. Cependant, depuis PostgreSQL 9.5, la fonctionnalité dUPSERT est implémentée gràce à une extension propriétaire à linstruction 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 quune contrainte dunicité, ici la clé primaire définie au niveau de c1 pour t1, est nécessaire avec PostgreSQL pour générer un conflit et assurer larbitrage au niveau de lUPSERT. Ce nétait pas nécessaire avec MERGE sous Oracle.
Ce que permet MERGE dépasse la notion dUPSERT. Limplémentation dOracle permet de détruire les lignes plutôt que les mettre à jour (un DELUPSERT ?). Je ne suis généralement pas favorable aux extensions propriétaires lorsque des solutions définies par le standard existent. Mais, si vous voulez absolument utiliser lUPSERT avec PostgreSQL, il est intéressant de savoir que cest malgré tout possible. Utiliser la clause ON CONFLICT est préférable à une solution basée sur PL/pgSQL ou autre.