sql >> Database >  >> RDS >> PostgreSQL

Dubbelzinnige kolomverwijzing in INSERT ... ON CONFLICT DO UPDATE

U moet de kolom kwalificeren waar deze anders dubbelzinnig zou zijn.
Gebruik de virtuele tabelnaam excluded om naar de invoerregel te verwijzen. Maar u wilt waarschijnlijk verwijzen naar de doelkolom, dus kwalificeer u met de naam van de doeltabel:

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

De handleiding:

De enkele rij uit de virtuele invoertabel excluded bevat alle kolommen van de doeltabel, zelfs als deze niet worden vermeld in de doelkolomlijst van de INSERT of de VALUES uitdrukking. Dus de dubbelzinnigheid die je tegenkwam is er altijd, of het nu gaat om count expliciet wordt getarget of niet.

Terzijde:kolommen die zijn weggelaten in de lijst met doelkolommen, worden standaard in hun respectieve kolom DEFAULT waarde, die NULL . is standaard (NULL zijnde de standaardkolom DEFAULT ). D.w.z. het zou standaard NULL . zijn in je setup en 1 in mijn verbeterde setup hieronder. En triggers op rijniveau BEFORE INSERT (indien aanwezig) worden toegepast.

Maar geen van beide is van toepassing op het voorbeeld, aangezien het verwijst naar het doel kolom toch.

Met name de andere twee instanties van de kolomnaam count zijn ondubbelzinnig (en vereisen dus geen tabelkwalificatie) omdat deze alleen kunnen verwijzen naar het doel tafel.

Je setup kan gemakkelijk breken terwijl de kolom count is niet gedefinieerd NOT NULL , als NULL + 1 is nog steeds NULL . Deze opstelling zou logischer zijn:

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

Ook geen gebruik van geciteerde CaMeL-case-namen in mijn voorbeeld. Zie:




  1. Hoe zorg ik ervoor dat Java &Postgres-enums samenwerken voor update?

  2. Oracle-querygegevens waarbij kolomwaarde met komma om te controleren of de waarde al dan niet bevat

  3. Pas `trim()` en `regexp_replace()` toe op tekstarray

  4. Als een site in een omgeving met meerdere servers langer dan 15 minuten inactief is, verliest de server de verbinding met de PostgreSQL-database