Consiglio per una stored p

sabato 01 settembre 2007 - 18.01

_J_ Profilo | Senior Member

salve ragazzi,
vorrei il vostro aiuto per cercare di risolvere questo problema, o meglio... vorrei un suggerimento su come affrontarlo.

uso sql sever ed ho un database che è un'anagrafica.. ho alcune tabelle così collegate:

cittadino<-----abita_in----->domicilio
cittadino<-----vive in----->nucleo familiare

cioè cittadino si collega a domicilio e nucleo familiare, ma tra nucleo familiare e domicilio non x'è collegamento diretto...

ebbene, io ho realizzato il caso in cui un cittadino cambia domicilio.. ora vorrei affrontare l'evenienza in cui un'intera famiglia cambia casa...
l'approccio che ho seguito è questo: conto i componenti di una famiglia, e per ognuno cambio casa.

il conteggio è ok, il cambio famiglia lo so fare(update)... il problema è la scansione di ciò che trova, cioè fare l'update in base ai codici persona che trova... (un po' come un ciclo for o un foreach)

questa è la stored che ho abbozzato:

ALTER PROCEDURE dbo.spostam_famiglia ( @nf int ) AS declare @num_comp as integer //così conto i record in una famiglia set @num_comp='' select @num_comp=(select count(*) from ruolo_in_nf_o_conviv where cod_nucleo_familiare=@nf) begin if @num_comp !=0 //se ho componenti in nf select cod_persona from vive_in where cod_nf=@nf //trovo tutti i componenti di un nf //e per ognuno vorrei fare la update...ma come si fa a scansionarli tutti??? //esiste il ciclo for/foreach per le sp? /si possono usare gli array in questo contesto? else print 'ciao' //è solo per motivi di test end RETURN

qualcuno di voi potrebbe darmi un consiglio o suggerimento a riguardo?
non so più come andare avanti...
grazie in anticipo a chi mi aiuterà
_J_

"Chi fa domande rischia di sembrare stupido,
chi non ne fa rischia di restare stupido..."

"Conosco me stesso? No, non parlo con gli estranei..."

micto27 Profilo | Senior Member

>
>il conteggio è ok, il cambio famiglia lo so fare(update)... il
>problema è la scansione di ciò che trova, cioè fare l'update
>in base ai codici persona che trova... (un po' come un ciclo
>for o un foreach)
>


Circa la possibilità di ciclare il risultato di una query, nell'ambito di una stored procedure, o meglio
utilizzando T-SQL, puoi usare un "cursore".
Ad esempio:

-- dichiarazione variabili che ospiteranno i dati di ogni riga del cursore declare @varCol1 int declare @varCol2 varchar(30) declare @varCol3 datetime declare @varColn ..... -- dichiarazione del cursore declare myCursor cursor local for select col1, col2, col3, coln from miaTabella..... where ........ -- apertura del cursore --> viene eseguita la query associata open csr1 -- lettura fuori ciclo: prima riga risultato fetch next from myCursor into @varCol1, @varCol2, @varCol3, @varColn -- continuo finchè il cursore restituisce righe while @@fetch_status = 0 begin -- elaborazione in ciclo potendo disporre nelle variabili @varCol1, @varCol2, @varCol3, @varColn -- dei valori restituiti dal cursore -- lettura prossima riga risultato fetch next from myCursor into varCol1, @varCol2, @varCol3, @varColn end -- chiusura cursore close myCursor -- deallocazione cursore deallocate myCursor

Ciao, Michele

_J_ Profilo | Senior Member

ok, grazie!

ma tu dichiari una variabile per ogni colonna, giusto? poi questa variabile prenderà differenti valori in base alla relativa query dopo il begin, giusto?

io ho scritto questo codice:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

va bene così?

un'altra cosa: e se al posto della update avessi una insert? cioè nel caso la famiglia in questione avesse costruito un nuovo domicilio e si volesse spostare lì... come potrei fare visto che le insert non prendono le where?
_J_

"Chi fa domande rischia di sembrare stupido,
chi non ne fa rischia di restare stupido..."

"Conosco me stesso? No, non parlo con gli estranei..."

_J_ Profilo | Senior Member

ho provato col codice che ho creato e che ti ho postato nel mess precedente... a rutnime mi contesta un timeout...
ho provato ad allungare il timeout per la connessione interessata, ma il risultato è lo stesso...

è normale un tempo così lungo per i cursori?
_J_

"Chi fa domande rischia di sembrare stupido,
chi non ne fa rischia di restare stupido..."

"Conosco me stesso? No, non parlo con gli estranei..."

micto27 Profilo | Senior Member

>ho provato col codice che ho creato e che ti ho postato nel mess
>precedente... a rutnime mi contesta un timeout...
>ho provato ad allungare il timeout per la connessione interessata,
>ma il risultato è lo stesso...
>
>è normale un tempo così lungo per i cursori?

Secondo me il codice che hai scritto determina un loop infinito e di conseguenza ecco il timeout.

Prova a modificarlo come segue (prevedendo la FETCH nel ciclo WHILE)

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Ciao, Michele

_J_ Profilo | Senior Member

perfetto! tutto ok!
grazie 1000 e complimenti per la chiarezza che hai avuto

ma prima di chiudere un'ultima curiosità: ma perchè si mette due volte l'istruzione 'fetch next from cursore into @variabile' ?

grazie ancora!
_J_

"Chi fa domande rischia di sembrare stupido,
chi non ne fa rischia di restare stupido..."

"Conosco me stesso? No, non parlo con gli estranei..."

micto27 Profilo | Senior Member

>perfetto! tutto ok!
>grazie 1000 e complimenti per la chiarezza che hai avuto
>
>ma prima di chiudere un'ultima curiosità: ma perchè si mette
>due volte l'istruzione 'fetch next from cursore into @variabile'
>?
>
Essendo il ciclo WHILE basato sul test di @@fetch_status è necessario eseguire una prima FECTH
fuori dal ciclo, per avere un valore iniziale di @@fetch_status.

Per scrivere una sola FETCH avresti potuto ad esempio... (vedi codice)

open cursore declare @continua smallint set @continua = 1 while @continua = 1 begin fetch next from cursore into @variabile if @@fetch_status=0 begin if @num_comp !=0 /*se ho componenti nel nf in questione*/ insert into spostamenti_e_i ( cod_istat_com_ita_dest,cod_istat_com_ita_part, cod_com_est_dest, cod_com_est_part, cod_persona, data_spostamento, data_registraz_spostam ) values ( @istat_d, @istat_p, @est_d, @est_p, @variabile, //qui dovrei mettere la variabile di cursore? @data_sp, @data_reg ) /*per tutti i componenti cambio domicilio*/ else print 'ciao' end else set @continua = 0 end

Ciao, Michele

_J_ Profilo | Senior Member

ti ringrazio ancora tanto!
ciao
_J_

"Chi fa domande rischia di sembrare stupido,
chi non ne fa rischia di restare stupido..."

"Conosco me stesso? No, non parlo con gli estranei..."
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