TRY...CATCH (Transact-SQL)
Si applica a: SQL Server Database SQL di Azure Istanza gestita di SQL di Azure Azure Synapse Analytics Piattaforma di strumenti analitici (PDW) Endpoint di analisi SQL in Microsoft Fabric Warehouse in Microsoft Fabric
Implementa la gestione degli errori per Transact-SQL simile alla gestione delle eccezioni nei linguaggi C# e Visual C++. Un gruppo di istruzioni Transact-SQL può essere racchiuso in un TRY
blocco. Se si verifica un errore nel blocco, il TRY
controllo viene in genere passato a un altro gruppo di istruzioni racchiuso in un CATCH
blocco.
Convenzioni relative alla sintassi Transact-SQL
Sintassi
BEGIN TRY
{ sql_statement | statement_block }
END TRY
BEGIN CATCH
[ { sql_statement | statement_block } ]
END CATCH
[ ; ]
Argomenti
sql_statement
Qualsiasi istruzione Transact-SQL.
statement_block
Qualsiasi gruppo di istruzioni Transact-SQL in un batch o racchiuso in un BEGIN...END
blocco.
Osservazioni:
Un TRY...CATCH
costrutto rileva tutti gli errori di esecuzione con gravità superiore a 10 che non chiudono la connessione al database.
Un TRY
blocco deve essere seguito immediatamente da un blocco associato CATCH
. L'inclusione di qualsiasi altra istruzione tra le END TRY
istruzioni e BEGIN CATCH
genera un errore di sintassi.
Un TRY...CATCH
costrutto non può estendersi su più batch. Un TRY...CATCH
costrutto non può estendersi su più blocchi di istruzioni Transact-SQL. Ad esempio, un TRY...CATCH
costrutto non può estendersi su due BEGIN...END
blocchi di istruzioni Transact-SQL e non può estendersi su un IF...ELSE
costrutto.
Se non sono presenti errori nel codice racchiuso in un TRY
blocco, al termine dell'ultima istruzione nel TRY
blocco, il controllo passa all'istruzione immediatamente dopo l'istruzione associata END CATCH
.
Se si verifica un errore nel codice racchiuso in un TRY
blocco, il controllo passa alla prima istruzione nel blocco associato CATCH
. Al termine del CATCH
codice nel blocco, il controllo passa all'istruzione immediatamente dopo l'istruzione END CATCH
.
Nota
Se l'istruzione END CATCH
è l'ultima istruzione in una stored procedure o un trigger, il controllo viene passato all'istruzione che ha chiamato la stored procedure o attivato il trigger.
Gli errori intrappolati da un CATCH
blocco non vengono restituiti all'applicazione chiamante. Se una parte delle informazioni sull'errore deve essere restituita all'applicazione, il codice nel CATCH
blocco deve farlo usando meccanismi quali SELECT
set di risultati o RAISERROR
istruzioni e PRINT
.
TRY...CATCH
i costrutti possono essere annidati. Un TRY
blocco o un CATCH
blocco può contenere costrutti annidati TRY...CATCH
. Ad esempio, un CATCH
blocco può contenere un costrutto incorporato TRY...CATCH
per gestire gli errori rilevati dal CATCH
codice.
Gli errori rilevati in un CATCH
blocco vengono considerati come errori generati in qualsiasi altra posizione. Se il CATCH
blocco contiene un costrutto annidato, qualsiasi errore nel blocco annidato TRY...CATCH
TRY
passa il controllo al blocco annidato CATCH
. Se non è presente alcun costrutto annidato, l'errore viene restituito TRY...CATCH
al chiamante.
TRY...CATCH
costruisce rileva errori non gestiti da stored procedure o trigger eseguiti dal codice nel TRY
blocco. In alternativa, le stored procedure o i trigger possono contenere costrutti personalizzati TRY...CATCH
per gestire gli errori generati dal codice. Ad esempio, quando un TRY
blocco esegue una stored procedure e si verifica un errore nella stored procedure, l'errore può essere gestito nei modi seguenti:
Se la stored procedure non contiene il proprio
TRY...CATCH
costrutto, l'errore restituisce il controllo alCATCH
blocco associato alTRY
blocco che contiene l'istruzioneEXECUTE
.Se la stored procedure contiene un
TRY...CATCH
costrutto, il controllo viene trasferita alCATCH
blocco nella stored procedure. Al termine del codice del blocco, ilCATCH
controllo viene passato all'istruzione immediatamente dopo l'istruzioneEXECUTE
che ha chiamato la stored procedure.
GOTO
Le istruzioni non possono essere usate per immettere un TRY
blocco o CATCH
. GOTO
Le istruzioni possono essere usate per passare a un'etichetta all'interno dello stesso TRY
blocco o CATCH
per lasciare un TRY
blocco o CATCH
.
Il TRY...CATCH
costrutto non può essere usato in una funzione definita dall'utente.
Recuperare le informazioni sull'errore
Nell'ambito di un CATCH
blocco, è possibile usare le funzioni di sistema seguenti per ottenere informazioni sull'errore che ha causato l'esecuzione del CATCH
blocco:
Funzione | Descrizione |
---|---|
ERROR_NUMBER | Restituisce il numero dell'errore. |
ERROR_SEVERITY | Restituisce la gravità. |
ERROR_STATE | Restituisce il numero di stato dell'errore. |
ERROR_PROCEDURE | Restituisce il nome della stored procedure o del trigger in cui si è verificato l'errore. |
ERROR_LINE | Restituisce il numero di riga all'interno della routine che ha causato l'errore. |
ERROR_MESSAGE | Restituisce il testo completo del messaggio di errore. Il testo include i valori forniti da qualsiasi parametro sostituibile, ad esempio lunghezze, nomi di oggetti oppure orari. |
Queste funzioni restituiscono NULL
se vengono chiamate all'esterno dell'ambito del CATCH
blocco. Le informazioni sugli errori possono essere recuperate usando queste funzioni da qualsiasi punto all'interno dell'ambito del CATCH
blocco. Nello script seguente, ad esempio, viene illustrata una stored procedure contenente funzioni di gestione degli errori. Nel blocco CATCH
di un costrutto TRY...CATCH
viene chiamata la stored procedure e vengono restituite informazioni sull'errore.
-- Verify that the stored procedure does not already exist.
IF OBJECT_ID('usp_GetErrorInfo', 'P') IS NOT NULL
DROP PROCEDURE usp_GetErrorInfo;
GO
-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
SELECT ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
GO
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1 / 0;
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
EXECUTE usp_GetErrorInfo;
END CATCH;
Le ERROR_*
funzioni funzionano anche in un CATCH
blocco all'interno di una stored procedure compilata in modo nativo.
Errori non interessati da un tentativo... Costrutto CATCH
TRY...CATCH
i costrutti non intercettare le condizioni seguenti:
Avvisi o messaggi informativi con livello di gravità minore o uguale a 10.
Errori con livello di gravità maggiore o uguale a 20 che determinano l'arresto dell'elaborazione dell'attività del motore di database di SQL Server per la sessione. Se si verifica un errore con gravità pari o superiore a 20 e la connessione al database non viene interrotta,
TRY...CATCH
gestisce l'errore.Situazioni di attenzione, richieste di interruzione dei client o interruzione delle connessioni client.
Quando un amministratore di sistema usa l'istruzione
KILL
per terminare la sessione.
I tipi di errori seguenti non vengono gestiti da un CATCH
blocco quando si verificano allo stesso livello di esecuzione del TRY...CATCH
costrutto:
Errori di compilazione, ad esempio errori di sintassi, che impediscono l'esecuzione di un batch.
Errori che si verificano durante la ricompilazione a livello di istruzione, ad esempio errori di risoluzione dei nomi degli oggetti che si verificano dopo la compilazione a causa della risoluzione dei nomi posticipata.
Errori di risoluzione del nome oggetto
Questi errori sono restituiti al livello che ha eseguito il batch, la stored procedure o il trigger.
Se si verifica un errore durante la compilazione o la ricompilazione a livello di istruzione a un livello di esecuzione inferiore (ad esempio, durante l'esecuzione sp_executesql
o una stored procedure definita dall'utente) all'interno del TRY
blocco, l'errore si verifica a un livello inferiore rispetto al TRY...CATCH
costrutto e verrà gestito dal blocco associato CATCH
.
Nell'esempio seguente viene illustrato come un errore di risoluzione dei nomi di oggetto generato da un'istruzione SELECT
non venga intercettato dal TRY...CATCH
costrutto, ma viene intercettato dal CATCH
blocco quando la stessa SELECT
istruzione viene eseguita all'interno di una stored procedure.
BEGIN TRY
-- Table does not exist; object name resolution
-- error not caught.
SELECT *
FROM NonexistentTable;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNumber,
ERROR_MESSAGE() AS ErrorMessage;
END CATCH
L'errore non viene intercettato e il controllo passa dal TRY...CATCH
costrutto al livello superiore successivo.
Se si esegue l'istruzione SELECT
all'interno di una stored procedure, l'errore si verifica a un livello inferiore al TRY
blocco. L'errore viene gestito dal TRY...CATCH
costrutto .
-- Verify that the stored procedure does not exist.
IF OBJECT_ID(N'usp_ExampleProc', N'P') IS NOT NULL
DROP PROCEDURE usp_ExampleProc;
GO
-- Create a stored procedure that will cause an
-- object resolution error.
CREATE PROCEDURE usp_ExampleProc
AS
SELECT *
FROM NonexistentTable;
GO
BEGIN TRY
EXECUTE usp_ExampleProc;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNumber,
ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
Transazioni e XACT_STATE non modificabili
Se un errore generato in un TRY
blocco causa l'invalidazione dello stato della transazione corrente, la transazione viene classificata come transazione non modificabile. Un errore che in genere termina una transazione all'esterno di un TRY
blocco fa sì che una transazione entri in uno stato non modificabile quando l'errore si verifica all'interno di un TRY
blocco. Una transazione non modificabile può eseguire solo operazioni di lettura o .ROLLBACK TRANSACTION
La transazione non può eseguire istruzioni Transact-SQL che generano un'operazione di scrittura o .COMMIT TRANSACTION
La XACT_STATE
funzione restituisce un valore di -1
se una transazione è stata classificata come transazione non modificabile. Al termine di un batch, il motore di database esegue automaticamente il rollback di qualsiasi transazione attiva di cui non è possibile eseguire il commit. Se non viene inviato alcun messaggio di errore quando la transazione ha immesso uno stato non modificabile, al termine del batch viene inviato un messaggio di errore all'applicazione client. Viene così indicato che è stata rilevata una transazione bloccata e ne è stato eseguito il rollback.
Per altre informazioni sulle transazioni non committable e sulla XACT_STATE
funzione , vedere XACT_STATE.
Esempi
R. Usare TRY...CATCH
Nell'esempio seguente viene illustrata un'istruzione SELECT
che genera un errore di divisione per zero. L'errore determina il passaggio dell'esecuzione al blocco CATCH
associato.
BEGIN TRY
-- Generate a divide-by-zero error.
SELECT 1 / 0;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
GO
B. Usare TRY... CATCH in una transazione
Nell'esempio seguente viene illustrato il funzionamento di un blocco TRY...CATCH
all'interno di una transazione. L'istruzione all'interno del blocco TRY
genera un errore di violazione di vincolo.
BEGIN TRANSACTION;
BEGIN TRY
-- Generate a constraint violation error.
DELETE
FROM Production.Product
WHERE ProductID = 980;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO
C. Usare TRY... CATCH con XACT_STATE
Nell'esempio seguente viene illustrato come utilizzare il costrutto TRY...CATCH
per gestire gli errori che si verificano all'interno di una transazione. La funzione XACT_STATE
determina se è necessario eseguire il commit o il rollback della transazione. In this example, l'evento SET XACT_ABORT
è ON
. Rende pertanto bloccata la transazione quando si verifica l'errore di violazione di vincolo.
-- Check to see whether this stored procedure exists.
IF OBJECT_ID(N'usp_GetErrorInfo', N'P') IS NOT NULL
DROP PROCEDURE usp_GetErrorInfo;
GO
-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
SELECT ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_LINE() AS ErrorLine,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_MESSAGE() AS ErrorMessage;
GO
-- SET XACT_ABORT ON will cause the transaction to be uncommittable
-- when the constraint violation occurs.
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION;
-- A FOREIGN KEY constraint exists on this table. This
-- statement will generate a constraint violation error.
DELETE
FROM Production.Product
WHERE ProductID = 980;
-- If the DELETE statement succeeds, commit the transaction.
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
EXECUTE usp_GetErrorInfo;
-- Test XACT_STATE:
-- If 1, the transaction is committable.
-- If -1, the transaction is uncommittable and should
-- be rolled back.
-- XACT_STATE = 0 means that there is no transaction and
-- a commit or rollback operation would generate an error.
-- Test whether the transaction is uncommittable.
IF (XACT_STATE()) = -1
BEGIN
PRINT N'The transaction is in an uncommittable state. Rolling back transaction.'
ROLLBACK TRANSACTION;
END;
-- Test whether the transaction is committable.
-- You may want to commit a transaction in a catch block if you want to commit changes to statements that ran prior to the error.
IF (XACT_STATE()) = 1
BEGIN
PRINT N'The transaction is committable. Committing transaction.'
COMMIT TRANSACTION;
END;
END CATCH;
GO
Contenuto correlato
- THROW (Transact-SQL)
- motore di database gravità degli errori
- ERROR_LINE (Transact-SQL)
- ERROR_MESSAGE (Transact-SQL)
- ERROR_NUMBER (Transact-SQL)
- ERROR_PROCEDURE (Transact-SQL)
- ERROR_SEVERITY (Transact-SQL)
- ERROR_STATE (Transact-SQL)
- RAISERROR (Transact-SQL)
- @@ERROR (Transact-SQL)
- GOTO (Transact-SQL)
- COMINCIARE... END (Transact-SQL)
- XACT_STATE (Transact-SQL)
- SET XACT_ABORT (Transact-SQL)