PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Riferimento di colonna ambiguo in INSERT... ON CONFLICT DO UPDATE

Devi qualificare come tabella la colonna in cui sarebbe altrimenti ambigua.
Utilizza il nome della tabella virtuale excluded per fare riferimento alla riga di input. Ma probabilmente vuoi fare riferimento alla colonna di destinazione, quindi qualifica con il nome della tabella di destinazione:

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

Il manuale:

La singola riga dalla tabella di input virtuale excluded contiene tutto colonne della tabella di destinazione, anche se non elencate nell'elenco delle colonne di destinazione di INSERT o i VALUES espressione. Quindi l'ambiguità che hai riscontrato è sempre presente, indipendentemente dal fatto che count è preso di mira in modo esplicito o meno.

A parte:le colonne omesse nell'elenco delle colonne di destinazione hanno per impostazione predefinita la rispettiva colonna DEFAULT valore, che è NULL per impostazione predefinita (NULL essendo la colonna predefinita DEFAULT ). Cioè, per impostazione predefinita sarebbe NULL nella tua configurazione e 1 nella mia configurazione migliorata di seguito. E attiva a livello di riga BEFORE INSERT (se presenti).

Ma nessuno dei due si applica all'esempio in quanto si riferisce all'obiettivo colonna dopo tutto.

In particolare, le altre due istanze del nome della colonna count sono inequivocabili (e quindi non richiedono la qualificazione al tavolo) in quanto possono riferirsi solo all'obiettivo tabella.

La tua configurazione può facilmente interrompersi mentre la colonna count non è definito NOT NULL , come NULL + 1 è ancora NULL . Questa configurazione avrebbe più senso:

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

Inoltre, nel mio esempio non utilizzo i nomi dei casi CaMeL tra virgolette. Vedi: