logo

Курсор в SQL Server

Курсорът в SQL Server е d atabase обект, който ни позволява да извличаме всеки ред наведнъж и да манипулираме неговите данни . Курсорът не е нищо повече от указател към ред. Винаги се използва заедно с оператор SELECT. Обикновено е колекция от SQL логика, която преминава през предварително определен брой редове един по един. Една проста илюстрация на курсора е, когато имаме обширна база данни от записи на работници и искаме да изчислим заплатата на всеки работник след приспадане на данъци и отпуски.

SQL сървърът целта на курсора е да актуализира данните ред по ред, да ги променя или да извършва изчисления, които не са възможни, когато извличаме всички записи наведнъж . Също така е полезно за извършване на административни задачи като архивиране на база данни на SQL Server в последователен ред. Курсорите се използват главно в процесите на разработка, DBA и ETL.

Тази статия обяснява всичко за курсора на SQL Server, като жизнения цикъл на курсора, защо и кога се използва курсорът, как да внедрим курсори, неговите ограничения и как можем да заменим курсор.

Жизнен цикъл на курсора

Можем да опишем жизнения цикъл на курсора в пет различни секции както следва:

Курсор в SQL Server

1: Декларирайте курсора

Първата стъпка е да декларирате курсора, като използвате следния SQL израз:

bash дължина на низ
 DECLARE cursor_name CURSOR FOR select_statement; 

Можем да декларираме курсор, като посочим името му с типа данни CURSOR след ключовата дума DECLARE. След това ще напишем командата SELECT, която дефинира изхода за курсора.

2: Отворете курсора

Това е втора стъпка, в която отваряме курсора, за да съхраняваме данни, извлечени от набора от резултати. Можем да направим това, като използваме следния SQL израз:

 OPEN cursor_name; 

3: Извличане на курсора

Това е трета стъпка, в която редовете могат да бъдат извлечени един по един или в блок, за да се извърши манипулиране на данни като операции за вмъкване, актуализиране и изтриване на текущо активния ред в курсора. Можем да направим това, като използваме следния SQL израз:

 FETCH NEXT FROM cursor INTO variable_list; 

Можем също да използваме Функция @@FETCHSTATUS в SQL Server, за да получите състоянието на най-скорошния курсор на оператор FETCH, който е бил изпълнен срещу курсора. The ИЗВЪРШВАНЕ изразът е успешен, когато @@FETCHSTATUS дава нулев резултат. The ДОКАТО операторът може да се използва за извличане на всички записи от курсора. Следният код го обяснява по-ясно:

 WHILE @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM cursor_name; END; 

4: Затворете курсора

Това е четвърта стъпка, в която курсорът трябва да бъде затворен, след като сме приключили работата с курсора. Можем да направим това, като използваме следния SQL израз:

 CLOSE cursor_name; 

5: Освобождаване на курсора

Това е петата и последна стъпка, в която ще изтрием дефиницията на курсора и ще освободим всички системни ресурси, свързани с курсора. Можем да направим това, като използваме следния SQL израз:

 DEALLOCATE cursor_name; 

Използване на SQL Server Cursor

Знаем, че системите за управление на релационни бази данни, включително SQL Server, са отлични при обработката на данни в набор от редове, наречени набори от резултати. Например , имаме маса product_table който съдържа описанията на продуктите. Ако искаме да актуализираме цена на продукта, след това по-долу „ АКТУАЛИЗАЦИЯ' заявката ще актуализира всички записи, които отговарят на условието в ' КЪДЕТО' клауза:

 UPDATE product_table SET unit_price = 100 WHERE product_id = 105; 

Понякога приложението трябва да обработва редовете по единичен начин, т.е. ред по ред, а не целия набор от резултати наведнъж. Можем да извършим този процес, като използваме курсори в SQL Server. Преди да използваме курсора, трябва да знаем, че курсорите са с много лоша производителност, така че винаги трябва да се използва само когато няма друга опция освен курсора.

Курсорът използва същата техника, както ние използваме цикли като FOREACH, FOR, WHILE, DO WHILE, за да итерира един обект наведнъж във всички езици за програмиране. Следователно, той може да бъде избран, защото прилага същата логика като процеса на цикъл на езика за програмиране.

Видове курсори в SQL Server

Следните са различните типове курсори в SQL Server, изброени по-долу:

  • Статични курсори
  • Динамични курсори
  • Курсори само за напред
  • Курсори на клавиатурата
Курсор в SQL Server

Статични курсори

Наборът от резултати, показан от статичния курсор, винаги е същият като при първото отваряне на курсора. Тъй като статичният курсор ще съхранява резултата в tempdb , те винаги са Само за четене . Можем да използваме статичния курсор, за да се движим както напред, така и назад. За разлика от други курсори, той е по-бавен и консумира повече памет. В резултат на това можем да го използваме само когато е необходимо превъртане и други курсори не са подходящи.

Този курсор показва редове, които са били премахнати от базата данни, след като е била отворена. Статичният курсор не представлява никакви операции INSERT, UPDATE или DELETE (освен ако курсорът не е затворен и отворен отново).

ляво съединяване срещу дясно съединяване

Динамични курсори

Динамичните курсори са противоположни на статичните курсори, които ни позволяват да извършваме операциите по актуализиране, изтриване и вмъкване на данни, докато курсорът е отворен. то е може да се превърта по подразбиране . Той може да открие всички промени, направени в редовете, реда и стойностите в набора от резултати, независимо дали промените се случват вътре в курсора или извън него. Извън курсора не можем да видим актуализациите, докато не бъдат ангажирани.

Курсори само за напред

Това е типът курсор по подразбиране и най-бързият сред всички курсори. Нарича се курсор само за напред, защото се движи само напред през набора от резултати . Този курсор не поддържа превъртане. Може да извлича само редове от началото до края на набора от резултати. Позволява ни да извършваме операции по вмъкване, актуализиране и изтриване. Тук ефектът от операциите за вмъкване, актуализиране и изтриване, направени от потребителя, които засягат редове в набора от резултати, се вижда, тъй като редовете се извличат от курсора. Когато редът е извлечен, не можем да видим промените, направени в редове чрез курсора.

Курсорите само за напред са три, категоризирани в три типа:

  1. Forward_Only Keyset
  2. Forward_Only Static
  3. Превъртане напред
Курсор в SQL Server

Курсори, управлявани от набор ключове

Тази функционалност на курсора се намира между статичен и динамичен курсор относно способността му да открива промени. Той не винаги може да открие промени в членството и реда на набора от резултати като статичен курсор. Той може да открие промени в стойностите на редовете на набора от резултати като динамичен курсор. Може само преминете от първия към последния и последния към първия ред . Редът и членството се фиксират при всяко отваряне на този курсор.

Той се управлява от набор от уникални идентификатори, същите като ключовете в комплекта ключове. Наборът ключове се определя от всички редове, които са квалифицирали израза SELECT при първото отваряне на курсора. Той може също да открие всякакви промени в източника на данни, който поддържа операции за актуализиране и изтриване. По подразбиране може да се превърта.

Изпълнение на Пример

Нека внедрим примера с курсора в SQL сървъра. Можем да направим това, като първо създадем таблица с име ' клиент ' използвайки израза по-долу:

 CREATE TABLE customer ( id int PRIMARY KEY, c_name nvarchar(45) NOT NULL, email nvarchar(45) NOT NULL, city nvarchar(25) NOT NULL ); 

След това ще вмъкнем стойности в таблицата. Можем да изпълним оператора по-долу, за да добавим данни в таблица:

 INSERT INTO customer (id, c_name, email, city) VALUES (1,'Steffen', '[email protected]', 'Texas'), (2, 'Joseph', '[email protected]', 'Alaska'), (3, 'Peter', '[email protected]', 'California'), (4,'Donald', '[email protected]', 'New York'), (5, 'Kevin', '[email protected]', 'Florida'), (6, 'Marielia', '[email protected]', 'Arizona'), (7,'Antonio', '[email protected]', 'New York'), (8, 'Diego', '[email protected]', 'California'); 

Можем да проверим данните, като изпълним ИЗБЕРЕТЕ изявление:

 SELECT * FROM customer; 

След като изпълним заявката, можем да видим резултата по-долу, където имаме осем реда в таблицата:

Курсор в SQL Server

Сега ще създадем курсор за показване на клиентските записи. Кодовите фрагменти по-долу обясняват всички стъпки от декларацията или създаването на курсора, като съберат всичко заедно:

какво е s в python
 --Declare the variables for holding data. DECLARE @id INT, @c_name NVARCHAR(50), @city NVARCHAR(50) --Declare and set counter. DECLARE @Counter INT SET @Counter = 1 --Declare a cursor DECLARE PrintCustomers CURSOR FOR SELECT id, c_name, city FROM customer --Open cursor OPEN PrintCustomers --Fetch the record into the variables. FETCH NEXT FROM PrintCustomers INTO @id, @c_name, @city --LOOP UNTIL RECORDS ARE AVAILABLE. WHILE @@FETCH_STATUS = 0 BEGIN IF @Counter = 1 BEGIN PRINT 'id' + CHAR(9) + 'c_name' + CHAR(9) + CHAR(9) + 'city' PRINT '--------------------------' END --Print the current record PRINT CAST(@id AS NVARCHAR(10)) + CHAR(9) + @c_name + CHAR(9) + CHAR(9) + @city --Increment the counter variable SET @Counter = @Counter + 1 --Fetch the next record into the variables. FETCH NEXT FROM PrintCustomers INTO @id, @c_name, @city END --Close the cursor CLOSE PrintCustomers --Deallocate the cursor DEALLOCATE PrintCustomers 

След като изпълним курсор, ще получим изхода по-долу:

Курсор в SQL Server

Ограничения на SQL Server Cursor

Курсорът има някои ограничения, така че винаги трябва да се използва само когато няма друга опция освен курсора. Тези ограничения са:

  • Курсорът изразходва мрежови ресурси, като изисква обиколка на мрежата всеки път, когато извлича запис.
  • Курсорът е резидентен набор от указатели, което означава, че отнема малко памет, която други процеси биха могли да използват на нашата машина.
  • Той налага ключалки върху част от таблицата или цялата таблица при обработка на данни.
  • Производителността и скоростта на курсора са по-бавни, защото те актуализират записите в таблицата един ред наведнъж.
  • Курсорите са по-бързи от циклите while, но имат повече допълнителни разходи.
  • Броят на редовете и колоните, въведени в курсора, е друг аспект, който влияе върху скоростта на курсора. Отнася се до това колко време е необходимо за отваряне на курсора и изпълнение на команда за извличане.

Как можем да избегнем курсорите?

Основната задача на курсорите е да обхождат таблицата ред по ред. Най-лесният начин да избегнете курсорите е даден по-долу:

Използване на SQL цикъла while

Най-лесният начин да избегнете използването на курсор е като използвате цикъл while, който позволява вмъкването на набор от резултати във временната таблица.

Дефинирани от потребителя функции

Понякога се използват курсори за изчисляване на резултантния набор от редове. Можем да постигнем това, като използваме дефинирана от потребителя функция, която отговаря на изискванията.

Използване на съединения

Join обработва само тези колони, които отговарят на определеното условие и по този начин намалява редовете код, които дават по-бърза производителност от курсорите, в случай че е необходимо да се обработват огромни записи.