Bonjour,

Lors du développement d’une procédure stockée, il est d’usage d’éviter l’utilisation des curseurs. Cependant ce n’est pas toujours possible. Il convient alors d’apprivoiser certaines subtilités.

Pour rappel, les curseurs permettent un parcourt ligne à ligne renvoyée par une requête de sélection (par exemple). Vous trouverez plus d’information sur leur usage sur Les procédures et les curseurs avec MS-SQL Server.

Après avoir chargé le curseur avec :

DECLARE curseur_1 CURSOR FOR (RQT)

puis avoir ouvert le curseur avec :

OPEN curseur_1

puis avoir récupéré le premier champ de la premiere ligne du curseur avec :

FETCH curseur_1 into @champ1

Un curseur se parcourt avec une boucle :

WHILE @@FETCH_STATUS = 0

BEGIN

Instructions

END

@@Fetch_Status retourne l’état de la dernière instruction FETCH effectuée sur un curseur actuellement ouvert par la connexion.

J’attire votre attention dans cet article sur l’**usage de 2 curseurs imbriqués**. En effet, la documentation Microsoft précise : Supposons, par exemple, qu’un utilisateur exécute une instruction FETCH sur un curseur, puis appelle une procédure stockée qui ouvre et traite les résultats pour un autre curseur. Lorsque le contrôle revient de la procédure stockée, **@@FETCH\_STATUS prend en compte la dernière instruction FETCH exécutée dans la procédure stockée et non celle qui avait eu lieu avant l’appel de la procédure stockée**. (<http://msdn.microsoft.com/fr-fr/library/ms187308.aspx>) Il est donc impossible d’imbriquer 2 curseurs. La solution est pour y remédier est d’attaquer la table sys.dm\_exec\_cursors qui contient l’état des curseurs actifs distinctement. Il faut donc remplacer le :
while fetch_status =0
par :
while (SELECT fetch_status FROM sys.dm_exec_cursors(@@spid) where name = ‘curseur_1’ ) =0

Dans le cas d’une utilisation importante de procédures stockées potentiellement imbriquées, cette solution garantie les résultats.

Si vous avez la possibilité de ne pas utiliser de curseur, c’est encore mieux 😉

Bonne soirée,

Guillaume