Use una tabla variable o una tabla temporal.
Como se mencionó anteriormente, un cursor es el último recurso. Principalmente porque usa muchos recursos, emite bloqueos y puede ser una señal de que simplemente no estás entendiendo cómo usar SQL correctamente.
Nota al margen: una vez encontré una solución que usaba cursores para actualizar filas en una tabla. Después de un cierto escrutinio, resultó que todo podría ser reemplazado con un solo comando ACTUALIZAR. Sin embargo, en este caso, donde se debe ejecutar un procedimiento almacenado, un solo comando SQL no funcionará.
Cree una variable de tabla como esta (si está trabajando con muchos datos o tiene poca memoria, use una tabla temporal en su lugar):
DECLARE @menus AS TABLE (
id INT IDENTITY(1,1),
parent NVARCHAR(128),
child NVARCHAR(128));
los id
es importante.
Reemplazar parent
ychild
con algunos buenos datos, por ejemplo, identificadores relevantes o el conjunto completo de datos para ser operado.
Insertar datos en la tabla, por ejemplo:
INSERT INTO @menus (parent, child)
VALUES ('Some name', 'Child name');
...
INSERT INTO @menus (parent,child)
VALUES ('Some other name', 'Some other child name');
Declara algunas variables:
DECLARE @id INT = 1;
DECLARE @parentName NVARCHAR(128);
DECLARE @childName NVARCHAR(128);
Y finalmente, cree un ciclo while sobre los datos en la tabla:
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
La primera selección obtiene datos de la tabla temporal. La segunda selección actualiza el @id.MIN
devuelve nulo si no se seleccionaron filas.
Un enfoque alternativo es hacer un bucle mientras la tabla tiene filas SELECT TOP 1
y eliminar la fila seleccionada de la tabla temporal:
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;