2016-04-01 32 views
43

Quando stai inviando una riga (PostgreSQL> = 9.5) e vuoi che il possibile INSERT sia esattamente lo stesso del possibile UPDATE, puoi scriverlo come questo :PostgreSQL INSERT ON CONFLICT UPDATE (upsert) usa tutti i valori esclusi

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 

C'è un modo più breve? Per dire basta: usa tutti i valori EXCLUDE.

In SQLite ho usato per fare:

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

Non è una risposta reale, ma è possibile utilizzare un po 'a breve la notazione: 'INSERT INTO nometabella (id, nome utente, password, livello, e-mail) VALORI (1, 'John', 'QWERTY', 5 , '[email protected]') SU CONFLICT (id) DO UPDATE SET (nome utente, password, livello, email) = (EXCLUDED.username, EXCLUDED.password, EXCLUDED.level, EXCLUDED.email) .' Quasi il lo stesso, ma facile da copiare/incollare/gestire l'elenco delle colonne – foal

+0

Un'altra opzione è usare le colonne jsonb e in questo modo non devi preoccuparti delle colonne –

risposta

53

Postgres non ha messo in atto un equivalente INSERT OR REPLACE. Dal ON CONFLICT docs (sottolineatura mia):

Può essere o non fare niente, o di una clausola UPDATE DO specificando i dettagli esatti dell'azione UPDATE per essere eseguita in caso di conflitto.

Anche se non ti dà una scorciatoia per la sostituzione, ON CONFLICT DO UPDATE vale più in generale, dal momento che consente di impostare i nuovi valori in base ai dati preesistenti. Per esempio:

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