SQL SERVER - trigger e cursori..

martedì 26 febbraio 2008 - 14.35

angie81 Profilo | Junior Member

in una stored procedure attivata da un trigger ho un cursore... che mi sta facendo impazzire... uff..

in pratica lanciando la SP esternamente (col l'EXEC) non ho problemi.. mentre lanciandola dal trigger non va..

dopo varie prove ho capito che è proprio il cursore che blocca tutto..
ma come posso risolvere???
il cursore mi serve perchè devo ciclare in una tabella e per ogni record devo fare una determinata operazione.. ci fosse un altro modo per ciclare .. lo utilizzerei volentieri..

sintetizzando un pò .. il codice interessato è questo..

DECLARE Avvocati CURSOR LOCAL SCROLL FOR SELECT ID_ANAGRAFICA FROM VALBO_ISCRIZIONE_DIF_ORDINARI ORDER BY ID_ANAGRAFICA OPEN Avvocati DECLARE @idanagrafica varchar(9) -- ciclo giorni da 1 a X WHILE @conta_giorni <= @totale_giorni BEGIN -- ogni giorno devo assegnare un record ad X avvocati WHILE @avvocato < @avvocati_al_giorno BEGIN IF @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM Avvocati INTO @idanagrafica END ELSE BEGIN FETCH FIRST FROM Avvocati INTO @idanagrafica END -- INSERT ... set @avvocato = @avvocato + 1 END -- ogni avvocato deve raggiungere X record dopo N giorni -- finchè l'avvocato Y non ha X record.. torno indietro di X avvocati.. IF @conta_giorni_per_avvocato < @giorni_per_avvocato BEGIN -- torno indietro di N avvocati SET @avv = (-1 * @avvocato) FETCH RELATIVE @avv FROM Avvocati INTO @idanagrafica SET @avvocato = 0 END set @conta_giorni = @conta_giorni + 1 END CLOSE Avvocati DEALLOCATE Avvocati

Wamba Profilo | Expert

Ciao,
purtroppo non ho il tempo di scriverti il codice, ma ti riassumo brevemente come faccio io normalmente.
Crei una variabile di tipo table o una tabella temporanea (credo sia meglio la prima se non hai particolari esigenze), con i dati minimi che ti servono per identificare i campi o per lavorare, anche solo un campo l'id ad esempio.

create table #Tmp
(
[I_ID] int
)

--Riempi #tmp con i dati su cui eseguire il loop:
INSERT INTO #Tmp
SELECT [I_ID] FROM MiaTab WHERE ...

--cicli su #tmp

while EXISTS(SELECT TOP 1 I_Id FROM #Tmp)
BEGIN
SELECT TOP 1 @TmpId = I_ID from #Tmp
DELETE #Tmp WHERE I_ID = @TmpId

--Tuo codice
END

alla fine elimini la tabella temporanea (se hai seguito quella strada)
drop table #Tmp

Spero di esserti stato di aiuto.

-----------------------------------------------------------
Solo chi ha il Caos dentro può generare una stella danzante
Wamba
blogs.ugidotnet.org/WamBlog/
www.intellimaker.com

angie81 Profilo | Junior Member

Grazie per la spiegazione.. sto provando il tuo suggerimento..
solo una cosa...
se volessi svuotare in un colpo la tab temporanea e poi ripopolarla?

Wamba Profilo | Expert

Lavori come con una comune tabella, ma ti ripeto è meglio lavorare con una variabile di tipo table rispetto ad una tabella temporanea.
-----------------------------------------------------------
Solo chi ha il Caos dentro può generare una stella danzante
Wamba
blogs.ugidotnet.org/WamBlog/
www.intellimaker.com

angie81 Profilo | Junior Member

quindi per cancellare tutti i record della tabella temp devo ugualmente ciclare e usare il DELETE * per ogni record?

che differenze ci sono tra tabelle temporanee e variabili table?

Wamba Profilo | Expert

>quindi per cancellare tutti i record della tabella temp devo ugualmente ciclare e usare il DELETE * per ogni record?
No se la devi svuotare di colpo basta una delete sola.

>che differenze ci sono tra tabelle temporanee e variabili table?
La differenza è che la tabella temporanea è una tabella a tutti gli effetti quindi scritta sul db e che può essere condivisa da più stored, una variabile di table ha molte più limitazioni, ma è visibile solo all'interno dell'esecuzione della stored e non rischi problemi in caso di esecuzione multipla. Mi rendo conto che la spiegazione è approssimativa, ma non ho le competenze necessarie per essere più preciso. Rimando alla documentazione o a Benaglia

-----------------------------------------------------------
Solo chi ha il Caos dentro può generare una stella danzante
Wamba
blogs.ugidotnet.org/WamBlog/
www.intellimaker.com

angie81 Profilo | Junior Member

ti ringrazio per la spiegazione..
un'ultima cosa..

il campo della tabella temp può essere anche un "varchar(50)" o deve necessariamente esserci un INT (considerando che la tabella avrà un unico campo..)?

Wamba Profilo | Expert

>il campo della tabella temp può essere anche un "varchar(50)" o deve necessariamente esserci un INT (considerando che la tabella
>avrà un unico campo..)?
può essere del tipo che vuoi, ricordati però che nel codice che ho postato è necessario cancellare il record dalla tabella temp dopo averlo letto. Quindi quel campo deve essere univoco, altrimenti la delete cancella tutte le corrispondenze.
-----------------------------------------------------------
Solo chi ha il Caos dentro può generare una stella danzante
Wamba
blogs.ugidotnet.org/WamBlog/
www.intellimaker.com

angie81 Profilo | Junior Member

si il campo è univoco.. quindi non dovrei aver problemi..

ma nella tabella temp posso inserire anche un campo non presente nella tabella originaria (ad esempio un campo numerico che vado ad incrementare di 1 ogni volta che inserisco un record per quell'ID_I .. senza quindi cancellare il record.. )?

Wamba Profilo | Expert

Il mio è solo un possibile approccio ad un problema.
La logica di lavoro scrivila come credi. La tabella può essere popolata con dati che arrivano da dove vuoi e del tipo che preferisci.
-----------------------------------------------------------
Solo chi ha il Caos dentro può generare una stella danzante
Wamba
blogs.ugidotnet.org/WamBlog/
www.intellimaker.com

angie81 Profilo | Junior Member

UFF.. mi sa che ho sempre lo stesso problema..

la stored procedure di per se va.. ma se la richiamo dal TRIGGER no....

Wamba Profilo | Expert

Non è che hai problemi di lock sulle tabelle o transazioni?
-----------------------------------------------------------
Solo chi ha il Caos dentro può generare una stella danzante
Wamba
blogs.ugidotnet.org/WamBlog/
www.intellimaker.com

angie81 Profilo | Junior Member

Ehm.. ovvero?

è da poco che uso SQL Server.. quindi non sono proprio espertissima...

Wamba Profilo | Expert

Scusa Angie, ma ho avuto da fare e mi sono dimenticato del thread. Qual'era il problema alla fine?
-----------------------------------------------------------
Solo chi ha il Caos dentro può generare una stella danzante
Wamba
http://blogs.ugidotnet.org/WamBlog/
http://www.intellimaker.com

angie81 Profilo | Junior Member

grazie per l'aiuto.. alla fine ho risolto..

ho spostato il BEGIN TRAN e il COMMIT all'esterno del ciclo WHILE .. ho sostituito la tabella temporanea con una variabile table e prima di ogni tabella del db richiamata, ho inserito "dbo" (l'utente proprietario) ...

Wamba Profilo | Expert

Di niente figurati
-----------------------------------------------------------
Solo chi ha il Caos dentro può generare una stella danzante
Wamba
http://blogs.ugidotnet.org/WamBlog/
http://www.intellimaker.com
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