Я обновляю базу данных Postgres 8.4 (из кода С#), и основная задача достаточно проста: либо ОБНОВЛЯЙТЕ существующую строку, либо INSERT - новую, если она еще не существует. Обычно я бы сделал это:
UPDATE my_table
SET value1 = :newvalue1, ..., updated_time = now(), updated_username = 'evgeny'
WHERE criteria1 = :criteria1 AND criteria2 = :criteria2
и если были затронуты 0 строк, выполните INSERT:
INSERT INTO my_table(criteria1, criteria2, value1, ...)
VALUES (:criteria1, :criteria2, :newvalue1, ...)
Тем не менее, есть небольшой поворот. Я не хочу менять столбцы updated_time и updated_username, если какое-либо из новых значений фактически не отличается от существующих значений, чтобы не вводить в заблуждение пользователей о том, когда данные были обновлены.
Если бы я только делал UPDATE, тогда я мог бы добавить условия WHERE для этих значений, но это не будет работать, потому что, если БД уже обновлена, UPDATE будет влиять на 0 строк, а затем я попытаюсь к INSERT.
Может ли кто-нибудь подумать об элегантном способе сделать это, кроме SELECT, затем либо ОБНОВИТЬ, либо ВСТАВИТЬ?