Очень часто задаваемый вопрос заключается в том, как выполнить upsert, что MySQL вызывает INSERT ... ON DUPLICATE UPDATE
, а стандартный поддерживает как часть операции MERGE
.
Учитывая, что PostgreSQL не поддерживает его напрямую (до pg 9.5), как вы это делаете? Рассмотрим следующее:
CREATE TABLE testtable (
id integer PRIMARY KEY,
somedata text NOT NULL
);
INSERT INTO testtable (id, somedata) VALUES
(1, 'fred'),
(2, 'bob');
Теперь представьте, что вы хотите "обновить" кортежи (2, 'Joe')
, (3, 'Alan')
, поэтому новое содержимое таблицы будет:
(1, 'fred'),
(2, 'Joe'), -- Changed value of existing tuple
(3, 'Alan') -- Added new tuple
Об этом говорят люди при обсуждении upsert
. Крайне важно, что любой подход должен быть безопасным при наличии нескольких транзакций, работающих в одной и той же таблице, - либо с помощью явной блокировки, либо в противном случае защитой от возникающих условий гонки.
Этот раздел подробно обсуждается в Вставить, при повторном обновлении в PostgreSQL?, но об альтернативах синтаксису MySQL, и он стал честным немного несвязанных деталей со временем. Я работаю над окончательными ответами.
Эти методы также полезны для "вставки, если не существует, в противном случае ничего не делают", т.е. "вставить... при дублировании ключа игнорировать".