Implementare la gestione strutturata delle eccezioni

Completato

Ora che si ha una conoscenza della natura degli errori e della gestione degli errori di base in T-SQL, è possibile esaminare una forma più avanzata di gestione degli errori. La gestione strutturata delle eccezioni è stata introdotta in SQL Server 2005.

In questa sezione viene illustrato come usarlo e valutarne i vantaggi e le limitazioni, tra cui il blocco TRY CATCH, il ruolo delle funzioni di gestione degli errori e la comprensione della differenza tra errori intercettabili e non recuperabili. Infine, si vedrà come gestire e visualizzare gli errori quando necessario.

Che cos'è la programmazione a blocchi TRY/CATCH

La gestione strutturata delle eccezioni è più efficace della gestione degli errori basata sulla variabile di sistema @@ERROR. Consente di impedire che il codice venga inserito nel codice di gestione degli errori e di centralizzare il codice di gestione degli errori. Centralizzazione del codice di gestione degli errori significa anche che è possibile concentrarsi maggiormente sullo scopo del codice anziché sulla gestione degli errori che contiene.

Blocco TRY e blocco CATCH

Quando si usa la gestione strutturata delle eccezioni, il codice che potrebbe generare un errore viene inserito all'interno di un blocco TRY. I blocchi TRY sono racchiusi tra le istruzioni BEGIN TRY e END TRY .

Se si verifica un errore intercettabile: la maggior parte degli errori può essere rilevata, il controllo di esecuzione passa al blocco CATCH. Il blocco CATCH è una serie di istruzioni T-SQL racchiuse dalle istruzioni BEGIN CATCH e END CATCH .

Annotazioni

Mentre BEGIN CATCH e END TRY sono istruzioni separate, BEGIN CATCH deve seguire immediatamente END TRY.

Limitazioni correnti

I linguaggi di alto livello spesso offrono un costrutto try/catch/finally e vengono spesso usati per rilasciare le risorse in modo implicito. Non esiste alcun blocco FINALLY equivalente in T-SQL.

Comprendere la differenza tra errori rilevabili e non recuperabili

È importante tenere presente che, mentre i blocchi TRY/CATCH consentono di intercettare una gamma molto più ampia di errori rispetto a @@ERROR, non è possibile intercettare ogni tipo.

Errori rilevabili e non recuperabili

Non tutti gli errori possono essere rilevati dai blocchi TRY/CATCH all'interno dello stesso ambito in cui esiste il blocco TRY/CATCH. Spesso, gli errori che non possono essere rilevati nello stesso ambito possono essere rilevati in un ambito circostante. Ad esempio, potrebbe non essere possibile intercettare un errore all'interno della stored procedure contenente il blocco TRY/CATCH. Tuttavia, è probabile che si intercetta l'errore in un blocco TRY/CATCH nel codice che ha chiamato la stored procedure in cui si è verificato l'errore.

Errori comuni non recuperabili

Esempi comuni di errori non recuperabili sono:

  • Errori di compilazione, ad esempio errori di sintassi, che impediscono la compilazione di un batch.
  • Problemi di ricompilazione a livello di istruzione correlati in genere alla risoluzione dei nomi posticipata. Ad esempio, è possibile creare una stored procedure che fa riferimento a una tabella sconosciuta. Viene generato un errore solo quando la routine tenta di risolvere il nome della tabella in un objectid.

Come rigenerare gli errori tramite THROW

Se l'istruzione THROW viene usata in un blocco CATCH senza parametri, verrà generato nuovamente l'errore che ha causato l'immissione del codice nel blocco CATCH. È possibile usare questa tecnica per implementare la registrazione degli errori nel database rilevando gli errori e registrandone i dettagli e quindi generando l'errore originale all'applicazione client, in modo che possa essere gestito in tale posizione.

Di seguito è riportato un esempio di come rigenerare un errore.

BEGIN TRY
    -- code to be executed
END TRY
BEGIN CATCH
    PRINT ERROR_MESSAGE();
    THROW
END CATCH

In alcune versioni precedenti di SQL Server non esiste alcun metodo per generare un errore di sistema. Anche se THROW non può specificare un errore di sistema da generare, quando THROW viene usato senza parametri in un blocco CATCH, verrà ricreato sia gli errori di sistema che degli utenti.

Che cosa sono le funzioni di gestione degli errori

I blocchi CATCH rendono disponibili le informazioni relative agli errori per tutta la durata del blocco CATCH. Sono inclusi ambiti secondari, ad esempio stored procedure, eseguiti dall'interno del blocco CATCH.

Funzioni di gestione degli errori

È necessario ricordare che, quando si programma con @@ERROR, il valore mantenuto dalla variabile di sistema @@ERROR è stato reimpostato non appena è stata eseguita l'istruzione successiva.

Un altro vantaggio chiave della gestione delle eccezioni strutturata in T-SQL è che è stata fornita una serie di funzioni di gestione degli errori e che mantengono i valori in tutto il blocco CATCH. Le funzioni separate forniscono ogni proprietà di un errore generato.

Ciò significa che è possibile scrivere stored procedure di gestione degli errori generiche che possono comunque accedere alle informazioni correlate agli errori.

  • I blocchi CATCH rendono disponibili le informazioni relative agli errori per tutta la durata del blocco CATCH.
  • @@Error viene reimpostato quando viene eseguita l'istruzione successiva.

Gestire gli errori nel codice

L'integrazione di SQL CLR consente l'esecuzione di codice gestito all'interno di SQL Server. I linguaggi .NET di alto livello, ad esempio C# e VB, dispongono di una gestione dettagliata delle eccezioni. Gli errori possono essere rilevati usando blocchi try/catch/finally .NET standard.

Errori nel codice gestito

In generale, è possibile rilevare gli errori nel codice gestito il più possibile. È tuttavia importante rendersi conto che tutti gli errori non gestiti nel codice gestito vengono passati al codice T-SQL chiamante. Ogni volta che si verifica un errore nel codice gestito viene restituito a SQL Server, viene visualizzato un errore 6522. Gli errori possono essere annidati e questo particolare errore eseguirà il wrapping della causa reale dell'errore.

Un'altra rara ma possibile causa di errori nel codice gestito sarebbe che il codice potrebbe eseguire un'istruzione T-SQL RAISERROR tramite un oggetto SqlCommand.