Bien que la lecture en boucle d'enregistrements dans T-SQL ne soit pas recommandée pour le code de production, il est parfois nécessaire de le faire. Un couple de grands exemples sont disponibles sur le site de support de Microsoft (dont aucune utiliser les curseurs): http://support.microsoft.com/kb/111401
Et voici une liste des méthodes:
Une méthode est l'utilisation des tables temporaires. Avec cette méthode, vous créez un "snapshot" de l'instruction SELECT initiale et l'utilisez comme base pour "cursoring". Par exemple:
/********** example 1 **********/
declare @au_id char(11)
set rowcount 0
select * into #mytemp from authors
set rowcount 1
select @au_id = au_id from #mytemp
while @@rowcount <> 0
begin
set rowcount 0
select * from #mytemp where au_id = @au_id
delete #mytemp where au_id = @au_id
set rowcount 1
select @au_id = au_id from #mytemp<BR/>
end
set rowcount 0
Une deuxième méthode consiste à utiliser la fonction min pour "parcourir" une table une ligne à la fois. Cette méthode intercepte les nouvelles lignes ajoutées après l'exécution de la procédure stockée, à condition que la nouvelle ligne ait un identifiant unique supérieur à la ligne en cours de traitement dans la requête. Par exemple:
/********** example 2 **********/
declare @au_id char(11)
select @au_id = min(au_id) from authors
while @au_id is not null
begin
select * from authors where au_id = @au_id
select @au_id = min(au_id) from authors where au_id > @au_id
end
REMARQUE: Les exemples 1 et 2 supposent qu'un identificateur unique existe pour chaque ligne de la table source. Dans certains cas, aucun identifiant unique ne peut exister. Si c'est le cas, vous pouvez modifier la méthode de table temporaire pour utiliser une colonne de clé nouvellement créée. Par exemple:
/********** example 3 **********/
set rowcount 0
select NULL mykey, * into #mytemp from authors
set rowcount 1
update #mytemp set mykey = 1
while @@rowcount > 0
begin
set rowcount 0
select * from #mytemp where mykey = 1
delete #mytemp where mykey = 1
set rowcount 1
update #mytemp set mykey = 1
end
set rowcount 0
Vous souhaitez un CURSEUR? (Ugly "non-set" SQL ;-) –
SQL n'a pas vraiment été conçu pour cela. Une raison particulière pour laquelle vous parcourez des lignes? – LittleBobbyTables
SQL est intrinsèquement basé sur SET, pas basé sur ROW. Si vous pouvez répondre à vos besoins en termes de traitement d'ensemble, vous n'aurez pas la «dissonance cognitive» qui consiste à essayer de forcer des opérations en rangée sur un conteneur défini par l'utilisateur. – DaveE