0Pricing
SQL Academy · Lekcja

UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)

Implementuj idempotentne wstawianie za pomocą ON CONFLICT DO UPDATE, używaj EXCLUDED i wybieraj właściwy cel konfliktu.

UPSERT: ON CONFLICT DO UPDATE (PostgreSQL) to bezpłatna lekcja SQL Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej SQL Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs SQL Academy zawiera 4 lekcji w sumie.

Czym jest UPSERT?

UPSERT oznacza: INSERT, jeśli wiersz nie istnieje, oraz UPDATE, jeśli już istnieje. W PostgreSQL zapisuje się go jako INSERT ... ON CONFLICT.

ON CONFLICT DO NOTHING

Wstawienie wiersza, jeśli go brakuje, i ciche pominięcie go, jeśli jest duplikatem:

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

ON CONFLICT DO UPDATE

Wstawienie wiersza, jeśli go brakuje, a w przeciwnym razie zaktualizowanie wybranych kolumn:

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: proponowany wiersz

Wewnątrz DO UPDATE wyrażenie EXCLUDED.col oznacza „wartość, którą INSERT próbował wstawić”. Sama nazwa kolumny (lub users.col) oznacza wartość istniejącego wiersza.

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

Wskazanie konfliktu

Należy wskazać ograniczenie UNIQUE lub klucz główny:

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

Warunkowy UPSERT (WHERE w DO UPDATE)

Aktualizacja tylko wtedy, gdy spełniony jest określony warunek:

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;

Wielowierszowy UPSERT

Wstawianie wielu wierszy, z których każdy jest obsługiwany osobno:

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 z UPSERT

Pobranie wynikowego wiersza — niezależnie od tego, czy został wstawiony, czy zaktualizowany:

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;

Idempotentne przepływy pracy

UPSERT sprawia, że ponowienie operacji jest bezpieczne. Jeśli webhook zostanie wywołany dwukrotnie, drugie wywołanie zaktualizuje ten sam wiersz zamiast utworzyć duplikat.

MERGE (standard SQL, PG15+)

PostgreSQL 15 dodał zgodne ze standardem SQL polecenie MERGE, które może wykonać INSERT, UPDATE i DELETE w jednym poleceniu:

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);

Kiedy nie używać UPSERT

UPSERT wymaga ograniczenia UNIQUE. Jeśli go nie ma, zwykle należy wykonać osobne SELECT, a następnie INSERT lub UPDATE — trzeba jednak uważać na wyścigi; operację należy umieścić w transakcji z odpowiednim blokowaniem.

Podsumowanie

ON CONFLICT to przejrzysty i atomowy UPSERT w PostgreSQL.

  • DO NOTHING służy do „wstawiania, jeśli wiersz nie istnieje”
  • DO UPDATE służy do właściwego upsertu
  • EXCLUDED oznacza proponowany wiersz
  • Zawsze należy wskazać cel konfliktu

Szybki test

W wyrażeniu ON CONFLICT (email) DO UPDATE SET last_login = EXCLUDED.last_login do czego odnosi się EXCLUDED?

Często zadawane pytania

Czy lekcja „UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)” jest bezpłatna?

Tak — pełny tekst „UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu SQL Academy, przejdź na CoddyKit PRO. Kurs SQL Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)”?

Implementuj idempotentne wstawianie za pomocą ON CONFLICT DO UPDATE, używaj EXCLUDED i wybieraj właściwy cel konfliktu. Ćwiczysz SQL Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć SQL Academy?

Nie wymagamy żadnego doświadczenia. SQL Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji SQL Academy?

Tak. Każda lekcja SQL Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. INSERT z wieloma wierszami
  2. UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)
  3. UPDATE z FROM i aktualizacje w stylu JOIN
  4. DELETE z USING i bezpieczne wzorce
← Powrót do SQL Academy