Database
 sql >> Baza danych >  >> RDS >> Database

Jak używać kursorów SQL do celów specjalnych

W tym artykule opisano kursory SQL i sposób ich użycia do niektórych specjalnych celów. Podkreśla znaczenie kursorów SQL wraz z ich wadami.

Nie zawsze jest tak, że używasz kursora SQL w programowaniu baz danych, ale ich zrozumienie pojęć i nauka, jak ich używać, bardzo pomaga zrozumieć, jak wykonywać wyjątkowe zadania w programowaniu T-SQL.

Przegląd kursorów SQL

Przyjrzyjmy się podstawom kursorów SQL, jeśli ich nie znasz.

Prosta definicja

Kursor SQL zapewnia dostęp do danych w jednym wierszu na raz, zapewniając w ten sposób większą kontrolę (wiersz po wierszu) nad zbiorem wyników.

Definicja Microsoft

Zgodnie z dokumentacją Microsoft, instrukcje Microsoft SQL Server dają pełny zestaw wyników, ale zdarzają się sytuacje, w których wyniki najlepiej przetwarzać po jednym wierszu na raz. Otwarcie kursora na zestawie wyników umożliwia przetwarzanie zestawu wyników po jednym wierszu na raz.

T-SQL i zestaw wyników

Ponieważ zarówno proste, jak i Microsoft definicje kursora SQL wspominają o zestawie wyników, spróbujmy zrozumieć, czym dokładnie jest zestaw wyników w kontekście programowania baz danych. Pozwól nam szybko utworzyć i wypełnić tabelę Studenci w przykładowej bazie danych UniversityV3 w następujący sposób:

CREATE TABLE [dbo].[Student] ( [Identyfikator Studenta] INT IDENTITY (1, 1) NOT NULL, [Nazwa] VARCHAR (30) NULL, [Kurs] VARCHAR (30) NULL, [Znaki] INT NULL, [ExamDate] DATETIME2 (7) NULL, CONSTRAINT [PK_Student] PODSTAWOWY KLUCZ CLUSTERED ([StudentId] ASC));-- (5) Wypełnij tabelę Student tableSET IDENTITY_INSERT [dbo].[Student] ONINSERT INTO [dbo].[Student] ( [Identyfikator Studenta], [Nazwisko], [Kurs], [Oceny], [DataEgzaminu]) WARTOŚCI (1, N'Asif', N'Database Management System', 80, N'2016-01-01 00:00:00 ')WSTAW DO [dbo].[Student] ([Identyfikator Studenta], [Imię i nazwisko], [Kurs], [Znaki], [DataEgzaminu]) WARTOŚCI (2, N'Peter', N'System zarządzania bazą danych', 85, N'2016-01-01 00:00:00')WSTAW DO [dbo].[Student] ([Identyfikator Studenta], [Imię i nazwisko], [Kurs], [Oceny], [DataEgzaminu]) WARTOŚCI (3, N' Sam', N'Database Management System', 85, N'2016-01-01 00:00:00')INSERT INTO [dbo].[Student] ([Identyfikator studenta], [Imię i nazwisko], [Kurs], [Znaki ], [DataEgzaminu]) WARTOŚCI (4, N'Adil', N'Database Management System', 85, N'2016-01-01 00:00:00 ')INSERT INTO [dbo].[Student] ([Identyfikator Studenta], [Nazwa], [Kurs], [Znaki], [DataEgzaminu]) WARTOŚCI (5, N'Naveed', N'Database Management System', 90, N'2016-01-01 00:00:00')SET IDENTITY_INSERT [dbo].[Student] WYŁ

Teraz wybierz wszystkie wiersze z Studenta tabela:

-- Wyświetl dane tabeli Student SELECT [Identyfikator studenta], [Imię i nazwisko], [Kurs], [Znaki], [Data egzaminu] FROM dbo.Student

To jest zestaw wyników, który jest zwracany w wyniku wybrania wszystkich rekordów od Studenta tabela.

T-SQL i teoria mnogości

T-SQL opiera się wyłącznie na następujących dwóch pojęciach matematycznych:

  1. Teoria mnogości
  2. Logika predykatów

Teoria mnogości, jak sama nazwa wskazuje, jest gałęzią matematyki dotyczącą zbiorów, którą można również nazwać zbiorami określonych, odrębnych obiektów.

Krótko mówiąc, w teorii mnogości myślimy o rzeczach lub obiektach jako całości w taki sam sposób, jak myślimy o pojedynczym przedmiocie.

Na przykład uczeń jest zbiorem wszystkich określonych odrębnych uczniów, więc bierzemy ucznia jako całość, co wystarczy, aby uzyskać szczegółowe informacje o wszystkich uczniach w tym zestawie (tabela).

Więcej informacji można znaleźć w moim artykule Sztuka agregacji danych w SQL od agregacji prostych do agregacji przesuwnych.

Kursory i operacje oparte na wierszach

T-SQL jest przeznaczony przede wszystkim do wykonywania operacji opartych na zestawach, takich jak wybieranie wszystkich rekordów z tabeli lub usuwanie wszystkich wierszy z tabeli.

Krótko mówiąc, T-SQL jest specjalnie zaprojektowany do pracy z tabelami w sposób oparty na zestawach, co oznacza, że ​​myślimy o tabeli jako o całości, a każda operacja, taka jak zaznaczanie, aktualizowanie lub usuwanie, jest stosowana jako całość do tabeli lub niektórych wiersze, które spełniają kryteria.

Jednak zdarzają się przypadki, gdy dostęp do tabel trzeba uzyskiwać wiersz po wierszu, a nie jako pojedynczy zestaw wyników, i wtedy zaczynają działać kursory.

Według Vaidehi Pandere czasami logika aplikacji musi działać z jednym wierszem naraz, a nie wszystkimi wierszami naraz, co jest równoznaczne z pętlą (używanie pętli do iteracji) przez cały zestaw wyników.

Podstawy kursorów SQL z przykładami

Omówmy teraz więcej o kursorach SQL.

Przede wszystkim nauczmy się lub przejrzyjmy (tych, którzy są już zaznajomieni z używaniem kursorów w T-SQL), jak używać kursora w T-SQL.

Korzystanie z kursora SQL to proces składający się z pięciu kroków, wyrażony w następujący sposób:

  1. Zadeklaruj kursor
  2. Otwórz kursor
  3. Pobierz wiersze
  4. Zamknij kursor
  5. Zwolnij kursor

Krok 1:Zadeklaruj kursor

Pierwszym krokiem jest zadeklarowanie kursora SQL, aby można było go później użyć.

Kursor SQL można zadeklarować w następujący sposób:

DECLARE Cursor  dla 

Krok 2:Otwórz kursor

Następnym krokiem po deklaracji jest otwarcie kursora, co oznacza zapełnienie kursora zbiorem wyników, który jest wyrażony w następujący sposób:

Otwórz 

Krok 3:Pobierz wiersze

Po zadeklarowaniu i otwarciu kursora, następnym krokiem jest rozpoczęcie pobierania wierszy z kursora SQL jeden po drugim, aby pobrać wiersze, aby uzyskać następny dostępny wiersz z kursora SQL:

Pobierz następny z 

Krok 4:Zamknij kursor

Gdy wiersze są pobierane jeden po drugim i manipulowane zgodnie z wymaganiami, następnym krokiem jest zamknięcie kursora SQL.

Zamknięcie kursora SQL wykonuje trzy zadania:

  1. Zwalnia zestaw wyników aktualnie trzymany przez kursor
  2. Zwalnia wszelkie blokady kursora w wierszach przez kursor
  3. Zamyka otwarty kursor

Prosta składnia do zamykania kursora jest następująca:

Zamknij 

Krok 5:Cofnij przydzielenie kursora

Ostatnim krokiem w tym zakresie jest cofnięcie alokacji kursora, co usuwa odniesienie do kursora.

Składnia jest następująca:

DEALLOCATE 

Kompatybilność z kursorem SQL

Zgodnie z dokumentacją Microsoft, kursory SQL są kompatybilne z następującymi wersjami:

  1. SQL Server 2008 i nowsze wersje
  2. Baza danych Azure SQL

Przykład kursora SQL 1:

Teraz, gdy znamy kroki związane z implementacją kursora SQL, spójrzmy na prosty przykład użycia kursora SQL:

-- Zadeklaruj przykład kursora Studenta 1USE UniversityV3GODECLARE Student_Cursor CURSOR FOR SELECT StudentId ,[Nazwa]FROM dbo.Student;OPEN Student_CursorFETCH NEXT FROM Student_CursorWHILE @@FETCH_STATUS =0BEGINFETCHCursCursDEOCTurStudent_lubEND_Student FROM> 

Dane wyjściowe są następujące:

Przykład kursora SQL 2:

W tym przykładzie użyjemy dwóch zmiennych do przechowywania danych trzymanych przez kursor podczas przemieszczania się z wiersza do wiersza, abyśmy mogli wyświetlić zestaw wyników w jednym wierszu na raz, wyświetlając wartości zmiennych.

-- Zadeklaruj kursor Studenta ze zmiennymi przykład 2USE UniversityV3GODECLARE @StudentId INT ,@StudentName VARCHAR(40) -- Zadeklaruj zmienne do przechowywania danych wiersza przechowywanych przez kursorDECLARE Student_Cursor CURSOR FOR SELECT StudentId ,[Name]FROM dbo.Student;OPEN Student_Curs NEXT FROM Student_Cursor INTO @StudentId, @StudentName -- Pobierz pierwszy wiersz i zapisz go w zmiennychWHILE @@FETCH_STATUS =0BEGINPRINT CONCAT(@StudentId,'--', @StudentName) -- Pokaż dane zmiennychFETCH NEXT FROM Student_Cursor -- Pobierz następny wiersz dane do kursora i zapisz je w zmiennychINTO @StudentId, @StudentNameENDCLOSE Student_Cursor -- Zamknij blokady kursora w wierszach DEALLOCATE Student_Cursor -- Zwolnij odniesienie do kursora

Wynik powyższego kodu SQL jest następujący:

Można by argumentować, że możemy osiągnąć ten sam wynik, używając prostego skryptu SQL w następujący sposób:

-- Wyświetlanie identyfikatora i nazwiska ucznia bez kursora SQLSELECT Identyfikator studenta,Nazwa FROM dbo.Kolejność studenta według identyfikatora studenta

W rzeczywistości istnieje wiele zadań, które wymagają użycia kursorów SQL, mimo że odradza się ich używanie ze względu na ich bezpośredni wpływ na pamięć.

Ważna uwaga

Pamiętaj, że według Vaidehi Pandere kursory są rezydentnym zestawem wskaźników, więc zajmują pamięć systemową, która w innym przypadku byłaby wykorzystywana przez inne ważne procesy; dlatego przemierzanie dużego zestawu wyników za pomocą kursorów nigdy nie jest dobrym pomysłem, chyba że istnieje ku temu uzasadniony powód.

Używanie kursorów SQL do specjalnych celów

Przejdziemy przez kilka specjalnych celów, do których można użyć kursorów SQL.

Testowanie pamięci serwera bazy danych

Ponieważ kursory SQL mają duży wpływ na pamięć systemową, są dobrymi kandydatami do replikacji scenariuszy, w których należy zbadać nadmierne użycie pamięci przez różne procedury składowane lub skrypty SQL ad hoc.

Prostym sposobem na zrozumienie tego jest kliknięcie przycisku statystyk klienta na pasku narzędzi (lub naciśnięcie Shift+Alt+S) w SSMS (SQL Server Management Studio) i uruchomienie prostego zapytania bez kursora:

Teraz uruchom zapytanie z kursorem używając zmiennych (SQL Cursor Przykład 2):

Teraz zanotuj różnice:

Liczba instrukcji SELECT bez kursora:1

Liczba instrukcji SELECT z kursorem:7

Liczba okrążeń serwera bez kursora:1

Liczba okrążeń serwera z kursorem:2

Czas przetwarzania klienta bez kursora:1

Czas przetwarzania klienta z kursorem:8

Całkowity czas wykonania bez kursora:1

Całkowity czas wykonania z kursorem:38

Czas oczekiwania na odpowiedzi serwera bez kursora:0

Czas oczekiwania na odpowiedzi serwera z kursorem:30

Krótko mówiąc, uruchomienie zapytania bez kursora, które zwraca tylko 5 wierszy, powoduje wykonanie tego samego zapytania 6-7 razy z kursorem.

Teraz możesz sobie wyobrazić, jak łatwo jest odtworzyć wpływ pamięci za pomocą kursorów, jednak nie zawsze jest to najlepsza rzecz do zrobienia.

Zbiorcze zadania manipulacji obiektami bazy danych

Jest jeszcze inny obszar, w którym kursory SQL mogą być przydatne i jest to sytuacja, w której musimy wykonać masową operację na bazach danych lub obiektach bazy danych.

Aby to zrozumieć, najpierw musimy utworzyć tabelę Course i wypełnić ją w UniversityV3 bazę danych w następujący sposób:

-- Utwórz tabelę kursuCREATE TABLE [dbo].[Kurs] ( [Identyfikator kursu] INT IDENTITY (1, 1) NOT NULL, [Name] VARCHAR (30) NOT NULL, [Szczegóły] VARCHAR (200) NULL, CONSTRAINT [PK_Kurs] PRIMARY KEY CLUSTERED ([Identyfikator kursu] ASC));-- Wypełnij tabelę kursuSET IDENTITY_INSERT [dbo].[Kurs] ONINSERT INTO [dbo].[Kurs] ([Identyfikator kursu], [Nazwa], [Szczegóły]) WARTOŚCI (1, N'DevOps for Databases', N'This dotyczy DevOps for Databases')WSTAW DO [dbo].[Kurs] ([Identyfikator kursu], [Nazwa], [Szczegóły]) WARTOŚCI (2, N'Power BI Podstawy', N'Tu chodzi o podstawy usługi Power BI')WSTAW DO [dbo].[Kurs] ([Identyfikator kursu], [Nazwa], [Szczegóły]) WARTOŚCI (3, Programowanie N'T-SQL', N'Informacje Programowanie T-SQL')INSERT INTO [dbo].[Kurs] ([Identyfikator kursu], [Nazwa], [Szczegóły]) WARTOŚCI (4, N'Tabular Data Modeling', N'To jest o tabelarycznym modelowaniu danych')INSERT INTO [dbo].[Kurs] ([Identyfikator kursu], [Nazwa], [Szczegóły]) WARTOŚCI (5, N „Podstawy usług analitycznych”, N „Tu chodzi o podstawy usług analitycznych”)SET IDENTITY_INSERT [dbo].[Kurs] WYŁ

Załóżmy teraz, że chcemy zmienić nazwy wszystkich istniejących tabel w UniversityV3 bazy danych jako STARE tabele.

Wymaga to iteracji kursora nad wszystkimi tabelami jedna po drugiej, aby można było zmienić ich nazwy.

Poniższy kod wykonuje zadanie:

-- Zadeklaruj kursor Studenta, aby zmienić nazwy wszystkich tabel na oldUSE UniversityV3GODECLARE @TableName VARCHAR(50) -- Istniejąca nazwa tabeli ,@NewTableName VARCHAR(50) -- Nowa nazwa tabeliDECLARE Student_Cursor CURSOR FOR SELECT T.TABLE_NAME FROM INFORMATION_SCHEMA.TABLES T;OPEN Student_CursorFETCH NEXT FROM Student_Cursor INTO @NazwaTabeliWHILE @@FETCH_STATUS =0BEGINSET @[email protected]+'_OLD' -- Dodaj _OLD do istniejącej nazwy tabeliEXEC sp_rename @TableName,@NewTableNameT lub FROMETCH tabeli NEXCur -- Pobierz dane następnego wiersza do kursora i zapisz je w zmiennychINTO @TableNameENDCLOSE Student_Cursor -- Zamknij blokady kursora w wierszachDEALLOCATE Student_Cursor -- Zwolnij odwołanie do kursora

Gratulacje, pomyślnie zmieniłeś nazwy wszystkich istniejących tabel za pomocą kursora SQL.

Rzeczy do zrobienia

Teraz, gdy znasz już użycie kursora SQL, spróbuj następujących rzeczy:

  1. Spróbuj utworzyć i zmienić nazwy indeksów wszystkich tabel przykładowej bazy danych przez kursor.
  2. Spróbuj przywrócić oryginalne nazwy tabel ze zmienionymi nazwami w tym artykule za pomocą kursora.
  3. Spróbuj wypełnić tabele dużą ilością wierszy i zmierzyć statystyki i czas dla zapytań z kursorem i bez kursora.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zrozumienie opróżnień bufora dziennika

  2. SQL WYBIERZ ŚREDN

  3. 10 przydatnych zasobów dla tych, którzy chcą dowiedzieć się więcej o SQL

  4. Łączenie się z Teradata w IRI Workbench

  5. Przechowywanie danych:REST vs. POSIX dla archiwów i HSM