FETCH

FETCH_STATUS

\

OPEN

\

CLOSE

DEALLOCATE


source

Пересказ статьи Jeremy Kadlec. SQL Server Cursor Example

Что такое курсор в SQL Server

Курсор

Создание курсора

  1. Объявите ваши переменные (для имен файлов, имен баз данных, номеров счетов и т.д.), которые вам нужны для реализации логики, и присвойте им начальные значения.
  2. Объявите курсор с конкретным именем (как db_cursor в этом примере), которое вы будете использовать на протяжении всей логики вместе с бизнес-логикой (оператор SELECT) для наполнения курсора требуемыми записями. Имя курсора может быть осмысленным. Сразу после этого следует открытие курсора.
  3. Извлеките запись из курсора, чтобы начать обработку
  4. Обработка данных уникальна для каждого набора логики. Это может быть вставка, обновление, удаление и т.д. для каждой извлекаемой строки данных
  5. Извлечение следующей записи из курсора, как это делалось на шаге 3, а затем шаг 4 снова повторяется при обработке выбранных данных
  6. По завершению обработки всех данных курсор закрывается
  7. На последнем и важном шаге вам необходимо освободить курсор, т.е. освободить все удерживаемые внутренние ресурсы SQL Server

Пример использования курсора

бекап всех полльзовательсеих БД на сервере

-- 1 - Объявление переменных
DECLARE @name VARCHAR(50) -- имя базы данных
DECLARE @path VARCHAR(256) -- путь в файлам резервных копий
DECLARE @fileName VARCHAR(256) -- имя файла бэкапа 
DECLARE @fileDate VARCHAR(20) -- используется для имени файла
-- Инициализация переменных
SET @path = 'C:\Backup'
SELECT @fileDate = CONVERT(VARCHAR(20),GETDATE(),112) 
-- 2 - Объявление курсора
DECLARE db_cursor CURSOR FOR 
SELECT name 
FROM MASTER.dbo.sysdatabases 
WHERE name NOT IN ('master','model','msdb','tempdb') 
-- Открытие курсора
OPEN db_cursor
-- Извлечение очередной записи из курсора
FETCH NEXT FROM db_cursor INTO @name  
-- Проверить состояние курсора
WHILE @@FETCH_STATUS = 0  
BEGIN  
   	SET @fileName = @path + @name + '_' + @fileDate + '.BAK' 
  	BACKUP DATABASE @name TO DISK = @fileName 
 	FETCH NEXT FROM db_cursor INTO @name 
END 
-- Закрытие курсора
CLOSE db_cursor  
-- Освобождение ресурсов, которые курсор занял
DEALLOCATE db_cursor

Оператор CLOSE - Освобождает текущие данные и связанные с ними блокировки, но оставляет возможность повторно открыть курсор.

Оператор DEALLOCATE - уничтожает курсор


source

Почему SQL курсоры настолько непопулярны

Как правило, курсоры SQL считаются неэффективными из-за того, что они обрабатывают данные построчно. Это не позволяет использовать преимущества массовых операций, встроенных в системы баз данных. Обычно такой подход приводит к замедлению выполнения запросов и увеличенному потреблению ресурсов. В отличие от курсоров, массовые операции справляются с задачей быстрее и эффективнее, обрабатывая значительные объёмы данных одним запросом