Use uma variável de tabela ou uma tabela temporária.
Como mencionado anteriormente, um cursor é o último recurso. Principalmente porque usa muitos recursos, bloqueia problemas e pode ser um sinal de que você simplesmente não está entendendo como usar o SQL corretamente.
Nota lateral: Uma vez me deparei com uma solução que usava cursores para atualizar linhas em uma tabela. Após algum exame, descobriu-se que a coisa toda poderia ser substituída por um único comando UPDATE. No entanto, nesse caso, onde um procedimento armazenado deve ser executado, um único comando SQL não funcionará.
Crie uma variável de tabela como esta (se você estiver trabalhando com muitos dados ou tiver pouca memória, use uma tabela temporária ):
DECLARE @menus AS TABLE (
id INT IDENTITY(1,1),
parent NVARCHAR(128),
child NVARCHAR(128));
o id
é importante.
Substitua parent
echild
por alguns bons dados, por exemplo, identificadores relevantes ou todo o conjunto de dados a ser operado.
Inserir dados na tabela, por exemplo:
INSERT INTO @menus (parent, child)
VALUES ('Some name', 'Child name');
...
INSERT INTO @menus (parent,child)
VALUES ('Some other name', 'Some other child name');
Declare algumas variáveis:
DECLARE @id INT = 1;
DECLARE @parentName NVARCHAR(128);
DECLARE @childName NVARCHAR(128);
E, finalmente, crie um loop while sobre os dados da tabela:
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
A primeira seleção busca dados da tabela temporária. A segunda seleção atualiza o @id.MIN
retorna nulo se nenhuma linha foi selecionada.
Uma abordagem alternativa é fazer um loop enquanto a tabela possui linhas SELECT TOP 1
e remover a linha selecionada da tabela temporária:
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;