0Pricing
SQL Academy · Lezione

UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)

Implementi inserimenti idempotenti con ON CONFLICT DO UPDATE, usi EXCLUDED e scelga il corretto obiettivo del conflitto

UPSERT: ON CONFLICT DO UPDATE (PostgreSQL) è una lezione SQL Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento SQL Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso SQL Academy include 4 lezioni in totale.

Che cos'è UPSERT?

UPSERT significa INSERT se non esiste e UPDATE se esiste. In PostgreSQL si scrive INSERT ... ON CONFLICT.

ON CONFLICT DO NOTHING

Inserire se manca e ignorare in modo silenzioso se è presente un duplicato:

INSERT INTO users (email, full_name)
VALUES ('alice@example.com', 'Alice')
ON CONFLICT (email) DO NOTHING;

ON CONFLICT DO UPDATE

Inserire se manca, altrimenti aggiornare colonne specifiche:

INSERT INTO users (email, full_name, last_login)
VALUES ('alice@example.com', 'Alice', NOW())
ON CONFLICT (email)
DO UPDATE SET
  full_name  = EXCLUDED.full_name,
  last_login = EXCLUDED.last_login;

EXCLUDED: la riga proposta

All'interno di DO UPDATE, EXCLUDED.col indica "il valore che INSERT ha tentato di inserire". Il nome semplice della colonna (oppure users.col) indica la riga esistente.

ON CONFLICT (email)
DO UPDATE SET visits = users.visits + 1,
              last_seen = EXCLUDED.last_seen;

Il target del conflitto

È necessario specificare un vincolo UNIQUE o una chiave primaria:

ON CONFLICT (email)             -- column with UNIQUE
ON CONFLICT (user_id, day)      -- composite UNIQUE
ON CONFLICT ON CONSTRAINT users_email_key   -- by name

UPSERT condizionale (WHERE in DO UPDATE)

Aggiornare solo quando una condizione è verificata:

INSERT INTO inventory (product_id, qty)
VALUES (42, 5)
ON CONFLICT (product_id)
DO UPDATE SET qty = inventory.qty + EXCLUDED.qty
WHERE inventory.qty + EXCLUDED.qty <= 1000;

UPSERT su più righe

Inserire molte righe; ogni riga viene gestita separatamente:

INSERT INTO page_views (path, day, count)
VALUES ('/home', CURRENT_DATE, 1), ('/about', CURRENT_DATE, 1)
ON CONFLICT (path, day)
DO UPDATE SET count = page_views.count + EXCLUDED.count;

RETURNING con UPSERT

Ottenere la riga risultante, sia che sia stata inserita sia che sia stata aggiornata:

INSERT INTO users (email, full_name)
VALUES ('alice@example.com', 'Alice')
ON CONFLICT (email) DO UPDATE
  SET full_name = EXCLUDED.full_name
RETURNING id, full_name;

Flussi di lavoro idempotenti

UPSERT rende sicuri i nuovi tentativi. Se il webhook viene attivato due volte, la seconda chiamata aggiorna la stessa riga invece di crearne un duplicato.

MERGE (standard SQL, PG15+)

PostgreSQL 15 ha aggiunto MERGE, conforme allo standard SQL, che consente di eseguire INSERT, UPDATE e DELETE in un'unica istruzione:

MERGE INTO users AS u
USING (VALUES ('alice@example.com','Alice')) AS src(email, name)
ON u.email = src.email
WHEN MATCHED THEN UPDATE SET full_name = src.name
WHEN NOT MATCHED THEN INSERT (email, full_name) VALUES (src.email, src.name);

Quando NON usare UPSERT

UPSERT richiede un vincolo UNIQUE. Se non ne esiste uno, in genere serve eseguire un SELECT separato seguito da INSERT o UPDATE; attenzione però alle race condition: racchiudere l'operazione in una transazione con un locking appropriato.

Riepilogo

ON CONFLICT è il meccanismo UPSERT pulito e atomico di PostgreSQL.

  • DO NOTHING per "inserire se assente"
  • DO UPDATE per un vero upsert
  • EXCLUDED = la riga proposta
  • Specificare sempre un target del conflitto

Verifica rapida

In ON CONFLICT (email) DO UPDATE SET last_login = EXCLUDED.last_login, a cosa fa riferimento EXCLUDED?

Domande Frequenti

La lezione «UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)» è gratuita?

Sì — il testo completo di «UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso SQL Academy, passa a CoddyKit PRO. Il corso SQL Academy include 4 lezioni in totale.

Cosa imparerò in «UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)»?

Implementi inserimenti idempotenti con ON CONFLICT DO UPDATE, usi EXCLUDED e scelga il corretto obiettivo del conflitto Eserciti SQL Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare SQL Academy?

Non è richiesta alcuna esperienza precedente. SQL Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione SQL Academy?

Sì. Ogni lezione SQL Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. INSERT con più righe
  2. UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)
  3. UPDATE con FROM e aggiornamenti in stile JOIN
  4. DELETE con USING e pattern sicuri
← Torna a SQL Academy