UPSERT - czy istnieje lepsza alternatywa dla MERGE lub @@ rowcount? [Zamknięte]

14

Zastanawiałem się, czy napotkałeś polecenie T-SQL podobne do koncepcji UPSERT? Wykonywanie operacji INSERT | UPDATE przy użyciu opcji (1) lub (2) wydaje się zbyt skomplikowane i podatne na błędy.

CEL

Aby upewnić się, że żądany rekord (w tym przypadku identyfikator_użytkownika 1) jest aktualny BEZ konieczności zasadniczo dwukrotnego napisania tego samego zapytania.

KONTEKST

  • nazwa tabeli: pracownik
  • identyfikator pracownika: ma klucz podstawowy, a właściwość tożsamości ma wartość true

OPCJE

  1. wykonaj aktualizację SQL ... sprawdź @@ rowcount = 0 i @@ error = 0 ... w razie potrzeby uruchom SQL INSERT

    • con: musisz efektywnie napisać to samo zapytanie dwukrotnie, raz jako wstawka, raz jako aktualizacja
    • con: więcej kodu = więcej czasu na pisanie
    • con: więcej kodu = więcej miejsca na błąd

/programming/1106717/how-to-implement-a-conditional-upsert-stored-procedure „Aktualizuj za pomocą @@ rowcount”

  1. wykonać scalenie SQL
    • con: musisz efektywnie napisać to samo zapytanie dwukrotnie, raz jako wstawka, raz jako aktualizacja
    • con: więcej kodu = więcej czasu na pisanie
    • con: więcej kodu = więcej miejsca na błąd

http://technet.microsoft.com/en-us/library/bb510625.aspx „Scalanie T-SQL”

  1. wykonać SQL UPSERT (funkcja nie istnieje)
    • pro: definiujesz relację danych do tabeli raz (pozwól, aby SQL Server martwił się, czy jest to INSERT czy UPDATE)
    • pro: mniej kodu = szybsza implementacja
    • pro: mniej kodu = niższe prawdopodobieństwo

PRZYKŁAD UPSERT

UPSERT pracownik (identyfikator pracownika, numer pracownika, tytuł pracy, imię, drugie imię, nazwisko, zmieniona nazwa) WARTOŚCI (1, „00-124AB37”, „Menedżer”, „John”, „T”, „Smith”, GetDate ());

  • jeśli identyfikator pracownika 1 nie istnieje: MS SQL wykonuje instrukcję INSERT
  • jeśli identyfikator pracownika 1 istnieje: wykonuje się MS SQL i instrukcja UPDATE
Pressacco
źródło
4
Wydaje się, że to prośba o udostępnienie funkcji dla firmy Microsoft, a nie coś, co może tu pomóc ci rozwiązać. Rozwiązaniem opracowanym przez Microsoft jest MERGE. Jeśli to nie jest wystarczająco elastyczne / wydajne, potrzebujesz innego rozwiązania, które jeszcze nie istnieje.
Aaron Bertrand
3
Moim zdaniem MERGEjest prosty, elastyczny, a także jest częścią SQL Standard. Prawdziwym problemem MERGEi innymi UPSERTimplementacjami jest potencjalna eskalacja blokady, a nawet zakleszczenia, które nie mają nic wspólnego ze składnią.
a1ex07
Jeśli masz pytanie, zadaj je. Jak napisano, jest to w zasadzie diatribe o MERGEimplementacji w SQL Server.
JNK
Dobre pytanie - czy istnieje zasadniczo oświadczenie UPSERT, w którym serwer martwi się, czy wymaga wstawienia czy aktualizacji. Zgadzam się, MERGE nie spełnia tego, czego logicznie oczekujesz od wdrożenia „UPSERT”. Biorąc pod uwagę, że stwardnienie rozsiane zdecydowało się zaimplementować w ten sposób, moje pytanie brzmiałoby: co może być wadą lub niemożliwością do wdrożenia, gdyby próbowali wdrożyć składnię, którą chcielibyście (i ja)?
youcantryreachingme

Odpowiedzi:

14

Myślę, że prosta odpowiedź na to pytanie brzmi „nie”. MERGEbyła odpowiedzią Microsoftu na bardziej skomplikowaną UPSERTlogikę. I nawet nie wymieniłeś najgorszego podejścia:

IF (SELECT COUNT ... ) > 0
    UPDATE
ELSE
    INSERT

Właśnie zwymiotowałem w ustach, trochę to pisząc, ale tak naprawdę to ten, który najczęściej widuję.

W każdym razie, jeśli MERGEnie jest wystarczająco elastyczny lub wydajny, sugeruję przesłanie żądania funkcji do firmy Microsoft pod adresem http://connect.microsoft.com/sql/ i dokładne wyjaśnienie swojego uzasadnienia biznesowego. Tak długo, jak trzymasz się prawdziwych zalet proponowanej składni MERGE, masz mój głos. Jeśli zwiesisz zbyt dużo na części „podatnej na błędy”, raczej nie kupię. Dlaczego? Ponieważ możesz wyciągnąć gruby palec z każdego oświadczenia.

To powiedziawszy, nie sądzę, żeby ktokolwiek tutaj mógł coś dla ciebie zrobić. Powinieneś zbadać potencjalne problemy z MERGE:

http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/

Aaron Bertrand
źródło
2
Dzięki Aaron. Przejrzałem dokumentację T-SQL na MSDN i nie mogłem znaleźć tego, czego szukałem; pomyślałem, że wyrzucę to na wypadek, gdyby coś mi umknęło. Chociaż wyrażenie MERGE ma sens w niektórych sytuacjach, nie mogę nie poradzić sobie z tym, że czuję, że jest to „młot kowalski wbijany w gwóźdź” dla prostej operacji zapisywania. Być może powinienem zdjąć czapkę programisty i założyć DBA Fedora. Dziękujemy za poświęcenie czasu na podzielenie się swoimi przemyśleniami.
Pressacco,