Jak UPSERT (MERGE, INSERT… ON DUPLICATE UPDATE) w PostgreSQL?
Bardzo często zadawanym pytaniem jest, jak zrobić upsert, co wywołuje MySQLINSERT ... ON DUPLICATE UPDATE
i standardowe podpory jako częśćMERGE
operacja.
Biorąc pod uwagę, że PostgreSQL nie obsługuje go bezpośrednio (przed pg 9.5), jak to zrobić? Rozważ następujące:
CREATE TABLE testtable (
id integer PRIMARY KEY,
somedata text NOT NULL
);
INSERT INTO testtable (id, somedata) VALUES
(1, 'fred'),
(2, 'bob');
Teraz wyobraź sobie, że chcesz „wzmocnić” krotki(2, 'Joe')
, (3, 'Alan')
, więc nowa zawartość tabeli będzie:
(1, 'fred'),
(2, 'Joe'), -- Changed value of existing tuple
(3, 'Alan') -- Added new tuple
O tym mówią ludzie podczas omawianiaupsert
. Co najważniejsze, każde podejście musi byćbezpieczne w obecności wielu transakcji pracujących na tej samej tabeli - albo poprzez użycie jawnego blokowania, albo w inny sposób broniąc się przed wynikającymi z tego warunkami wyścigu.
Ten temat jest szeroko omawiany na stronieWstaw, przy duplikacie aktualizacji w PostgreSQL?, ale to jest alternatywa dla składni MySQL, i z czasem stała się niezbyt szczegółowa. Pracuję nad ostatecznymi odpowiedziami.
Techniki te są także użyteczne dla „wstawiania, jeśli nie istnieją, w przeciwnym razie nic nie robić”, tj. „Wstawić ... na duplikacie klucza ignorować”.