PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Référence de colonne ambiguë dans INSERT ... ON CONFLICT DO UPDATE

Vous devez qualifier de table la colonne là où elle serait autrement ambiguë.
Utilisez le nom de table virtuelle excluded pour faire référence à la ligne d'entrée. Mais vous voulez probablement faire référence à la colonne cible, alors qualifiez-vous avec le nom de la table cible :

INSERT INTO test.test_counter (id)
VALUES ('id-0')
ON CONFLICT (id) DO UPDATE
SET count = test_counter.count + 1  -- here
RETURNING count;

Le manuel :

La ligne unique de la table d'entrée virtuelle excluded contient tous colonnes de la table cible, même si elles ne figurent pas dans la liste des colonnes cible du INSERT ou les VALUES expression. Ainsi, l'ambiguïté que vous avez rencontrée est toujours là, que ce soit count est ciblé explicitement ou non.

À côté :les colonnes omises dans la liste des colonnes cibles sont définies par défaut sur leur colonne respective DEFAULT valeur, qui est NULL par défaut (NULL étant la colonne par défaut DEFAULT ). C'est-à-dire qu'il serait par défaut NULL dans votre configuration et 1 dans ma configuration améliorée ci-dessous. Et les déclencheurs au niveau de la ligne BEFORE INSERT (le cas échéant) sont appliqués.

Mais rien de tout cela ne s'applique à l'exemple car il fait référence à la cible colonne après tout.

Notamment, les deux autres instances du nom de colonne count sont sans ambiguïté (et ne nécessitent donc pas de qualification de table) car celles-ci ne peuvent se référer qu'à la cible tableau.

Votre configuration peut facilement se casser pendant que la colonne count n'est pas défini NOT NULL , comme NULL + 1 est toujours NULL . Cette configuration aurait plus de sens :

CREATE TABLE test.test_counter (
  id    text PRIMARY KEY
, count integer NOT NULL DEFAULT 1
);

Ne pas utiliser non plus les noms de cas CaMeL entre guillemets dans mon exemple. Voir :