Utilisez une variable de table ou une table temporaire.
Comme cela a été mentionné précédemment, un curseur est un dernier recours. Principalement parce qu'il utilise beaucoup de ressources, émet des verrous et peut être un signe que vous ne comprenez pas comment utiliser SQL correctement.
Note latérale: J'ai rencontré une fois une solution qui utilisait des curseurs pour mettre à jour les lignes d'un tableau. Après un examen minutieux, il s'est avéré que le tout pouvait être remplacé par une seule commande UPDATE. Cependant, dans ce cas, lorsqu'une procédure stockée doit être exécutée, une seule commande SQL ne fonctionnera pas.
Créez une variable de table comme celle-ci (si vous travaillez avec beaucoup de données ou si vous manquez de mémoire, utilisez un plutôt table temporaire ):
DECLARE @menus AS TABLE (
id INT IDENTITY(1,1),
parent NVARCHAR(128),
child NVARCHAR(128));
C'est id
important.
Remplacez parent
et child
par de bonnes données, par exemple des identifiants pertinents ou l'ensemble des données à exploiter.
Insérez des données dans le tableau, par exemple:
INSERT INTO @menus (parent, child)
VALUES ('Some name', 'Child name');
...
INSERT INTO @menus (parent,child)
VALUES ('Some other name', 'Some other child name');
Déclarez quelques variables:
DECLARE @id INT = 1;
DECLARE @parentName NVARCHAR(128);
DECLARE @childName NVARCHAR(128);
Et enfin, créez une boucle while sur les données du tableau:
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 première sélection récupère les données de la table temporaire. La seconde sélection met à jour le @id. MIN
renvoie null si aucune ligne n'a été sélectionnée.
Une autre approche consiste à boucler pendant que la table contient des lignes SELECT TOP 1
et à supprimer la ligne sélectionnée de la table temporaire:
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;