Comment éviter d'utiliser des curseurs dans Sybase (T-SQL) ?
Question
Imaginez la scène, vous mettez à jour du code Sybase existant et vous rencontrez un curseur.La procédure stockée crée un jeu de résultats dans une table #temporary qui est prête à être renvoyée sauf que l'une des colonnes n'est pas très lisible par l'homme, c'est un code alphanumérique.
Ce que nous devons faire, c'est déterminer les valeurs distinctes possibles de ce code, appeler une autre procédure stockée pour croiser ces valeurs discrètes, puis mettre à jour le jeu de résultats avec les valeurs nouvellement déchiffrées :
declare c_lookup_codes for
select distinct lookup_code
from #workinprogress
while(1=1)
begin
fetch c_lookup_codes into @lookup_code
if @@sqlstatus<>0
begin
break
end
exec proc_code_xref @lookup_code @xref_code OUTPUT
update #workinprogress
set xref = @xref_code
where lookup_code = @lookup_code
end
Maintenant, même si cela peut donner des palpitations à certaines personnes, cela fonctionne.Ma question est la suivante : comment éviter au mieux ce genre de chose ?
_NB :pour les besoins de cet exemple, vous pouvez également imaginer que le jeu de résultats est de l'ordre de 500 000 lignes et qu'il existe 100 valeurs distinctes de look_up_code et enfin, qu'il n'est pas possible d'avoir une table avec les valeurs xref comme logique dans proc_code_xref est trop obscur._
La solution
Vous devez disposer d'une table XRef si vous souhaitez supprimer le curseur.En supposant que vous connaissez les 100 valeurs de recherche distinctes (et qu'elles sont statiques), il est simple d'en générer une en appelant proc_code_xref 100 fois et en insérant les résultats dans un tableau.
Autres conseils
À moins que vous ne souhaitiez dupliquer le code dans la procédure xréf, il n'y a aucun moyen d'éviter d'utiliser un curseur.
On dit que si vous devez utiliser le curseur, alors vous devez avoir fait quelque chose de mal ;-) voici la solution sans curseur :
declare @lookup_code char(8)
select distinct lookup_code
into #lookup_codes
from #workinprogress
while 1=1
begin
select @lookup_code = lookup_code from #lookup_codes
if @@rowcount = 0 break
exec proc_code_xref @lookup_code @xref_code OUTPUT
delete #lookup_codes
where lookup_code = @lookup_code
end