Cursores en Store Procedure.... u otra alternativa

18/04/2005 - 23:36 por alfbl_85 | Informe spam
Tengo 2 tablas en mi Bd:

Mes(Mes PK,Descripcion) y Valores(Anio PK,Mes PK,Valor)

y quiero generar un reporte anual de estos valores, la única forma que
he encontrado es utilizando cursores (por mi inexperiencia), aunque
tambien utilizo una tabla temporal.

Lo que quisiera saber es si hay alguna forma de lograr este resultado
sin tener que recurrir a usar cursores, la verdad yo ya agote todos
mis escasos conocimientos y no lo he logrado.

Gracias de antemano, espero su crítica y aportes.


ESTE ES EL RESULTADO

Anio Enero Febrero Marzo Abril Mayo
2001 -- 77 78 80 82 84
2002 -- 71 71 71 71
71 2003 -- 77 78 80
82 84 2004 78 82 87 92
97 2

LLAMANDO AL PROCEDURE:

EXEC sp_ResumenAnio null, '2001','2004'




CODIGO COMPLETO

/*************************************************************/
CREATE PROCEDURE sp_ResumenAnio
@Anio int=NULL,
@AnioDesde int=NULL,
@AnioHasta int=NULL
AS
BEGIN

SET NOCOUNT ON
DECLARE @Nombre VARCHAR(50)
DECLARE @Valor INT
DECLARE @Val CHAR(2)
DECLARE @Mes INT
DECLARE @Count INT
DECLARE @GrantCount INT
DECLARE @Select VARCHAR(8000)
DECLARE @GrantSelect VARCHAR(8000)

SET @GrantCount = 0
SET @GrantSelect = ''

DECLARE CurValores CURSOR SCROLL
FOR ( SELECT Anio
FROM Valores
WHERE CASE WHEN NOT @Anio IS NULL THEN Anio ELSE 0 END = CASE WHEN
NOT @Anio IS NULL THEN @Anio ELSE 0 END
AND CASE WHEN NOT @AnioDesde IS NULL THEN Anio ELSE 0 END >ÊSE
WHEN NOT @AnioDesde IS NULL THEN @AnioDesde ELSE 0 END
AND CASE WHEN NOT @AnioHasta IS NULL THEN Anio ELSE 0 END <ÊSE
WHEN NOT @AnioHasta IS NULL THEN @AnioHasta ELSE 0 END
GROUP BY Anio)
OPEN CurValores
FETCH FIRST FROM CurValores INTO @Anio
CREATE TABLE #Tempo (Anio INT,Enero CHAR(10),Febrero CHAR(10), Marzo
CHAR(10),Abril CHAR(10),Mayo CHAR(10),
Junio CHAR(10),Julio CHAR(10),Agosto CHAR(10),Setiembre
CHAR(10),Octubre CHAR(10),Noviembre CHAR(10),
Diciembre CHAR(10) )
WHILE @@FETCH_STATUS=0
BEGIN
DECLARE CurMeses CURSOR SCROLL
FOR (SELECT a.Descripcion, v.Valor, v.Anio,v.Mes
FROM Mes a RIGHT JOIN Valores v ON a.Mes=v.Mes
WHERE v.Anio=@Anio)
SET @Select=''
SET @Count=0



INSERT INTO #Tempo (Anio) VALUES (@Anio)

OPEN CurMeses
FETCH FIRST FROM CurMeses INTO @Nombre,@Valor,@Anio,@Mes
WHILE @@FETCH_STATUS=0
BEGIN
IF @Valor IS NULL SET @Val='--'
ELSE SET @ValÊST(@Valor AS CHAR(2))

IF @Mes= 1 UPDATE #Tempo SET EneroÊST(@Val AS CHAR(4)) WHERE
Anio=@Anio
IF @Mes= 2 UPDATE #Tempo SET FebreroÊST(@Val AS CHAR(4)) WHERE
Anio=@Anio
IF @Mes= 3 UPDATE #Tempo SET MarzoÊST(@VaL AS CHAR(4)) WHERE
Anio=@Anio
IF @Mes= 4 UPDATE #Tempo SET AbrilÊST(@Val AS CHAR(4)) WHERE
Anio=@Anio
IF @Mes= 5 UPDATE #Tempo SET MayoÊST(@Val AS CHAR(4)) WHERE
Anio=@Anio
IF @Mes= 6 UPDATE #Tempo SET JunioÊST(@Val AS CHAR(4)) WHERE
Anio=@Anio
IF @Mes= 7 UPDATE #Tempo SET JulioÊST(@Val AS CHAR(4)) WHERE
Anio=@Anio
IF @Mes= 8 UPDATE #Tempo SET AgostoÊST(@Val AS CHAR(4)) WHERE
Anio=@Anio
IF @Mes= 9 UPDATE #Tempo SET SetiembreÊST(@Val AS CHAR(4)) WHERE
Anio=@Anio
IF @Mes= 10 UPDATE #Tempo SET OctubreÊST(@Val AS CHAR(4)) WHERE
Anio=@Anio
IF @Mes= 11 UPDATE #Tempo SET NoviembreÊST(@Val AS CHAR(4))
WHERE Anio=@Anio
IF @Mes= 12 UPDATE #Tempo SET DiciembreÊST(@Val AS CHAR(4))
WHERE Anio=@Anio

FETCH NEXT FROM CurMeses INTO @Nombre, @Valor, @Anio,@Mes
END
CLOSE CurMeses
DEALLOCATE CurMeses

FETCH NEXT FROM CurValores INTO @Anio
END

SELECT * FROM #Tempo
DROP TABLE #Tempo
CLOSE CurValores
DEALLOCATE CurValores
END
GO
/*********************************************************************/

Preguntas similare

Leer las respuestas

#1 Isaias
19/04/2005 - 00:49 | Informe spam
Si estas 100% seguro que el la columna MES en tu PK, entonces, sigue las
instrucciones de esta liga:

http://support.microsoft.com/defaul...US;q175574
Respuesta Responder a este mensaje
#2 Don Roque
19/04/2005 - 14:49 | Informe spam
Hola, te puedo dar dos opciones. Por comodidad, arme el ejemplo para
solo tres meses, pero deberias replicar la logica para el resto de los
meses y todo andaria bien.

/*Inicializo el campo de batalla*/

use northwind
go


create table datos (
anio int,
mes int,
val float
)

go
insert into datos values (2000, 1, 1)
insert into datos values (2000, 1, 2)

insert into datos values (2000, 2, 3)
insert into datos values (2000, 2, 4)

insert into datos values (2000, 3, 5)
insert into datos values (2000, 3, 6)

insert into datos values (2001, 1, 7)
insert into datos values (2001, 1, 8)

insert into datos values (2001, 2, 9)
insert into datos values (2001, 2, 1)

insert into datos values (2001, 3, 2)
insert into datos values (2001, 3, 3)

insert into datos values (2002, 1, 4)
insert into datos values (2002, 1, 5)

insert into datos values (2002, 2, 6)
insert into datos values (2002, 2, 7)

insert into datos values (2002, 3, 8)
insert into datos values (2002, 3, 9)

insert into datos values (2003, 1, 1)
insert into datos values (2003, 1, 2)

insert into datos values (2003, 2, 3)
insert into datos values (2003, 2, 4)

insert into datos values (2003, 3, 5)
insert into datos values (2003, 3, 6)

/*se me ocurrio una forma usando tablas temporales y otra sin usar. Te
muestro primero la que no usa tablas temporales*/

select anio,
(select sum (val) from datos d2 where d1.anio = d2.anio and d2.mes = 1
) as enero,
(select sum (val) from datos d2 where d1.anio = d2.anio and d2.mes = 2
) as febrero,
(select sum (val) from datos d2 where d1.anio = d2.anio and d2.mes = 3
) as marzo
from datos d1
group by anio


/*ahora te muestro la solucion que se me ocurrio usando tablas
temporales*/

create table #tmp
(
anio int not null,
enero float null,
febrero float null,
marzo float null
)

insert into #tmp (anio) select distinct anio from datos

insert into #tmp (anio) select distinct anio from datos
update t
set enero = ( select sum (val) from datos d where t.anio = d.anio and
d.mes = 1 )
from #tmp t

update t
set febrero = ( select sum (val) from datos d where t.anio = d.anio and
d.mes = 2 )
from #tmp t

update t
set marzo = ( select sum (val) from datos d where t.anio = d.anio and
d.mes = 3 )
from #tmp t

select * from #tmp

drop table #tmp

/*borro la tabla de datos para que no se te llene la NORTHWIND despues
de probar y probar ejemplos*/
drop table datos
go



Espero que te sirva
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida