2016-04-01 12 views
43

Wenn Sie eine Zeile (PostgreSQL> = 9.5) aufstellen, und Sie die mögliche INSERT genau die gleiche UPDATE sein möchten, können Sie es wie folgt schreiben :PostgreSQL INSERT AUF KONFLIKT UPDATE (upsert) Verwenden Sie alle ausgeschlossenen Werte

INSERT INTO tablename (id, username, password, level, email) 
       VALUES (1, 'John', 'qwerty', 5, '[email protected]') 
ON CONFLICT (id) DO UPDATE SET 
    id=EXCLUDED.id, username=EXCLUDED.username, 
    password=EXCLUDED.password, level=EXCLUDED.level,email=EXCLUDED.email 

Gibt es einen kürzeren Weg? Um nur zu sagen: verwende alle EXCLUDE-Werte.

In SQLite verwendet ich tun:

INSERT OR REPLACE INTO tablename (id, user, password, level, email) 
         VALUES (1, 'John', 'qwerty', 5, '[email protected]') 
+5

Keine wirkliche Antwort, aber man kann etwas kurz Notation: 'INSERT INTO Tabellennamen (id, Benutzername, Passwort, Ebene, E-Mail) VALUES (1, 'John', 'QWERTZ', 5 , '[email protected]') ON CONFLICT (ID) DO UPDATE SET (Benutzername, Passwort, Ebene, E-Mail) = (EXCLUDED.username, EXCLUDED.password, EXCLUDED.level, EXCLUDED.email). 'Fast die Gleich, aber einfach zu kopieren/einfügen/verwalten Sie die Spaltenliste – foal

+0

Eine andere Option ist die Verwendung von Jsonb-Spalten und auf diese Weise müssen Sie sich nicht um Spalten kümmern –

Antwort

53

Postgres ein Äquivalent zu INSERT OR REPLACE nicht umgesetzt hat. Vom ON CONFLICT docs (Hervorhebung von mir):

Es kann NICHTS entweder DO oder eine UPDATE-Klausel DO die genauen Details der UPDATE-Aktion Angabe im Fall eines Konflikts durchgeführt werden.

Obwohl es nicht, dass Sie für den Ersatz Kurzschrift nicht geben, ON CONFLICT DO UPDATE gilt ganz allgemein, da es können Sie neue Werte basierend auf bereits vorhandenen Daten. Zum Beispiel:

INSERT INTO users (id, level) 
VALUES (1, 0) 
ON CONFLICT (id) DO UPDATE 
SET level = users.level + 1;