PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Mehrdeutiger Spaltenverweis in INSERT ... ON CONFLICT DO UPDATE

Sie müssen die Spalte dort tabellenqualifizieren, wo sie sonst mehrdeutig wäre.
Verwenden Sie den Namen der virtuellen Tabelle excluded um auf die Eingabezeile zu verweisen. Aber Sie möchten wahrscheinlich auf die Zielspalte verweisen, also qualifizieren Sie sich mit dem Namen der Zieltabelle:

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

Das Handbuch:

Die einzelne Zeile aus der virtuellen Eingabetabelle excluded enthält alle Spalten der Zieltabelle, auch wenn sie nicht in der Zielspaltenliste von INSERT aufgeführt sind oder die VALUES Ausdruck. Die Mehrdeutigkeit, auf die Sie gestoßen sind, ist also immer da, egal ob count gezielt angesteuert wird oder nicht.

Übrigens:Spalten, die in der Zielspaltenliste ausgelassen werden, werden standardmäßig in ihrer jeweiligen Spalte DEFAULT verwendet Wert, der NULL ist standardmäßig (NULL Dabei handelt es sich um die Standardspalte DEFAULT ). Das heißt, es wäre standardmäßig NULL in Ihrem Setup und 1 in meinem verbesserten Setup unten. Und Trigger auf Zeilenebene BEFORE INSERT (falls vorhanden) angewendet werden.

Aber beides trifft nicht auf das Beispiel zu, da es sich auf das Ziel bezieht Spalte immerhin.

Insbesondere die anderen beiden Instanzen des Spaltennamens count sind eindeutig (und erfordern daher keine Tabellenqualifikation), da diese sich nur auf das Ziel beziehen können Tabelle.

Ihr Setup kann leicht kaputt gehen, während die Spalte count ist nicht definiert NOT NULL , als NULL + 1 ist immer noch NULL . Dieses Setup wäre sinnvoller:

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

Ich verwende in meinem Beispiel auch keine CaMeL-Case-Namen in Anführungszeichen. Siehe: