SQLLab
Глоссарий/UPSERT (ON CONFLICT)
PostgreSQLСредний

UPSERT (ON CONFLICT)

Вставляет строку или обновляет её при конфликте уникального ключа. Атомарная операция.

Синтаксис
INSERT INTO table (cols) VALUES (...)
ON CONFLICT (unique_col) DO UPDATE
  SET col = EXCLUDED.col;

Объяснение

UPSERT = INSERT + UPDATE при конфликте. В PostgreSQL: ON CONFLICT DO UPDATE или ON CONFLICT DO NOTHING. Атомарен — нет race condition между проверкой и вставкой. Безопаснее, чем проверять через SELECT + INSERT/UPDATE в приложении.

Пример

-- Атомарный счётчик
INSERT INTO page_views (page, views) VALUES ('home', 1)
ON CONFLICT (page) DO UPDATE
  SET views = page_views.views + 1;

-- Обновить профиль или создать
INSERT INTO profiles (user_id, bio) VALUES ($1, $2)
ON CONFLICT (user_id) DO UPDATE
  SET bio = EXCLUDED.bio, updated_at = NOW();