SQLShack (Polski)
Kursory SQL Server to częsty temat w Internecie . Znajdziesz różne opinie, kiedy ich używać, a kiedy nie. Dzisiaj również o nich porozmawiamy i odpowiemy na pytanie, kiedy (nie) ich używać.
Model danych i ogólna idea
W poprzednim artykule, Wprowadzenie do SQL Pętle serwera, mówiliśmy o pętlach SQL Server, ale nie używaliśmy danych z bazy danych. To było dziwne, ale teraz powinno to stać się znacznie jaśniejsze. Dzisiaj, wyjaśniając kursory, użyjemy danych z bazy danych, aby pokazać, kiedy (nie) używać kursorów. Model danych, którego będziemy używać, jest tym samym, którego używamy w całej tej serii.
SQL Server obsługuje 3 różne implementacje kursorów – kursory języka Transact-SQL, kursory API i kursory klienta. W tym artykule skupimy się na kursorach Transact-SQL. Rozpoznasz je łatwo, ponieważ są one oparte na składni DECLARE CURSOR.
Kursor SQL Server – wprowadzenie
Zanim przejdziemy do kodu i przykładów, powinniśmy wyjaśnić, jakie kursory SQL Server są.
Kursor programu SQL Server jest logiką T-SQL, która pozwala nam przeglądać pokrewny wynik zapytania. Umożliwia nam to wykonywanie działań sekwencyjnie – np. Wykonanie aktualizacji w jednym wierszu.
Czasami może to (wydawać się) pomocne, ale podczas pracy z bazami danych nie należy używać proceduralnych wzorców programowania ale raczej trzymaj się programowania deklaratywnego. Jednym z głównych powodów jest to, że systemy DBMS są już zoptymalizowane do wykonywania działań na zbiorach danych, a zatem nie powinieneś być tym, który stara się być „mądrzejszy od systemu”.
Mimo wszystko to dobrze żeby wiedzieć, jak działają. Jeśli nic więcej, może spotkasz je w kodzie, który odziedziczysz, i będziesz musiał przepisać logikę. Zanim cokolwiek zrobisz, powinieneś zrozumieć, jak to działa.
Więc jeśli potrzebujesz kursorów, oto co powinieneś o nich wiedzieć:
- Kursory używają zmiennych do przechowywania wartości zwracanych w każdej części pętli. Dlatego musisz ZADEKLAROWAĆ wszystkie potrzebne zmienne
- Następną rzeczą do zrobienia jest zadeklarowanie zapytania… CURSOR FOR SELECT, w którym zadeklarujesz kursor, a także zdefiniujesz zapytanie związane z (zapełnieniem) tego kursora
- Otworzysz kursor i FETCH NEXT z kursora
- W pętli WHILE przetestujesz zmienną @@ FETCH_STATUS (WHILE @@ FETCH_STATUS = 0). Jeśli warunek zostanie spełniony, Wejdę w pętlę BEGIN … END blok i wykonaj instrukcje wewnątrz tego bloku
- Po przejściu przez cały zestaw wyników wyjdziesz z pętli. Powinieneś ZAMKNĄĆ kursor i ZWOLNIĆ go. Zwalnianie jest ważne, ponieważ spowoduje to usunięcie definicji kursora i zwolnienie używanej pamięci
Kursor SQL Server – przykłady
Przyjrzyjmy się teraz dwóm przykładom kursorów. Chociaż są dość proste, ładnie wyjaśniają, jak działają kursory.
W pierwszym przykładzie chcemy uzyskać wszystkie identyfikatory i nazwy miast wraz z powiązanymi nazwami krajów. Użyjemy polecenia PRINT, aby wydrukować kombinacje w każdym przebiegu pętli.
Używając kursora SQL Server i pętla while zwróciła dokładnie to, czego się spodziewaliśmy – identyfikatory i nazwy wszystkich miast i powiązanych krajów, które mamy w bazie danych.
Najważniejszą rzeczą, o której należy tutaj wspomnieć, jest to, że możemy po prostu zwrócić ten zestaw wyników używając oryginalnego zapytania SQL zapisanego w części DECLARE kursora, więc kursor nie był potrzebny.
Pójdziemy z jeszcze jednym przykładem. Tym razem zapytamy bazę danych schematu informacji, aby zwrócić pierwsze 5 tabel uporządkowanych według nazwy tabeli. Chociaż nie ma sensu używać takiego zapytania, ten przykład pokazuje:
- Jak przeszukiwać bazę danych schematu informacji
- Jak połączyć kilka poleceń / stwierdzeń, wspomniałem w poprzednich artykułach (IF… ELSE, WHILE loop, CONCAT)
Od strony kodowania, Chciałbym podkreślić, że tym razem nie wydrukowaliśmy niczego w pętli, a raczej utworzyliśmy ciąg za pomocą CONCAT. Ponadto użyliśmy instrukcji IF, aby sprawdzić, czy jesteśmy w pierwszym przebiegu, a jeśli tak, to nie dodaliśmy znaku „,”. W przeciwnym razie dodalibyśmy „,” do ciągu.
Po wykonaniu pętli wypisaliśmy ciąg wynikowy, zamknęliśmy i zwolniliśmy kursor.
Moglibyśmy to osiągnąć za pomocą funkcji STRING_AGG. Ten jest dostępny począwszy od SQL Server 2017 i jest odpowiednikiem funkcji MySQL GROUP_CONCAT.
Kursor SQL Server – kiedy (nie) ich używać?
Spróbuję udzielić obiektywnej odpowiedzi na pytanie – „Kiedy należy używać kursorów SQL Server, a kiedy nie”? Ponieważ rzeczy zmieniają się w czasie i należy wprowadzać ulepszenia, albo na kursorach, albo na innych obiektach, które je „zastępują”, weź pod uwagę datę napisania tego artykułu.Więc zacznijmy.
Nie należy używać kursorów:
- Prawie zawsze 🙂 Może to zabrzmieć głupio, ale w większości przypadków tak jest. SQL Server implementuje dużą liczbę obiektów & funkcji, które robią dokładnie to, co prawdopodobnie próbowałbyś rozwiązać za pomocą kursorów. Przed podjęciem decyzji o przejściu z kursorem upewnij się, że zbadałeś wystarczająco dużo, aby stwierdzić, że kursor jest jedynym możliwym (dobrym) rozwiązaniem. To samo dotyczy pętli w bazach danych. W poprzednim artykule, Wprowadzenie do pętli SQL Server, używaliśmy pętli, ale nie używaliśmy pętli przez dane.
Możesz użyć kursorów:
- Głównie do zadań związanych z administrowaniem bazami danych, takich jak tworzenie kopii zapasowych, sprawdzanie integralności, odbudowywanie indeksów
- jednorazowe zadania, gdy masz pewność, że ewentualna niska wydajność nie wpłynie na ogólną wydajność systemu
-
Kilkukrotne wywołanie procedury składowanej przy użyciu różnych parametrów. W takim przypadku należy pobrać parametry ze zmiennych kursora i wywołać wywołania wewnątrz pętli
Wywołanie procedury składowanej lub innego zapytania wewnątrz kursora (lub pętli) ma duży wpływ na wydajność, ponieważ w każdym kroku pętla kursora, uruchomisz zapytanie / procedurę od początku. Jeśli zdecydujesz się to zrobić, pamiętaj o możliwych konsekwencjach.
- Poprzednia wskazówka prowadzi nas do ostatniego punktu, w którym należy używać kursorów. Jeśli jesteś całkowicie świadomy tego, jak działają i jesteś prawie pewien, że nie wpłynie to na wydajność, zrób to
SQL Server Cursor – Dlaczego ludzie (nie) ich używają ?
Ostatnie pytanie, na które chciałbym odpowiedzieć, brzmi: po co ktoś miałby używać kursora? Oto jak to widzę:
- Osoby, które używają ich do jednorazowych prac lub do regularnych działań, gdzie nie mają one wpływu na wydajność, mają wymówkę. Jednym z powodów jest to, że taki kod jest kodem proceduralnym i jeśli jesteś do niego przyzwyczajony, jest bardzo czytelny
- Z drugiej strony ci, którzy zaczęli uczyć się o bazach danych i są przyzwyczajeni do programowania proceduralnego, mogą używają kursorów, ponieważ, jak wspomniano, są one znacznie bliższe programowaniu proceduralnemu niż bazom danych. To nie jest powód, aby ich używać, ponieważ jedyną wymówką byłoby to, że po prostu nie znasz innego (właściwego) sposobu wykonywania zadań
- Najważniejszą rzeczą w przypadku kursorów jest to, że są powolne w porównaniu do instrukcji SQL, dlatego powinieneś ich unikać, ponieważ wcześniej czy później doprowadzą one do problemów z wydajnością (chyba że wiesz dokładnie, co robisz i dlaczego)
I uznasz za przydatne zrozumienie pojęcia kursorów, ponieważ istnieje duża szansa, że spotkasz je po drodze. Były popularne przed dodaniem nowych opcji do SQL Server. Istnieje również szansa, że będziesz kontynuować pracę w systemie, w którym ktoś wcześniej ich użył, i będziesz musiał kontynuować w miejscu, w którym się zatrzymał. Może będziesz musiał zamienić kursor (kod proceduralny) na SQL (kod deklaratywny).
Podsumowanie
Nie ma lepszego wniosku na temat kursorów niż – nie używaj ich 🙂 SQL Server wprowadził wiele zmian, które rozwiązują problemy, które wcześniej były trudne do rozwiązania przy użyciu kodu deklaratywnego. Lepiej poświęć trochę czasu na zbadanie i nauczenie się czegoś nowego, a na koniec stworzyć optymalny kod. Oczywiście możesz z nich korzystać, jeśli wiesz, dlaczego to robisz i wiesz o możliwych problemach z nimi związanych.
Spis treści
Naucz się języka SQL : CREATE DATABASE & CREATE TABLE Operations
Nauka języka SQL: WSTAWIANIE DO TABELI
Nauka języka SQL: klucz podstawowy
Nauka SQL: klucz obcy
Nauka SQL: instrukcja SELECT
Nauka SQL: INNER JOIN vs LEFT JOIN
Naucz się SQL: skrypty SQL
Naucz się SQL: typy relacji
Naucz się SQL: łącz wiele tabel
Naucz się SQL: funkcje agregujące
Naucz się SQL: jak napisać złożone zapytanie SELECT?
Naucz się SQL: Baza danych INFORMATION_SCHEMA
Naucz się języka SQL: Typy danych SQL
Naucz się SQL: Teoria zbiorów
Nauka języka SQL: funkcje zdefiniowane przez użytkownika
Nauka języka SQL: procedury składowane zdefiniowane przez użytkownika
Nauka języka SQL: widoki SQL
Nauka języka SQL: wyzwalacze SQL
Nauka języka SQL: ćwiczenie zapytań SQL
Nauka języka SQL: przykłady zapytań SQL
Nauka języka SQL: ręczne tworzenie raportów za pomocą zapytań SQL
Nauka języka SQL: funkcje daty i godziny w programie SQL Server
Nauka języka SQL: tworzenie raportów w programie SQL Server używanie funkcji daty i czasu
Naucz się SQL: tabele przestawne programu SQL Server
Naucz się języka SQL: eksport programu SQL Server do programu Excel
Learn SQL: Wprowadzenie do pętli SQL Server
Learn SQL: SQL Server Cursors
Learn SQL: SQL Best Practices for Delete and Updating data
Naucz się języka SQL: Konwencje nazewnictwa
Naucz się języka SQL: Zadania związane z SQL
Naucz się języka SQL: Łączenia nierównomierne w SQL Server
Nauka języka SQL: wstrzykiwanie SQL
- Autor
- Najnowsze posty
Jego przeszłe i obecne zadania obejmują różne dziedziny, od projektowania i kodowania baz danych po nauczanie, doradztwo i pisanie o bazach danych. Nie zapominajmy też, BI, tworzenie algorytmów, szachy, filatelistyka, 2 psy, 2 koty, 1 żona, 1 dziecko …
Możesz go znaleźć na LinkedIn
Wyświetl wszystkie posty Emila Drkusica
- Learn SQL: SQL Injection – 2 listopada 2020 r.
- Learn SQL: Non-Equi Joins in SQL Server – 29 września 2020 r.
- Learn SQL: Praca związana z SQL – 1 września 2020 r.