Fetch annidati...come?

lunedì 26 maggio 2008 - 08.13

lukepet Profilo | Junior Member

Buongiorno a tutti,

ho un problema con SQL Server. Devo realizzare una stored procedure che letta una riga di una data tabella ne crei eventualmente altre in base ad una divisione prevista per uno o più campi.

Mi spiego meglio....

In pratica ho una riga che rappresenta una proposta di ordine e questa proposta deve essere suddivisa in base al mese di consegna e al marchio...assegnato ad ogni riga un codice differente.

Per riuscire a realizzare ciò avevo intenzione di utilizzare due fetch annidati che mi permettono di gestire tutte le possibili combinazioni tra mese e marchio. Il problema è che non so come si gestiscono due fetch uno dentro l'altro.

Sostanzialmente la procedure dovrebbe contenere una struttura di questo tipo:

.
.
.
DECLARE DivideMese CURSOR FOR SELECT MONTH(Data) AS Mese FROM RigheOrdine WHERE (NumProposta = @NumeroProposta) GROUP BY MONTH(Data)
DECLARE DivideMarchio CURSOR FOR SELECT Marchio FROM RigheOrdine WHERE (NumProposta = @NumeroProposta) GROUP BY Marchio

OPEN DivideMese
OPEN DivideMarchio


FETCH NEXT FROM DivideMese INTO @Mese
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH FIRST FROM DivideMarchio INTO @Marchio
WHILE @@FETCH_STATUS = 0
BEGIN
//Assegna nuovo codice ed inserisci

FETCH NEXT FROM DivideMarchio INTO @Marchio
END

FETCH NEXT FROM DivideMese INTO @Mese

END

CLOSE DivideMarchio
CLOSE DivideMese
.
.
.

E' corretta una struttura di questo tipo? e soprattutto è possibile utilizzarla?

In alternativa quale sarebbe un modo per gestire l'esigenza di utilizzare dei fetch annidati?

Vi ringrazio in anticipo per ogni aiuto.

lbenaglia Profilo | Guru

>E' corretta una struttura di questo tipo? e soprattutto è possibile
>utilizzarla?
Direi di si, provala

>In alternativa quale sarebbe un modo per gestire l'esigenza di
>utilizzare dei fetch annidati?
Per rispondere a questa domanda occorrerebbe una analisi completa di quello che vuoi fare, accompagnata dai comandi DDL delle tabelle coinvolte, da alcune righe di prova e del result set finale che vuoi ottenere con quei dati.

>Vi ringrazio in anticipo per ogni aiuto.
Prego.

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

lukepet Profilo | Junior Member

Facendo il debug della stored procedure ho riscontrato un problema con il @@FETCH_STATUS.

Sempre che mettendo due WHILE @@FETCH_STATUS annidati la procedura non riesce a capire a quale operazione di FETCH sia associato lo stato...così quando il ciclo di FETCH più interno termina di conseguenza termina anche quello esterno (che in realtà si trovava solo alla prima iterazione).

Da ciò che ho capito il comportamento sembra essere questo...o sbaglio?

Avete qualche suggerimento???

lbenaglia Profilo | Guru

>Da ciò che ho capito il comportamento sembra essere questo...o
>sbaglio?

Secondo me sbagli dato che al termine del ciclo interno esegui una nuova fetch, quindi @@FETCH_STATUS verrà aggiornato col nuovo valore:

... FETCH NEXT FROM DivideMarchio INTO @Marchio END FETCH NEXT FROM DivideMese INTO @Mese END

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

lukepet Profilo | Junior Member

Hai ragione...il problema allora è un altro. Attualmente la struttura della procedura è:

FETCH NEXT FROM DivideMese INTO @Mese
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH FIRST FROM DivideMarchio INTO @Marchio
FETCH NEXT FROM DivideMarchio INTO @Marchio
WHILE @@FETCH_STATUS = 0
BEGIN
//Assegna nuovo codice ed inserisci

FETCH NEXT FROM DivideMarchio INTO @Marchio
END

FETCH NEXT FROM DivideMese INTO @Mese

END

il malfunzionamento sembra che si legato al FETCH_STATUS interno...infatti sembra che, nel momento in cui il FETCH interno viene ri-inizializzato, il FETCH_STATUS ad esso associato non viene resettato. Possibile?

lukepet Profilo | Junior Member

Come non detto...la soluzione era molto più semplice del previsto, bastava fare un GROUP BY a due livelli

DECLARE DivideMeseMarchio CURSOR FOR SELECT MONTH(Data) AS Mese, Marchio FROM RigheOrdine WHERE (NumProposta = @NumeroProposta) GROUP BY MONTH(Data), Marchio

OPEN DivideMeseMarchio

FETCH NEXT FROM DivideMeseMarchio INTO @Mese, @Marchio
WHILE @@FETCH_STATUS = 0
BEGIN
//Assegna nuovo codice ed inserisci
FETCH NEXT FROM DivideMeseMarchio INTO @Mese
END

CLOSE DivideMeseMarchio

Tutto qui.
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-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5