¿Cómo evito el uso de cursores en Sybase (T-SQL)?
Pregunta
Imagine la escena: está actualizando un código Sybase heredado y se encuentra con un cursor.El procedimiento almacenado genera un conjunto de resultados en una tabla temporal que está lista para ser devuelta, excepto que una de las columnas no es muy legible por humanos, es un código alfanumérico.
Lo que debemos hacer es descubrir los posibles valores distintos de este código, llamar a otro procedimiento almacenado para hacer una referencia cruzada de estos valores discretos y luego actualizar el conjunto de resultados con los valores recién descifrados:
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
Ahora bien, si bien esto puede provocar palpitaciones a algunas personas, funciona.Mi pregunta es, ¿cuál es la mejor manera de evitar este tipo de cosas?
_NÓTESE BIEN:Para los propósitos de este ejemplo, también puede imaginar que el conjunto de resultados está en la región de 500k filas y que hay 100 valores distintos de look_up_code y, finalmente, que no es posible tener una tabla con los valores de referencia externa como lógica. en proc_code_xref es demasiado arcano._
Solución
Debes tener una tabla XRef si quieres quitar el cursor.Suponiendo que conoce los 100 valores de búsqueda distintos (y que son estáticos), es sencillo generar uno llamando a proc_code_xref 100 veces e insertando los resultados en una tabla.
Otros consejos
A menos que esté dispuesto a duplicar el código en el proceso xref, no hay forma de evitar el uso de un cursor.
Dicen que si debes usar el cursor, entonces debes haber hecho algo mal ;-) aquí tienes una solución sin cursor:
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