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;
Счастье-то какое!
В Майсиквеле апсерт это insert ... on duplicate key update ... :)
Комментарий для Олег Волчков:
Да? А в чём разница с REPLACE? Я уже очень давно с ним не работаю.
Риплейс заменяет всю строку целиком (по сути этотделит плюс инсерт), а инсерт с ондупликейтом позволяет поменять поля, т. е. инсерт плюс апдейт иф екзистс.
Комментарий для Олег Волчков:
Ага, спасибо за разъяснения!
Комментарий для Олег Волчков:
Поправил пост.