Fran Otero

Programación C#, ASP.NET,SqlServer, Mobile y electrónica.

Fila a fila sin cursores II: SELECT simple

Para los que les haya gustado mi anterior artículo en el cual substituiamos el uso de cursores por un bucle While, aquí está la continuación DEFINITIVA. Supongo que muchos pensareis que no ganamos mucho substituyendo una iteración por la otra, y en parte tenéis razón. No obstante la no utilización de cursores tiene beneficios intrínsecos que van más allá del propio rendimiento de la consulta, como podría ser la seguridad ante fallos de que no tendremos objetos instanciados en memoria.

De todas formas viendo el código anterior uno se queda con la sensación de que es un poco rudimentario. Hay otras alternativasparecidas, como puede ser incluir en la tabla temporal una columna IDENTITY que nos permita iterar la tabla en el While a través de una variable puntero que iremos incrementando en el propio While: más de lo mismo. Ahora bien, que os parecería si os digo que se puede substituir todo el bucle, el recorrido de filas, la comparación e incluso la tabla temporal por una única instrucción SELECT "corriente". Lo de corriente tiene un poco de trampa, pero nada de complicación: si utilizamos una instrucción select de asignación, la asignación se repetirá para cada fila de la consulta. Si además introducimos una expresión de tipo "case ... then .... else ..... end" podemos en cada fila comparar el valor máximo con el que llevamos agregado y asignar al máximo el mayor de ellos.

-- Creamos la tabla del ejemplo. Para simplificar introducimos solo los

--datos que utilizaremos, pero esto no afecta al ejemplo

declare @movimientos as table (Producto nvarchar(10), Cantidad int, Fecha date)

insert into @movimientos values ('tornillos',500,'20090101')

insert into @movimientos values ('tornillos',-200,'20090104')

insert into @movimientos values ('tornillos',-50,'20090102')

insert into @movimientos values ('tornillos',-220,'20090110')

insert into @movimientos values ('tornillos',500,'20090111')

insert into @movimientos values ('tornillos',-100,'20090120')

--Variables auxiliares que utilizaremos

declare @Acc int,@Max

int set @Acc=0 --Valor acumulado hasta la fila actual

set @Max=0 --Valor máximo hasta la fila actual

-- Consulta "importante"

select

@Acc=@Acc+Cantidad, --Valor acumulado hasta la fila actual

@Max=case sign(@Acc-@Max) when 1 then @Acc else @Max end --Asigna el nuevo máximo o se queda con el que había

From @movimientos

Where Producto= 'tornillos'

orderby fecha asc

print 'Máximo alcanzado:'

print @Max

 

-- Héchale una pensada, puede ser muy útil !!!!

 

 

 

Posted: 16/12/2009 23:15 por Fran Otero Otero | con 1 comment(s)
Archivado en:
Comparte este post:

Comentarios

preguntoncojonero ha opinado:

Gracias, siga con asuntos de sql server, por favor !!!

# December 17, 2009 8:12 AM