Nie taki znów zwykły SQL Server cz. 3 – Merge czyli po prostu UPSERT

Merge, upsert – o co chodzi ?

Merge ? Nigdy tego nie używałem, z tego w ogóle się korzysta ?! Mniej więcej, taka moja była pierwsza reakcja, kiedy napotkałem kod zawierający składnię owego wyrażenia. Otóż używa się i ma wiele zastosowań, gdyż potrafi czasem zastąpić aż trzy różne operacje INSERT, UPDATE, DELETE. Czy istnieje jakieś konkretny uniwersalny przypadek użycia dla MERGE ? Szczerze mówiąc ciężko mi takowy przytoczyć. Podobnie jak w przypadku wcześniej opisywanego WITH potrafi ułatwić rozwiązywanie pewnej klasy problemów, bez angażowania rozbudowanej procedury T-SQL lub języków programowania.

Składnia wyrażenia jest dość skomplikowana na pierwszy rzut oka, jednak po parokrotnym użyciu można szybko poczuć co można uzyskać korzystając z niego, a co jest niemożliwe. Najlepiej zresztą poczuć moc na przykładzie.

Merge – przykład

Wyobraźmy sobie, że mamy przestarzały system zgłoszeniowy, którego statusów potrzebuje nasza aplikacja (np. do wyświetlenia). Oczywiście ten stary system wciąż działa, zatem co jakiś czas muszą przychodzić aktualizacje.

Normalną i częstą praktyką jest, że dane przychodzące z zewnętrznego systemu lądują nie od razu w docelowej tabeli, z której korzysta aplikacja, ale z tabeli pośredniej (staging’owej) z której dopiero są ładowane do tabeli roboczej. Przykładowo szyna integracyjna przysyła nam nową partię danych:

A więc na naszej tabeli mamy:

A tabela staging’owa z aktualizacjami wygląda mniej więcej tak:

Chcąc wyrównać te dane standardową drogą powinniśmy. Napisać SELECT’a który znajdzie odpowiadające sobie wiersze, a następnie wykona UPDATE kolumn statusowych, a  w przypadku gdy danego id nie ma na bazie zostanie wykonany INSERT. Trochę kodu do napisania przed nami… Otóż nie!

W wyniku otrzymamy syntezę dwóch tabel:

Podsumowanie

Merge potrafi scalić kilka instrukcji w jedną, jednak niestety nie jest super wydajny – konieczny jest każdorazowy pełny skan tabeli. Z drugiej strony, czy powierzając te same zadania kilku insert’om, update’om uzyskamy lepszą wydajność ? Warto zwrócić uwagę na jeszcze jedną ciekawą rzecz. To wszystko jest część standardu SQL:2003! Niestety z implementacją w różnych SZBD nie ma już tak dobrze – najgorzej jest w tym przypadku z Postgres’em. Poszczególni dostawcy zadbali jednak o swoje odpowiedniki i rozszerzenia, zatem gdy musicie znaleźć coś podobnego wpisujcie UPSERT <Nazwa waszego dostawcy>.

To by było na tyle. Standardowo dzięki wszystkim, którzy dotarli aż tutaj! 🙂

 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *