J'ai dernièrement eu besoin dans une de mes procédures stockées de parcourir dans une boucle les résultats issus d'une requête construite dynamiquement. Je l'ai déjà fait il y a quelques temps mais cette fonctionnalité n'étant pas très souvent utilisée, j'ai du me rafraichir la mémoire.

En fait le point où il faut faire attention est le moment du passage du curseur de la requête dynamique vers la variable de type CURSOR déclarée dans la procédure où vous exécutez ladite requête dynamique.

L'exemple ci-dessous utilisant la base "AdventureWorks" illustre ce comportement. Il n'a aucun sens du point de vue de son utilité dans une application réelle mais cela suffit pour réaliser notre test.

Dans la variable @ColumnName au début du script nous définissons le nom de la colonne de la table DimCustomer à parcourir dans une boucle. Vous pouvez remplacer la valeur actuelle 'FirstName' par le nom d'une autre colonne ('LastName' par exemple) afin de voir l'utilité d'une requête dynamique.

  DECLARE @ColumnName varchar(20), @ColumnValue varchar(50), @sql nvarchar(500)

  SET @ColumnName = 'FirstName' -- pour réaliser le test remplacez la valeur par 'LastName'

  -- construire la requête SQL dynamiquement, le curseur est déclaré et ensuite ouvert
  SET @sql = N'SET @CursorOUT = CURSOR FOR SELECT ' + @ColumnName + N' FROM DimCustomer WHERE MaritalStatus = ''M'' OPEN @CursorOUT'
  DECLARE @Cursor CURSOR -- déclarer une variable en tant que curseur
  EXEC sp_executesql @sql, N'@CursorOUT cursor OUTPUT', @Cursor OUTPUT -- le curseur est passé en sortie à notre variable de type curseur
  FETCH NEXT FROM @Cursor INTO @ColumnValue
  WHILE @@FETCH_STATUS = 0 -- on parcours nos résultats
  BEGIN
    print 'Colonne : ' + @ColumnName + ' | Valeur : ' + @ColumnValue
  
    FETCH NEXT FROM @Cursor INTO @ColumnValue
  END
  CLOSE @Cursor
  DEALLOCATE @Cursor

Comme vous le voyez, rien de neuf ni rien d'extraordinaire mais cela n'empêche pas que de temps en temps on oublie les choses les plus évidentes.

A+