Gestire un errore con relativo messaggio in una stored sql

venerdì 12 settembre 2008 - 11.28

trinity Profilo | Guru

salve ragazzi, buongiorno!
Io ho creato una stored con all'interno un semplice codice di Update...
Questo codice serve ad aggiornare un campo del db chiamato dataPartenza. Ovviamente c'è a monte anche un campo denominato DataArrivo,un campo Idstato ed altri due campi che rappresentano la chiave primaria che sono: codalbergo e codcomune.

Allora la mia query è la seguente:

Update dbo.archivio_mov Set datapartenza=@datapar Where codalbergo=@codalb and codcomune=@codcom and idstato=@codstato

Funziona tranquillamente solo che ora dovrei inserire un determinato controllo, ossia devo stabilire che se la data di partenza è inferiore alla data di arrivo non si deve effettuare l'update e mi deve ritornare un messaggio di errore che posso gestire da vbnet.

Mi spiego meglio con un esempio e vi posto i codici:

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

supponiamo l'inserimento dei seguenti record:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

il codice idstato=70 rappresenta la nazione FRANCIA

pertanto nella tabella del db avremo i seguenti record:

1000 - 60038 - 09-09-2008 - Null - 70 1000 - 60038 - 09-09-2008 - Null - 70 1000 - 60038 - 09-09-2008 - Null - 70 1000 - 60038 - 09-09-2008 - Null - 70 1000 - 60038 - 09-09-2008 - Null - 70 1000 - 60038 - 10-09-2008 - Null - 70 1000 - 60038 - 10-09-2008 - Null - 70 1000 - 60038 - 10-09-2008 - Null - 70

ora io per facilitare il cliente in quanto gestire tantissimi movimenti per loro resta impossibile, ho dovuto raggruppare nell'applicativo tutto i movimenti che non hanno partenza per idstato.
Pertanto in vbnet i miei clienti avranno quanto segue:

8 arrivi Francia

senza riportare la data di arrivo.

Io a questo punto mi serve da implementare la mia update facendo in modo che posso aggiornare la data di partenza a qualsiasi record che hanno l'idstato che stabilisco anche se hanno data arrivo diverse, ma questa data di partenza deve essere superiore alla data di arrivo.

esempio:

se dico che 5 record di Francia devono partire l'11-09-2008 avreo il seguente quadro:
1000 - 60038 - 09-09-2008 - 11-09-2008 - 70 1000 - 60038 - 09-09-2008 - 11-09-2008 - 70 1000 - 60038 - 09-09-2008 - 11-09-2008 - 70 1000 - 60038 - 09-09-2008 - 11-09-2008 - 70 1000 - 60038 - 09-09-2008 - 11-09-2008 - 70 1000 - 60038 - 10-09-2008 - Null - 70 1000 - 60038 - 10-09-2008 - Null - 70 1000 - 60038 - 10-09-2008 - Null - 70

mentre nel caso in cui volessi aggionare la data di partenza a 08-09-2008 vedendo che la prima data di arrivo libera è = 09/09/2008 allora l'update non deve essere eseguita e mi deve generare un messaggio di errore.

Spero di essere stato abbastanza chiaro.

Grazie


Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>salve ragazzi, buongiorno!
Ciao!


>Ecco la tabella:
Attenzione che hai indicato i due campi della chiave NULLABLE.. e non puoi fare la PK su campi NULL

>supponiamo l'inserimento dei seguenti record:
>il codice idstato=70 rappresenta la nazione FRANCIA
>
>pertanto nella tabella del db avremo i seguenti record:
Anche qui, attenzione alle date, come le passi tu non vengono accettate come valide e SQL mette il 1900 .
Inoltre le tue insert violano la PK..


>mentre nel caso in cui volessi aggionare la data di partenza
>a 08-09-2008 vedendo che la prima data di arrivo libera è = 09/09/2008
>allora l'update non deve essere eseguita e mi deve generare un
>messaggio di errore.
Allora, nell'esempio seguente, viene eseguita l'update dove deve essere eseguita ma non torni messaggi di errore.
Se vuoi fare in modo che ti venga restituito un messaggio d'errore nel caso in cui anche solo un record non rispetti il criterio, devi fare un controllo a monte con una select. Se invece vuoi che l'update venga eseguita ma che al primo criterio non rispettato ti torni un messaggio di errore devi lavorare coi cursori, ma te lo sconsiglio.

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

>Grazie
di nulla!
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

trinity Profilo | Guru

Scusami ho postato i dati velocemente e non mi sono accorto di questi errori, cmq hai capito il mio problema. Ho visto il tuo esempio e volevo dirti 2 cose:
1- nel caso il valore della variabile @valore sia inferiore alla data di arrivo come posso gestire un messaggio di errore che venga poi visualizzato in vbnet?
2 - l'esempio funziona perfettamente ma il problema sta sul fatto che a volte capita che su 10 record che hanno datapartenza = Null solo per esempio 5 devono essere aggiornati e gli altri no, con il tuo codice vengono aggiornati tutti in base ai criteri passati nella Where.

come si può fare?


Ciao e grazie mille dell'aiuto


Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>Scusami ho postato i dati velocemente e non mi sono accorto di
>questi errori, cmq hai capito il mio problema.
Nessun problema..

> Ho visto il tuo esempio e volevo dirti nel caso il valore della variabile @valore
>sia inferiore alla data di arrivo come posso gestire un messaggio
>di errore che venga poi visualizzato in vbnet?
Ti dicevo, non puoi.. con la update, fa l'update.. e se va in errore l'update puoi gestire l'eccezione..
Ma non puoi dare un messaggio solo nel caso in cui l'errore sia "logico" e solo in alcuni casi..

>In + nel caso in cui volessi eseguire una select prima dell'update di modo
>da gestire l'errore, come posso determinare un messaggio di errore
>che devo poi far visualizzare in vbnet?
Puoi fare l'EXISTS e nel caso in cui esista almeno un record con quel criterio puoi scegliere:
- usare il comando RAISERROR (che lancia proprio l'eccezione)
- valorizzare due parametri di output, un @ErrorNumber ed un @ErrorMessage costruiti ad hoc dalla procedura (non sollevi alcuna eccezione a DB, ma gestisci da VB.Net)

Intanto eccoti il comando RAISERROR
http://technet.microsoft.com/it-it/library/ms178592.aspx

>Ciao e grazie mille dell'aiuto
di nulla!
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

trinity Profilo | Guru

Scusami,
rivedendo il tuo codice sull'update ho notato una cosa ossia l'esempio funziona perfettamente ma il problema sta sul fatto che a volte capita che su 10 record che hanno datapartenza = Null solo per esempio 5 devono essere aggiornati e gli altri no, con il tuo codice vengono aggiornati tutti in base ai criteri passati nella Where

per questo motivo in precedenza avevo creato una cosa del genere per gestire tutto nei criteri che mi servono:

(
@Codalbergo Int,
@CodComAlbergo Int,
@idstato Int,
@idcomune Int,
@idgruppo Int,
@DataPartenza Smalldatetime
)
AS
BEGIN
WITH CTE_GetID AS
(
SELECT MIN(iddb) AS id
FROM dbo.ARCHIVIO_MOV_NEW
WHERE codalbergo=@codalbergo and codcomalbergo=@codcomalbergo and idstato=@idstato and
idcomune=@idcomune and idgruppo=@idgruppo and datapartenza Is Null
)
UPDATE T
SET T.datapartenza = @datapartenza
From Archivio_mov_new As T
JOIN CTE_GetID AS CTE
ON T.iddb = CTE.id
Where T.codalbergo=@codalbergo
And T.codcomalbergo=@codcomalbergo
And T.idstato=@idstato
and T.idcomune=@idcomune
and T.idgruppo=@idgruppo
END

e così mi funziona tutto solo è che devo gestire il discorso della data di arrivo che deve essere inferiore alla data di partenza ma cmq sempre con un messaggio in quanto l'operatore deve essere avvertito che sta inserendo un parametro errato.
Nel mio codice il RAISERROR può essere inserito? e se si dove?


Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>Nel mio codice il RAISERROR può essere inserito? e se si dove?
No, in una istruzione non puoi gestire il RAISERROR.
Ma perchè non cambi filosofia e non ti fai un ciclo applicativo su tutti i record?
In questo modo, da VB.Net, ricavi l'elenco dei record da elaborare, poi, uno alla volta li aggiorni e laddove la data non è superata gestisci l'eccezione..
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

trinity Profilo | Guru

aspetta in che senso intendi?

prima di tutto calcola che il mio applicativo lavora tuto in remoto tramite transazioni ossia sui client dei miei clienti vi è solo l'applicativo, il db si trova su un server remoto.
Io a monte ogni volta che si avvia l'applicativo in una list carico tutti i movimenti raggruppati per nazione e comune che non hanno la data di partenza.
tieni presente però che non posso caricarmi nella list anche la data di arrivo altrimenti il gioco era fatto, tu mi dirai: perchè! Perchè esempio se ho in diversi giorni di arrivo tanti record che hanno nazione = Italia e comune = Roma io li raggruppo tutti insieme in quanto al cliente creerebbe problema avere tanti record da scorrere.
Partendo da questa reale situazione cosa mi consigli?

come posso agire su vb per gestire la mia situazione?

Ho provato e pensato ad una cifra di modi ma nessuno di questi mi è utile.

ciao
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>aspetta in che senso intendi?
>Partendo da questa reale situazione cosa mi consigli?
Allora, le istruzioni SQL che abbiamo scritto sono tutte corrette. Il problema è che non puoi proprio intervenire a metà di una istruzione di update e controllare se c'è un errore logico per poter tornare un messaggio di errore... Quindi, o cicli sulla stored procedure su di un cursore che è il tuo set di dati da aggiornare oppure sposti la select su vb, crei una collezione e la scorri. Poi, riga per riga fai l'update e controlli applicativamente se i criteri sono rispettati. Se non lo sono, messaggio di errore da vb (throw per intenderci).
Non conta se il db server è centralizzato e se il tuo applcativo è client.. Devi solo decidere da che parte ciclare, perchè altrimenti non puoi intervenire a metà per dire se ci sono errori.
In alternativa, puoi aggiornare tutti quelli dove il criterio è soddisfatto (esempio che ti facevo io all'inizio) e poi, controllare con una select se ci sono errori con quel criterio. In caso positivo, RAISERROR o errore gestito applicativamente..
non hai a mio avviso molte strade..
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

trinity Profilo | Guru

Secondo te che strada prenderesti se dovessi tu scegliere come agire?
Io voglio fare la cosa migliore sia da un punto di vista di codice che di prestazioni
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>Secondo te che strada prenderesti se dovessi tu scegliere come agire?
Se devi gestire per forza l'errore e non hai tanti dati, puoi fare tranquillamente fare il ciclo lato applicazione.
Più che altro fai attenzione all'accesso contemporaneo di più utenti.
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

trinity Profilo | Guru

Si ci possono stare anche molti clienti che si connetto contemporaneamente ma cmq registrano dati che hanno chiavi primarie diverse l'uno dall'altro.
Comunque pensavo a questa soluzione, se puoi seguimi e dimmi se può andare.

1 - Prima di tutto appena aprò l'applicativo carico in una lista i movimenti senza partenza raggruppati il che vuol dire che già eseguo una select sul db; questi record vengono raggruppati per nazione-comune

2 - Appena clicco su uno dei record per far partire il numero di clienti, eseguo un'altra select sul db per ricavare in dettaglio tutti i record caricando anche la data di arrivo e questi record verranno visualizzati in una lista che a seconda della volontà del cliente potrà essere aperta come dettaglio oppure no.

3 - su questa lista ciclo la data di arrivo e la confronto con la data di partenza che sto applicando direttamente tutto su lato client e se non ci sono problemi eseguo l'update attraverso una stored sql

secondo te potrebbe andar bene?

Ciao
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alx_81 Profilo | Guru

>secondo te potrebbe andar bene?
direi di sì.. e sei comodo con il messaggio di errore..
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org
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