Tag : Postgresql

PostgreSQL : Utiliser ON CONFLICT et RETURNING

Dans le cadre de l'utilisation d'une query postgre INSERT ON CONFLICT vous avez peut-être tenté d'utiliser RETURNING afin de par exemple retourner l'id original de l'élément qui créer le conflict.

Prenons la table "customers" suivante :

id	name	email	        date
1	Maxime	maxime@test.fr	2022/08/11
2	Goodie	goodie@test.fr	2022/08/11

Nous avons évidement une contrainte unique sur l'email customers. Si l'on souhaite jouer cette requête nous allons avoir une erreur :

INSERT INTO customers (email) VALUES ('maxime@test.fr');
ERROR:  duplicate KEY value violates UNIQUE constraint "customers_email_key"
DETAIL:  KEY (email)=(maxime@test.fr) already EXISTS.

Nous utilisons donc la clause "ON CONFLICT" pour éviter d'avoir cette erreur et souhaitons retourner l'id du customer.

Notre première id serait d'utiliser cette requête :

INSERT INTO customers (email) VALUES ('maxime@test.fr') ON CONFLICT (email) DO NOTHING RETURNING id;
 id 
----
(0 rows)

Seulement comme vous le voyez nous n'avons aucun résultat.

La solution : il faut bien utiliser un DO UPDATE SET en n'effectuant aucune modification pour avoir nos résultats.

INSERT INTO customers (email) VALUES ('maxime@test.fr') ON CONFLICT (username) DO UPDATE SET email=EXCLUDED.email RETURNING id;
 id 
----
   1
(1 row)

Vous noterez l'utilisation de EXCLUDED qui est la valeur originale de l'insert, donc pas de modification et nos récupérons bien notre id smile