In Sql Server 2005 è stato introdotto un nuovo modello di gestione degli errori. Esso ricalca il già noto Try…Catch del Framework .NET, e può essere implementato con il linguaggio Transact-SQL all’interno di Batch, Stored Procedure, User Defined Function e Trigger. La sintassi è la seguente:
BEGIN TRY Statement 1 … Statement n END TRY BEGIN CATCH … (Gestione degli errori) … END CATCH GO Al verificarsi di un errore durante l’esecuzione del codice racchiuso all’interno del blocco TRY, il flusso di esecuzione passa al blocco CATCH. Le istruzioni che seguono la fine del blocco CATCH, vengono eseguite in ogni caso (a meno che si faccia esplicitamente ricorso a un'istruzione che cambi il flusso di esecuzione come RETURN o GOTO). Una conseguenza di questo tipo di gestione è la possibilità di avere una gestione di logging degli errori più intelligente rispetto a quella della precedente versione di SQL Server, demandando la funzionalità di logging dell’errore ad una stored procedure, con un notevole vantaggio in termini di riusabilità del codice. Si noti che i due blocchi devono essere inclusi in un unico batch e che i blocchi TRY..CATCH possono anche essere nidificati. Allo scopo di controllare lo stato delle transazioni esplicite all’interno del blocco TRY…CATCH, è stata introdotta la funzione di sistema XACT_STATE() che permette di sapere se si può fare il COMMIT della transazione aperta. Se richiamata, XACT_STATE() fornisce i seguenti possibili valori: 1: se è attiva una transazione e la sessione può compiere qualsiasi azione (COMMIT o ROLLBACK) 0: se non vi è nessuna transazione attiva -1: se esiste una transazione aperta, ma non si può eseguire il COMMIT. Quindi, se aperta una transazione con BEGIN TRAN, si può valutare lo stato della transazione con XACT_STATE e, se uguale a -1, comandarne il ROLLBACK oppure rimediare all’errore per fare poi un COMMIT. BEGIN CATCH IF (XACT_STATE()) = -1 ROLLBACK TRANSACTION IF (XACT_STATE()) = 1 COMMIT TRANSACTION END CATCH Ricordo che la funzione di sistema @@TRANCOUNT, già presente in SQL Server 2000, permette invece di conoscere il numero di transazione aperte, ma non da alcuna informazione riguardo il suo stato. Tra gli errori intercettati dal blocco TRY…CATCH ci sono anche i Deadlock e, come in precedenza, non vengono intercettati né errori di sintassi né quelli dovuti alla risoluzione dei nomi (ovvero se si fa riferimento a oggetti di database inesistenti). Sono state introdotte nuove funzioni che forniscono informazioni sull’errore verificatosi: ERROR_MESSAGE() ERROR_NUMBER() ERROR_SEVERITY() ERROR_STATE() ERROR_PROCEDURE() ERROR_LINE() Tali funzioni sono utilizzabili all’interno del blocco CATCH, o in una stored procedure richiamata dal suo interno. Si noti, in particolare, le funzioni ERROR_PROCEDURE() e ERROR_LINE() che permettono di sapere il nome della procedura ed il numero della linea in cui si è verificato l’errore. Ma che fine fanno GOTO, @@ERROR e RAISERROR? Sono ancora utilizzabili, ma tenendo in considerazione che: Con il GOTO si è in grado di uscire da un blocco TRY..CATCH ma non di entrarvi La variabile di sistema @@ERROR, se adoperata nel blocco TRY…CATCH, necessita di essere usata nel primo statment del bocco CATCH. RAISERROR può essere molto utile per rilanciare un’eccezione al chiamante dall’interno del blocco TRY…CATCH. Articoli correlati: [1] F.Quaratino - "Stored Procedure sotto controllo", Xplayn.org / 2005
|