Как узнать, было ли обновление обновлением PostgreSQL 9.5+ UPSERT?
Записанные CTE считались решением UPSERT до 9.5, как описано вВставить, при повторном обновлении в PostgreSQL?
Можно выполнить UPSERT с информацией о том, закончился ли он как ОБНОВЛЕНИЕ или ВСТАВКА со следующей идиомой записываемых CTE:
WITH
update_cte AS (
UPDATE t SET v = $1 WHERE id = $2 RETURNING 'updated'::text status
),
insert_cte AS (
INSERT INTO t(id, v) SELECT $2, $1 WHERE NOT EXISTS
(SELECT 1 FROM update_cte) RETURNING 'inserted'::text status
)
(SELECT status FROM update_cte) UNION (SELECT status FROM insert_cte)
Этот запрос вернет либо «обновленный», либо «вставленный», либо может (редко) потерпеть неудачу с нарушением ограничения, как описано вhttps://dba.stackexchange.com/questions/78510/why-is-cte-open-to-lost-updates
Можно ли добиться чего-то подобного, используя новый синтаксис «UPSERT» в PostgreSQL 9.5+, выиграв от его оптимизации и избежав возможного нарушения ограничений?