Upsert в PostgreSQL

Ура, появился коммит, добавляющий к оператору INSERT «Постгреса» конструкцию, которая позволяет использовать его как upsert (в «Оракле» это конструкция MERGE, в «Майэскуэеле» — INSERT… ON DUPLICATE KEY UPDATE):

-- Обновить, если не удалась вставка
INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution')
ON CONFLICT (did) DO UPDATE
SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')'
WHERE d.zipcode != '21201';

-- Если не удалась вставка, ничего не делать
INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International')
ON CONFLICT (did) WHERE is_active DO NOTHING;

Счастье-то какое!

Комментарии 5

Олег Волчков № 1
В Майсиквеле апсерт это insert … on duplicate key update … :)
Евгений Степанищев (bolknote.ru) автор № 2
Да? А в чём разница с REPLACE? Я уже очень давно с ним не работаю.
Олег Волчков № 3
Риплейс заменяет всю строку целиком (по сути этотделит плюс инсерт), а инсерт с ондупликейтом позволяет поменять поля, т.е. инсерт плюс апдейт иф екзистс.
Евгений Степанищев (bolknote.ru) автор № 4
Комментарий для Олег Волчков:

Ага, спасибо за разъяснения!
Евгений Степанищев (bolknote.ru) автор № 5
Комментарий для Олег Волчков:

Поправил пост.