PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 14/06/2019 18:55:57

Mlan2
Membre

Problème d'utilisation de la clause ON CONFLICT dans un ordre INSERT

Bonjour,

Je rencontre un problème lors d'un ordre INSERT d'une clé déjà présente. (La clé vient d'être enregistrée par un autre processus en parallèle)

Je voulais utiliser la clause ON CONFLICT afin de faire une mise à jour (somme de la valeur fournie à la valeur déjà présente), mais je rencontre une erreur d'utilisation.

Ci-dessous, la table exemple à alimenter :

 Colonne   |         Type          | Collationnement | NULL-able | Par défaut
------------+-----------------------+-----------------+-----------+------------
 domaine    | character varying(10) |                 | not null  |
 struct     | character varying(40) |                 | not null  |
 datjour    | date                  |                 | not null  |
 jour       | character varying(1)  |                 | not null  |
 codecpt    | character varying(10) |                 | not null  |
 valeura    | character varying(40) |                 |           |
 codemodele | character varying(10) |                 |           |
 typedata   | character varying(1)  |                 |           |
 valeurd    | integer               |                 |           |
Index :
    "i_matable" PRIMARY KEY, btree (domaine, struct, datjour, jour, codecpt)

L'instruction INSERT que je voudrai réaliser. Dans l'exemple, je voudrais ajouter la valeur 10 si la clé est présente, sinon insérer la valeur 10 pour la clé fournie.

 INSERT INTO MATABLE (DOMAINE,
                      STRUCT,
                      DATJOUR,
                      JOUR,
                      CODECPT,
                      VALEURA,
                      CODEMODELE,
                      TYPEDATA,
                      VALEURD)

           VALUES    ('STRUCTURE',
                      'XXXXXX',
                      TO_DATE ('20190801', 'YYYYMMDD'),
                      '1',
                      'TOG',
                      ' ',
                      ' ',
                      '1',
                      10)
 ON CONFLICT DO UPDATE SET VALEURD = VALEURD + 10
                 WHERE (DOMAINE = 'STRUCTURE')
                   AND (STRUCT  = 'XXXXXX')
                   AND (DATJOUR = TO_DATE ('20190801', 'YYYYMMDD'))
                   AND (JOUR    = '1')
                   AND (CODECPT = 'TOG');

Le message d'erreur  que j'obtiens :

ERREUR:  ON CONFLICT DO UPDATE requiert une spécification d'inférence ou un nom de contrainte
 19 : ON CONFLICT DO UPDATE SET VALEURD = VALEURD + 10
      ^
E : Par exemple, ON CONFLICT (nom_colonne)

Il semble manquer une information dans la clause ON CONFLICT, aussi que faut t'il indiquer ?

D'autre part vais réussir à obtenir le résultat souhaité (20) ?

D'avance merci de votre retour.

Hors ligne

#2 14/06/2019 19:58:13

rjuju
Administrateur

Re : Problème d'utilisation de la clause ON CONFLICT dans un ordre INSERT

Bonjour,

Comme indiqué dans le message, il faut indiquer une spécification d'inférence (cad la liste de colonnes sur laquelle déduire une contrainte d'unicité) ou le nom de la contrainte unique pour laquelle vous voulez détecter un conflit.


Vous pouvez utiliser par exemple :

 INSERT INTO MATABLE (DOMAINE,
                      STRUCT,
                      DATJOUR,
                      JOUR,
                      CODECPT,
                      VALEURA,
                      CODEMODELE,
                      TYPEDATA,
                      VALEURD)

           VALUES    ('STRUCTURE',
                      'XXXXXX',
                      TO_DATE ('20190801', 'YYYYMMDD'),
                      '1',
                      'TOG',
                      ' ',
                      ' ',
                      '1',
                      10)
 ON CONFLICT (domaine, struct, datjour, jour, codecpt) DO UPDATE SET VALEURD = matable.VALEURD + 10;

Hors ligne

Pied de page des forums