Какая польза от курсора в SQL Server?

Я хочу использовать курсор базы данных; Сначала мне нужно понять, каково его использование и синтаксис, и в каком сценарии мы можем использовать это в хранимых процедурах? Существуют ли разные синтаксисы для разных версий SQL Server?

Когда нужно использовать?


person Red Swan    schedule 19.11.2010    source источник
comment
Поиск действительно не занимает много времени, я легко нашел эту статью, и она охватывает большинство вопросов, которые вы задаете: sqlteam.com/article/cursors-an-overview   -  person Tony    schedule 19.11.2010


Ответы (6)


Курсоры - это механизм явного перечисления строк результирующего набора, а не его извлечения как такового.

Однако, хотя их может быть удобнее использовать для программистов, привыкших писать While Not RS.EOF Do ..., их обычно следует избегать в хранимых процедурах SQL Server, если это вообще возможно - если вы можете написать запрос без использования курсоров, вы дадите у оптимизатора гораздо больше шансов найти быстрый способ его реализации.

Честно говоря, я никогда не находил реалистичного варианта использования курсора, которого нельзя было бы избежать, за исключением нескольких административных задач, таких как перебор всех индексов в каталоге и их восстановление. Я предполагаю, что они могут иметь какое-то применение при создании отчетов или слиянии писем, но, вероятно, более эффективно выполнять работу, подобную курсору, в приложении, которое общается с базой данных, позволяя ядру базы данных делать то, что он делает лучше всего, - манипулировать наборами.

person Jeffrey Hantin    schedule 19.11.2010
comment
+1 в большинстве случаев они не нужны. Используйте их только при одноразовой работе или когда все остальные варианты не работают. - person Lieven Keersmaekers; 19.11.2010
comment
Единственная реальная потребность в курсорах, которые я обнаружил, касается триггеров - если у вас есть несколько затронутых записей, и вы хотите выполнить сохраненную процедуру для каждой записи, вам нужно перемещать курсор по таблицам триггеров (например, INSERTED) - person RPM1984; 19.11.2010
comment
Значит, курсор используется для итерации по строкам набора результатов, например, для обновления статуса 100 строк с ожидающих до завершения? - person JsonStatham; 26.06.2013
comment
@SelectDistinct Используется для перебора строк результирующего набора непосредственно в модели программируемости СУБД, например, внутри триггера или хранимой процедуры; как говорит RPM1984, типичным вариантом использования является запуск хранимой процедуры для каждой строки данного набора результатов, особенно если ваша модель программируемости не допускает значения набора результатов в качестве параметров. - person Jeffrey Hantin; 02.07.2013
comment
@ красивое объяснение, даже я не могу найти ни одного примера в реальном времени, который должен использовать курсор - person Just code; 18.12.2013
comment
У меня есть один вопрос, могу ли я получить набор результатов в курсоре, как и все примеры, найденные в Google, используют PRINT 'Name : '+@name+ ', pagename : '+convert(varchar(20),@salary), но могу ли я вернуть набор результатов отсюда в С #? - person Just code; 18.12.2013
comment
@ RPM1984 Мне только что пришло в голову, что выполнение сохраненной процедуры для каждой записи в триггере, вероятно, настолько пагубно сказывается на производительности, насколько это возможно; Лучше, чтобы хранимая процедура могла каким-то образом напрямую работать с набором строк триггера, возможно, с помощью аргумента с табличным значением. - person Jeffrey Hantin; 26.06.2014
comment
@JeffreyHantin как насчет сохраненных функций? Могут ли сохраненные функции использовать курсоры? - person Dylan Czenski; 08.01.2016

курсор используются, потому что в подзапросе мы можем извлекать запись строка за строкой, поэтому мы используем курсор для выборки записей

Пример курсора:

DECLARE @eName varchar(50), @job varchar(50)

DECLARE MynewCursor CURSOR -- Declare cursor name

FOR
Select eName, job FROM emp where deptno =10

OPEN MynewCursor -- open the cursor

FETCH NEXT FROM MynewCursor
INTO @eName, @job

PRINT @eName + ' ' + @job -- print the name

WHILE @@FETCH_STATUS = 0

BEGIN

FETCH NEXT FROM MynewCursor 
INTO @ename, @job

PRINT @eName +' ' + @job -- print the name

END

CLOSE MynewCursor

DEALLOCATE MynewCursor

ВЫХОД:

ROHIT                           PRG  
jayesh                          PRG
Rocky                           prg
Rocky                           prg
person rohit vyas    schedule 11.12.2012
comment
мы могли бы получить тот же результат с помощью простого запроса «Выберите eName, job FROM emp, где deptno = 10», так зачем использовать курсор для его зацикливания, какие-либо практические применения? - person Thunder; 12.12.2012
comment
У меня есть один вопрос, могу ли я получить набор результатов в курсоре, как и все примеры, найденные в Google, используют PRINT 'Name : '+@name+ ', pagename : '+convert(varchar(20),@salary), но могу ли я вернуть набор результатов отсюда в С #? - person Just code; 18.12.2013

Курсор может использоваться для получения данных строка за строкой. Он действует как оператор цикла (то есть цикл while или for). Чтобы использовать курсоры в процедурах SQL, вам необходимо сделать следующее: 1. Объявить курсор, определяющий набор результатов. 2. Откройте курсор, чтобы установить набор результатов. 3. При необходимости извлеките данные из курсора в локальные переменные, по одной строке за раз. 4. По завершении закройте курсор.

например:

declare @tab table
(
Game varchar(15),
Rollno varchar(15)
)
insert into @tab values('Cricket','R11')
insert into @tab values('VollyBall','R12')

declare @game  varchar(20)
declare @Rollno varchar(20)

declare cur2 cursor for select game,rollno from @tab 

open cur2

fetch next from cur2 into @game,@rollno

WHILE   @@FETCH_STATUS = 0   
begin

print @game

print @rollno

FETCH NEXT FROM cur2 into @game,@rollno

end

close cur2

deallocate cur2
person Murugan    schedule 04.10.2012

Я бы сказал, что вам может понадобиться использовать курсор, когда вы хотите провести сравнение характеристик, которые находятся в разных строках возвращаемого набора, или если вы хотите в некоторых случаях написать другой формат выходной строки, чем стандартный. На ум приходят два примера:

  1. Один был в колледже, где каждое добавление и удаление класса имело свою собственную строку в таблице. Возможно, это был плохой дизайн, но вам нужно было сравнить строки, чтобы узнать, сколько строк добавления и удаления у вас было, чтобы определить, был ли человек в классе или нет. Я не могу придумать простой способ сделать это только с sql.

  2. Другой пример - написание итоговой строки для журналов GL. Вы получаете произвольное количество дебетов и кредитов в своем журнале, у вас есть много журналов в вашем возврате набора строк, и вы хотите писать итоговую строку журнала каждый раз, когда вы заканчиваете журнал, чтобы опубликовать его в Главной книге. С помощью курсора вы могли определить, когда вы покинули один журнал и начали другой, и у вас есть накопители для ваших дебетов и кредитов, и написать итоговую строку журнала (или вставку в таблицу), которая отличается от дебетовой / кредитной линии.

person renaissanceMan    schedule 20.01.2018

Сам курсор является итератором (например, WHILE). Говоря итератор, я имею в виду способ пройти по набору записей (так называемому набору выбранных строк данных) и выполнять с ним операции во время обхода. Например, операции могут быть INSERT или DELETE. Следовательно, вы можете использовать его, например, для извлечения данных. Курсор работает со строками результирующего набора последовательно - строка за строкой. Курсор можно рассматривать как указатель на одну строку в наборе строк и может ссылаться только на одну строку за раз, но при необходимости может перемещаться к другим строкам набора результатов.

Это ссылка может содержать четкое объяснение синтаксиса и дополнительную информацию с примерами.

Курсоры также можно использовать в Sprocs. Это ярлык, который позволяет использовать один запрос для выполнения задачи вместо нескольких запросов. Однако курсоры распознают область действия и считаются неопределенными вне области действия sproc, а их операции выполняются в рамках одной процедуры. Хранимая процедура не может открыть, получить или закрыть курсор, который не был объявлен в процедуре.

person igelr    schedule 27.07.2018

В SQL-сервере курсор используется, когда вам нужно. Вместо команд T-SQL, которые работают со всеми строками в наборе результатов по одной за раз, мы используем курсор, когда нам нужно обновить записи в таблице базы данных в одноэлементном режиме. мода, другими словами, строка за строкой. извлекать по одной строке за раз или строка за строкой.

Работа с курсорами состоит из нескольких шагов:

Declare - Declare используется для определения нового курсора. Открыть - Курсор открывается и заполняется путем выполнения оператора SQL, определенного курсором. Извлечь - когда курсор открыт, строки могут быть извлечены из курсора одна за другой. Закрыть - после операций с данными мы должны явно закрыть курсор. Deallocate - наконец, нам нужно удалить определение курсора и освободить все системные ресурсы, связанные с курсором. Синтаксис

DECLARE имя_курсора CURSOR [LOCAL | ГЛОБАЛЬНО] [FORWARD_ONLY | ПРОКРУТКА] [СТАТИЧЕСКАЯ | KEYSET | ДИНАМИЧЕСКИЙ | FAST_FORWARD] [READ_ONLY | SCROLL_LOCKS | OPTIMISTIC] [TYPE_WARNING] FOR select_statement [FOR UPDATE [OF имя_столбца [, ... n]]] [;]

person Shiwangini    schedule 15.06.2019