it-swarm.com.de

Richtiges Upsert in Postgres 9.5

korrekte Syntax von Upsert mit Postgresql 9.5, unten Abfrage zeigt column reference "gallery_id" is ambiguous Fehler, warum?

var dbQuery = `INSERT INTO category_gallery (
  category_id, gallery_id, create_date, create_by_user_id
  ) VALUES ($1, $2, $3, $4)
  ON CONFLICT (category_id)
  DO UPDATE SET
  category_id = $1,
  last_modified_date = $3,
  last_modified_by_user_id = $4
  WHERE gallery_id = $2`;

Ich habe versucht, WHERE gallery_id = $2; bis WHERE category_gallery.gallery_id = $2; zeigt dann Fehler there is no unique or exclusion constraint matching the ON CONFLICT specification, aber ich möchte gallery_id oder category_id nicht als eindeutig festlegen weil ich sicherstellen möchte, dass beide Spalten gleich sind, dann aktualisiere ...

Wie man in postgres 9.5 richtig upsert?

ob ON CONFLICT Benötige eine eindeutige Spalte, sollte ich eine andere Methode verwenden, wie?



Ich möchte sicherstellen, dass mehrere Spalten in Konflikt stehen und dann aktualisieren, was die richtige Verwendung ist

var dbQuery = `INSERT INTO category_gallery (
  category_id, gallery_id, create_date, create_by_user_id
  ) VALUES ($1, $2, $3, $4)
  ON CONFLICT (category_id, gallery_id)
  DO UPDATE SET
  category_id = $1,
  last_modified_date = $3,
  last_modified_by_user_id = $4
  WHERE gallery_id = $2`;


var dbQuery = `INSERT INTO category_gallery (
  category_id, gallery_id, create_date, create_by_user_id
  ) VALUES ($1, $2, $3, $4)
  ON CONFLICT (category_id AND gallery_id)
  DO UPDATE SET
  category_id = $1,
  last_modified_date = $3,
  last_modified_by_user_id = $4
  WHERE gallery_id = $2`;

tabelle (category_id, gallery_id keine eindeutige Spalte)

category_id | gallery_id | create_date | create_by_user_id | last_modified_date | last_modified_by_user_id
1 | 1 | ...  
1 | 2 | ...
2 | 2 | ...
1 | 3 | ...
27
user1575921

Das ON CONFLICT Konstrukt benötigt eine UNIQUE Einschränkung, um zu funktionieren. Aus der Dokumentation zu INSERT .. ON CONFLICT Klausel :

Die Wahl ON CONFLICT-Klausel gibt eine alternative Aktion zum Auslösen einer eindeutigen Verletzung oder Ausschlussbedingung Verstoß Fehler. Für jede einzelne Zeile, die zum Einfügen vorgeschlagen wird, wird entweder die Einfügung fortgesetzt, oder wenn eine durch conflict_target angegebene Arbiter-Einschränkung oder ein durch conflict_target angegebener Index verletzt wird, wird die alternative conflict_action verwendet. ON CONFLICT DO NOTHING vermeidet einfach das Einfügen einer Zeile als alternative Aktion. ON CONFLICT DO UPDATE aktualisiert die vorhandene Zeile, die mit der als alternative Aktion vorgeschlagenen Zeile in Konflikt steht.

Nun ist die Frage nicht sehr klar, aber Sie benötigen wahrscheinlich eine UNIQUE -Einschränkung für die beiden kombinierten Spalten: (category_id, gallery_id).

ALTER TABLE category_gallery
    ADD CONSTRAINT category_gallery_uq
    UNIQUE (category_id, gallery_id) ;

Wenn die einzufügende Zeile mit beiden Werten einer bereits in der Tabelle vorhandenen Zeile übereinstimmt, führen Sie anstelle von INSERT ein UPDATE:

INSERT INTO category_gallery (
  category_id, gallery_id, create_date, create_by_user_id
  ) VALUES ($1, $2, $3, $4)
  ON CONFLICT (category_id, gallery_id)
  DO UPDATE SET
    last_modified_date = EXCLUDED.create_date,
    last_modified_by_user_id = EXCLUDED.create_by_user_id ;

Sie können entweder die Spalten der UNIQUE-Einschränkung verwenden:

  ON CONFLICT (category_id, gallery_id) 

oder der Name der Einschränkung:

  ON CONFLICT ON CONSTRAINT category_gallery_uq  
52
ypercubeᵀᴹ

Als vereinfachte Alternative zu der aktuell akzeptierten Antwort kann die UNIQUE -Einschränkung beim Erstellen der Tabelle anonym hinzugefügt werden:

CREATE TABLE table_name (
    id  TEXT PRIMARY KEY,
    col TEXT,
    UNIQUE (id, col)
);

Dann wird die Upsert-Abfrage (ähnlich zu dem, was bereits beantwortet wurde):

INSERT INTO table_name (id, col) VALUES ($1, $2)
ON CONFLICT (id, col)
    DO UPDATE SET col = $2;
5
Erik