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 nameWarunkowy 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
EXCLUDEDoznacza 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
- INSERT z wieloma wierszami
- UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)
- UPDATE z FROM i aktualizacje w stylu JOIN
- DELETE z USING i bezpieczne wzorce