Approccio su CICLI ITERATIVI nelle store porcedure

lunedì 13 luglio 2009 - 12.46

Aragorn2004 Profilo | Newbie

Ciao, ho questo quesito: ho una applicazione VB6 che interfaccia una base SQL SERVER 2000.

Spesso nell'applicazione è necessario provvedere a ricalcolare dei valori per un certo periodo. Spiego Meglio.
Ho un record in una tabella (TABELLA 1) che mi dice qual'è la data d'inizio e qual'è la data di fine.
Il codice VB6 poi va ad aggiornare un'altra tabella (diciamo TABELLA 2) nella quale il GIORNO è la colonna chiave.
Per cui devo ciclare per esempio dal 13-07-2009 al 20-7-2009 e fare una serie di UPDATE (precisamente 8) sulla Tabella N.2

Ora vorrei spostare questa cosa in una store procedure.

Ho realizzato il tutto con un cursore (dichiarato come LOCAL) e sono riuscito nell'intento. Ora ho letto in giro su vari blog che l'uso di cursori è sconsigliato per via dei blocchi che vengono applicati.

Il mio dubbio ora è: qual'è l'approccio giusto per risolvere questo tipo di problema all'interno di una store procedure.

Grazie per il vostro tempo e la vostra competenza.

Ciao.



lbenaglia Profilo | Guru

>Il mio dubbio ora è: qual'è l'approccio giusto per risolvere
>questo tipo di problema all'interno di una store procedure.

Ciao,

Posta un esempio completo con la struttura delle due tabelle (CREATE TABLE), alcune righe di prova (INSERT INTO) ed il result set finale che vorresti ottenere con quei dati.

>Grazie per il vostro tempo e la vostra competenza.
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

Aragorn2004 Profilo | Newbie

Ho buttato giù una piccola SP (anche se riduttiva) ma l'obiettivo è questo.
Preciso che sul target le colonne non solo 3 ma un po' di più.

Si potrebbe forse anche lavorare sulla struttura del TARGET ma per ora non è possibile.

Grazie ancora.

Ciao.

------------------------------------------------------------------------------------------------------------------------------------------------------
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TBTARGET]') and OBJECTPROPERTY(id, N'IsTable') = 1)
drop table [dbo].[TBTARGET]

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TBSOURCE]') and OBJECTPROPERTY(id, N'IsTable') = 1)
drop table [dbo].[TBSOURCE]

Declare @kdata datetime
Declare @maxData as datetime
Declare @MaxIDSource int
Declare @Kont int
Declare @Err int

Set NOCOUNT ON

CREATE TABLE [TBTarget] (
[Tgiorno] [datetime] NOT NULL ,
[Lotto1] [int] NULL ,
[Lotto2] [int] NULL ,
[Lotto3] [int] NULL ,
CONSTRAINT [PK_TBTARGET1] PRIMARY KEY CLUSTERED
(
[Tgiorno]
) ON [PRIMARY]
) ON [PRIMARY]


CREATE TABLE [TBSource] (
[ID_Source] [int] IDENTITY (1, 1) NOT NULL ,
[Data_INIZIO] [datetime] NULL ,
[Data_FINE] [datetime] NULL ,
[Lotto] [int] NULL ,
[QTA] [int] NULL ,
CONSTRAINT [PK_TBSOURCE1] PRIMARY KEY CLUSTERED
(
[ID_Source]
) ON [PRIMARY]
) ON [PRIMARY]

--Popolo i dati del target
set @kdata=CAST('01-01-2009' as datetime)
set @maxData=CAST('31-12-2009' as datetime)

While @kdata<=@maxData
BEGIN
INSERT INTO TBTarget
([Tgiorno], [Lotto1], [Lotto2], [Lotto3])
VALUES(@kdata, 50, 30, 30)

set @kdata=@kdata+1

END
---------------------------------------------------------
--Popolo i dati del Source

INSERT INTO TBSource ([Data_INIZIO], [Data_FINE], [Lotto], [QTA])
VALUES(CAST('01-01-2009' AS datetime),CAST('15-01-2009' AS datetime),1,2)

INSERT INTO [TBSource] ([Data_INIZIO], [Data_FINE], [Lotto], [QTA])
VALUES(CAST('07-02-2009' AS datetime),CAST('15-02-2009' AS datetime),2,3)

INSERT INTO [TBSource] ([Data_INIZIO], [Data_FINE], [Lotto], [QTA])
VALUES(CAST('21-03-2009' AS datetime),CAST('24-03-2009' AS datetime),3,5)

INSERT INTO [TBSource] ([Data_INIZIO], [Data_FINE], [Lotto], [QTA])
VALUES(CAST('01-12-2009' AS datetime),CAST('03-12-2009' AS datetime),1,20)

--------------------------------------------------------------
--Nel caso specifico ora dovrei aggiornare il target sottrando i valori del source
--per esempio per il primo record di source dovrei ciclare dal 1-1-2009 al 15-1-2009 e aggiornare
-- il corrispondente giorno. Questo pezzo l'ho realizzato con un cursore


Declare @vDataI datetime,@vDataF datetime,@vLotto int,@vQTA int
DECLARE @NstrSQL nvarchar(4000),@GiornoConv nvarchar(100)

select @MaxIDSource=Max(ID_SOURCE) From TBSOURCE
Set @Kont=1

DECLARE Cursore CURSOR LOCAL FOR
SELECT Data_Inizio,Data_Fine,Lotto,QTA
FROM TBSource

OPEN Cursore
FETCH NEXT FROM Cursore
INTO @vDataI,@vDataF,@vLotto,@vQTA


WHILE @@FETCH_STATUS = 0
BEGIN

set @kdata = @vDataI
while @kdata<=@vDataF
BEGIN
set @GiornoConv = ' CONVERT(Datetime,''' + cast(convert(datetime,@kdata,102) as nvarchar(30)) + ''',102)'

SET @NstrSQL= 'Update TBTARGET Set Lotto' + CAST(@vLotto as nvarchar(1)) + '=' +
' Lotto' + CAST(@vLotto as nvarchar(1))
+ ' - ' + CAST(@vQTA as nvarchar(5))
+ ' Where TGiorno =' + @GiornoConv

PRINT @NstrSQL

exec sp_executesql @NstrSQL

SELECT @err = @@error IF @err <> 0 BREAK

set @kdata=@kdata+1

END

SELECT @err = @@error IF @err <> 0 BREAK

FETCH NEXT FROM Cursore
INTO @vDataI,@vDataF,@vLotto,@vQTA
END
CLOSE Cursore
DEALLOCATE Cursore

Set NOCOUNT OFF

Select * From TBTARGET
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5