Використовуйте змінну таблиці або тимчасову таблицю.
Як вже було сказано раніше, курсор є крайнім засобом. Переважно тому, що він використовує багато ресурсів, видає блокування і може бути ознакою того, що ви просто не розумієте, як правильно використовувати SQL.
Побічна примітка: Я одного разу натрапив на рішення, яке використовувало курсори для оновлення рядків у таблиці. Після деякої перевірки виявилося, що вся справа може бути замінена однією командою UPDATE. Однак у цьому випадку, коли має бути виконана збережена процедура, одна SQL-команда не працюватиме.
Створіть подібну змінну таблиці (якщо ви працюєте з великою кількістю даних або не вистачає пам’яті, замість цього використовуйте тимчасову таблицю ):
DECLARE @menus AS TABLE (
id INT IDENTITY(1,1),
parent NVARCHAR(128),
child NVARCHAR(128));
The id
значення.
Замініть parent
іchild
деякі дані хороші, наприклад , відповідні ідентифікатори або весь набір даних , які будуть працювати на.
Вставте дані в таблицю, наприклад:
INSERT INTO @menus (parent, child)
VALUES ('Some name', 'Child name');
...
INSERT INTO @menus (parent,child)
VALUES ('Some other name', 'Some other child name');
Заявіть деякі змінні:
DECLARE @id INT = 1;
DECLARE @parentName NVARCHAR(128);
DECLARE @childName NVARCHAR(128);
І, нарешті, створіть цикл часу на даних у таблиці:
WHILE @id IS NOT NULL
BEGIN
SELECT @parentName = parent,
@childName = child
FROM @menus WHERE id = @id;
EXEC myProcedure @parent=@parentName, @child=@childName;
SELECT @id = MIN(id) FROM @menus WHERE id > @id;
END
Перший вибір витягує дані з тимчасової таблиці. Другий вибір оновлює @id.MIN
повертає null, якщо не було вибрано рядків.
Альтернативний підхід полягає в циклі, поки таблиця має рядки, SELECT TOP 1
і видалення вибраного рядка з таблиці темп:
WHILE EXISTS(SELECT 1 FROM @menuIDs)
BEGIN
SELECT TOP 1 @menuID = menuID FROM @menuIDs;
EXEC myProcedure @menuID=@menuID;
DELETE FROM @menuIDs WHERE menuID = @menuID;
END;