Stored Procedure con 'Cursor' annidati

mercoledì 08 giugno 2011 - 13.31
Tag Elenco Tags  SQL Server 2005

soundsgood Profilo | Newbie

Ciao ragazzi da poco sto utilizzando le stored procedure con sql server 2005

c'è una criticità con l'utilizzo di "cursor" annidati, vi posto l'esempio. Come potete vedere il cursor B è definito dentro il cursorA che effettua un ciclo while, da cui scaturisce l'errore che il cursorB gia esiste ogni volta che il while itera. Come si aggira questa cosa?



CREATE PROCEDURE test_ARCHSEGN_31_32_example
AS

DECLARE @rifoper_pri VARCHAR(20)
declare @DATAREG_31 datetime
declare @DATAREG_32 datetime

DECLARE cursorA CURSOR for
SELECT TOP 10 ARCS_RIFOPER_PRI , ARCS_DATAREG
FROM ARCHSEGN_20110607
WHERE dbo.ARCHSEGN_20110607.ARCS_TIPOREG = '3'
and dbo.ARCHSEGN_20110607.ARCS_TIPOOPER = '1'

OPEN cursorA

FETCH NEXT FROM cursorA
INTO @rifoper_pri, @DATAREG_31
While @@FETCH_STATUS = 0
Begin
PRINT 'begin a'

DECLARE cursorB CURSOR for

SELECT ARCS_DATAREG
FROM ARCHSEGN_20110607
WHERE dbo.ARCHSEGN_20110607.ARCS_TIPOREG = '3'
AND dbo.ARCHSEGN_20110607.ARCS_TIPOOPER = '2'
AND dbo.ARCHSEGN_20110607.ARCS_RIFOPER_PRI = @rifoper_pri

--OPEN cursorB

FETCH NEXT FROM cursorB
INTO @DATAREG_32
While @@FETCH_STATUS = 0
Begin
PRINT 'begin b'
--if(@DATAREG_32<@DATAREG_31)
PRINT @rifoper_pri
FETCH NEXT FROM cursorB
INTO @DATAREG_32
End



FETCH NEXT FROM cursorA
INTO @rifoper_pri, @DATAREG_31
End

CLOSE cursorA
CLOSE cursorB
DEALLOCATE cursorA
DEALLOCATE cursorB
GO







lbenaglia Profilo | Guru

>c'è una criticità con l'utilizzo di "cursor" annidati, vi posto
>l'esempio. Come potete vedere il cursor B è definito dentro il
>cursorA che effettua un ciclo while, da cui scaturisce l'errore
>che il cursorB gia esiste ogni volta che il while itera. Come
>si aggira questa cosa?

Ciao,

I casi in cui i cursori sono realmente necessari si possono contare sulle dita della mano di un falegname poco attento
Il 99% delle volte una o più operazioni basate su set di dati eseguono lo stesso lavoro di un cursore con aumenti prestazionali di diversi ordini di grandezza dato che non vincoliamo il dbengine a ragionare in modo statico riga per riga, ma gli offriamo la possibilità di eseguire il lavoro in modo autonomo, sfruttando tutte le ottimizzazioni intrinseche del motore.

Ora, se ci prepari in esempio completo con tabelle (CREATE TABLE), dati (INSERT INTO) e risultato atteso con quei dati, vedremo di suggerirti una soluzione set based.

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

soundsgood Profilo | Newbie

l'utilizzo di cursor annidati è dovuto al fatto che per ogni tupla della prima query su una tabella A devo effettuare un'altra query sulla tabella B. Quando per ogni riga della tabella A devo fare un'altra query su un'altra tabella ed è come se il secondo cursore viene ridichiarato e da errore di conseguenza

lbenaglia Profilo | Guru

>l'utilizzo di cursor annidati è dovuto al fatto che per ogni
>tupla della prima query su una tabella A devo effettuare un'altra
>query sulla tabella B.
E sei sicuro che il risultato finale non si possa raggiungere con una o più operazioni set based?
Se prepari l'esempio che ti ho chiesto proveremo a ragionarci insieme...

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

soundsgood Profilo | Newbie

risolto.. alla fine del primo while ci va messo "CLOSE cursorB" e "DEALLOCATE cursorB" cosi all'iterazione successiva quando si ridichiara il cursorB non da problemi. grazie

ma_di Profilo | Junior Member

Ciao,
sono contento che tu abbia risolto.
Visto però che esiste la possibilità di ottenere lo stesso risultato con una maggiore efficienza ( ed anche di imparare qualcosa ), gentilmente Lorenzo, potresti farci un piccolo esempio dell'argomento a cui fai riferimento?
Grazie.

lbenaglia Profilo | Guru

>Visto però che esiste la possibilità di ottenere lo stesso risultato
>con una maggiore efficienza ( ed anche di imparare qualcosa ),
>gentilmente Lorenzo, potresti farci un piccolo esempio dell'argomento
>a cui fai riferimento?
No, dato che non ho capito in che contesto ci troviamo.
Senza un esempio concreto su cui ragionare non è possibile fornire una soluzione.

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
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-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5