TRY...CATCH (Transact-SQL)
S’applique à : SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW) SQL analytics endpoint in Microsoft Fabric Warehouse in Microsoft Fabric
Implémente la gestion des erreurs pour Transact-SQL similaire à la gestion des exceptions dans les langages C# et Visual C++. Un groupe d’instructions Transact-SQL peut être placé dans un TRY
bloc. Si une erreur se produit dans le TRY
bloc, le contrôle est généralement passé à un autre groupe d’instructions placés dans un CATCH
bloc.
Conventions de la syntaxe Transact-SQL
Syntaxe
BEGIN TRY
{ sql_statement | statement_block }
END TRY
BEGIN CATCH
[ { sql_statement | statement_block } ]
END CATCH
[ ; ]
Arguments
sql_statement
Toute instruction Transact-SQL.
statement_block
Tout groupe d’instructions Transact-SQL dans un lot ou placé dans un BEGIN...END
bloc.
Notes
Une TRY...CATCH
construction intercepte toutes les erreurs d’exécution dont la gravité est supérieure à 10 et qui ne ferment pas la connexion de base de données.
Un TRY
bloc doit être immédiatement suivi d’un bloc associé CATCH
. L’inclusion d’autres instructions entre les END TRY
instructions génère BEGIN CATCH
une erreur de syntaxe.
Une TRY...CATCH
construction ne peut pas s’étendre sur plusieurs lots. Une TRY...CATCH
construction ne peut pas s’étendre sur plusieurs blocs d’instructions Transact-SQL. Par exemple, une TRY...CATCH
construction ne peut pas s’étendre sur deux BEGIN...END
blocs d’instructions Transact-SQL et ne peut pas s’étendre sur une IF...ELSE
construction.
S’il n’y a aucune erreur dans le code placé dans un TRY
bloc, lorsque la dernière instruction du TRY
bloc se termine, le contrôle passe à l’instruction immédiatement après l’instruction associée END CATCH
.
S’il existe une erreur dans le code placé entre un TRY
bloc, le contrôle passe à la première instruction du bloc associé CATCH
. Une fois le code du CATCH
bloc terminé, le contrôle passe à l’instruction immédiatement après l’instruction END CATCH
.
Remarque
Si l’instruction est la dernière instruction d’une procédure stockée ou d’un déclencheur, le END CATCH
contrôle est repassé à l’instruction qui a appelé la procédure stockée ou déclenché le déclencheur.
Les erreurs interceptées par un CATCH
bloc ne sont pas retournées à l’application appelante. Si une partie des informations d’erreur doit être retournée à l’application, le code du CATCH
bloc doit le faire à l’aide de mécanismes tels que SELECT
les jeux de résultats ou les RAISERROR
instructions PRINT
.
TRY...CATCH
les constructions peuvent être imbriquées. Un TRY
bloc ou un CATCH
bloc peut contenir des constructions imbriquées TRY...CATCH
. Par exemple, un CATCH
bloc peut contenir une construction incorporée TRY...CATCH
pour gérer les erreurs rencontrées par le CATCH
code.
Les erreurs rencontrées dans un CATCH
bloc sont traitées comme des erreurs générées ailleurs. Si le CATCH
bloc contient une construction imbriquée TRY...CATCH
, toute erreur dans le bloc imbriqué TRY
passe le contrôle au bloc imbriqué CATCH
. S’il n’existe aucune construction imbriquée TRY...CATCH
, l’erreur est renvoyée à l’appelant.
TRY...CATCH
crée des erreurs non gérées à partir de procédures stockées ou de déclencheurs exécutés par le code dans le TRY
bloc. Les procédures stockées ou les déclencheurs peuvent également contenir leurs propres TRY...CATCH
constructions pour gérer les erreurs générées par leur code. Par exemple, lorsqu’un TRY
bloc exécute une procédure stockée et qu’une erreur se produit dans la procédure stockée, l’erreur peut être gérée de la manière suivante :
Si la procédure stockée ne contient pas sa propre
TRY...CATCH
construction, l’erreur retourne le contrôle auCATCH
bloc associé auTRY
bloc qui contient l’instructionEXECUTE
.Si la procédure stockée contient une
TRY...CATCH
construction, l’erreur transfère leCATCH
contrôle au bloc dans la procédure stockée. Une fois le code de bloc terminé, leCATCH
contrôle est repassé à l’instruction immédiatement après l’instructionEXECUTE
qui a appelé la procédure stockée.
GOTO
les instructions ne peuvent pas être utilisées pour entrer un ou CATCH
un TRY
bloc. GOTO
les instructions peuvent être utilisées pour accéder à une étiquette à l’intérieur du même ou du même TRY
bloc ou CATCH
pour quitter un ou CATCH
un TRY
bloc.
La TRY...CATCH
construction ne peut pas être utilisée dans une fonction définie par l’utilisateur.
Récupérer les informations d’erreur
Dans l’étendue d’un CATCH
bloc, les fonctions système suivantes peuvent être utilisées pour obtenir des informations sur l’erreur qui a provoqué l’exécution du CATCH
bloc :
Fonction | Description |
---|---|
ERROR_NUMBER | Retourne le nombre de l’erreur. |
ERROR_SEVERITY | Retourne la gravité. |
ERROR_STATE | Retourne le numéro d’état d’erreur. |
ERROR_PROCEDURE | Retourne le nom de la procédure stockée ou du déclencheur où l’erreur s’est produite. |
ERROR_LINE | Retourne le numéro de ligne à l’intérieur de la routine qui a provoqué l’erreur. |
ERROR_MESSAGE | Retourne le texte complet du message d’erreur. Le texte comprend les valeurs fournies pour tous les paramètres remplaçables, tels que les longueurs, les noms d'objet ou les heures. |
Ces fonctions retournent NULL
si elles sont appelées en dehors de l’étendue du CATCH
bloc. Les informations d’erreur peuvent être récupérées à l’aide de ces fonctions n’importe où dans l’étendue du CATCH
bloc. Par exemple, le script suivant montre une procédure stockée contenant des fonctions de gestion des erreurs : dans le bloc CATCH
d'une construction TRY...CATCH
, la procédure stockée est appelée et les informations sur l'erreur sont retournées.
-- 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;
Les ERROR_*
fonctions fonctionnent également dans un CATCH
bloc à l’intérieur d’une procédure stockée compilée en mode natif.
Erreurs non affectées par un TRY... Construction CATCH
TRY...CATCH
les constructions ne interceptent pas les conditions suivantes :
Les avertissements ou messages d'information dont la gravité est inférieure ou égale à 10.
Les erreurs dont le niveau de gravité est supérieur ou égal à 20 interrompent le traitement des tâches du Moteur de base de données SQL Server pour la session. Si une erreur se produit qui a une gravité de 20 ou supérieure et que la connexion de base de données n’est pas interrompue,
TRY...CATCH
gère l’erreur.Un événement d'avertissement, tel qu'une requête d'interruption par le client ou une rupture de connexion avec le client, se produit.
Lorsqu’un administrateur système utilise l’instruction
KILL
pour mettre fin à la session.
Les types d’erreurs suivants ne sont pas gérés par un CATCH
bloc lorsqu’ils se produisent au même niveau d’exécution que la TRY...CATCH
construction :
Les erreurs de compilation, telles que les erreurs de syntaxe, qui empêchent un traitement de s'exécuter.
Les erreurs qui se produisent pendant une recompilation de niveau instruction, telles que les erreurs de résolution de nom d’objet qui surviennent après la compilation en raison d’une résolution de nom différée.
Erreurs de résolution de noms d’objets
Ces erreurs sont renvoyées au niveau qui a exécuté le traitement, la procédure stockée ou le déclencheur.
Si une erreur se produit pendant la recompilation au niveau de la compilation ou de l’instruction à un niveau d’exécution inférieur (par exemple, lors de l’exécution sp_executesql
ou d’une procédure stockée définie par l’utilisateur) à l’intérieur du TRY
bloc, l’erreur se produit à un niveau inférieur à la TRY...CATCH
construction et sera gérée par le bloc associé CATCH
.
L’exemple suivant montre comment une erreur de résolution de noms d’objet générée par une SELECT
instruction n’est pas interceptée par la TRY...CATCH
construction, mais interceptée par le CATCH
bloc lorsque la même SELECT
instruction est exécutée à l’intérieur d’une procédure stockée.
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’erreur n’est pas interceptée et le contrôle passe de la TRY...CATCH
construction au niveau supérieur suivant.
L’exécution de l’instruction à l’intérieur SELECT
d’une procédure stockée provoque l’erreur à un niveau inférieur au TRY
bloc. L’erreur est gérée par la TRY...CATCH
construction.
-- 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;
Transactions non modifiables et XACT_STATE
Si une erreur générée dans un TRY
bloc entraîne l’invalidation de l’état de la transaction actuelle, la transaction est classifiée comme une transaction noncommittable. Une erreur qui met généralement fin à une transaction en dehors d’un TRY
bloc entraîne l’entrée d’une transaction dans un état noncommittable lorsque l’erreur se produit à l’intérieur d’un TRY
bloc. Une transaction noncommittable ne peut effectuer que des opérations de lecture ou un ROLLBACK TRANSACTION
. La transaction ne peut pas exécuter d’instructions Transact-SQL qui généreraient une opération d’écriture ou un COMMIT TRANSACTION
. La XACT_STATE
fonction retourne une valeur de -1
si une transaction a été classifiée comme une transaction noncommittable. Lorsqu'un traitement est terminé, le Moteur de base de données restaure automatiquement toutes les transactions non validables actives. Si aucun message d’erreur n’a été envoyé lorsque la transaction a entré un état noncommittable, une fois le lot terminé, un message d’erreur est envoyé à l’application cliente. Cela indique qu'une transaction non validable a été détectée et annulée.
Pour plus d’informations sur les transactions non modifiables et la XACT_STATE
fonction, consultez XACT_STATE.
Exemples
R. Utiliser TRY... CATCH
L’exemple suivant montre une instruction SELECT
qui génère une erreur de division par zéro. L'erreur entraîne le saut de l'exécution vers le bloc CATCH
associé.
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. Utiliser TRY... CATCH dans une transaction
L'exemple suivant montre comment un bloc TRY...CATCH
fonctionne dans une transaction. L'instruction dans le bloc TRY
génère une erreur de violation de contrainte.
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. Utiliser TRY... CATCH avec XACT_STATE
L'exemple suivant montre comment utiliser la construction TRY...CATCH
pour gérer les erreurs qui surviennent dans une transaction. La fonction XACT_STATE
détermine si la transaction doit être validée ou annulée. Dans cet exemple, SET XACT_ABORT
est ON
. Cela rend la transaction non validable lorsque l'erreur de violation de contrainte se produit.
-- 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
Contenu connexe
- THROW (Transact-SQL)
- gravités d’erreur Moteur de base de données
- 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)
- BEGIN...END (Transact-SQL)
- XACT_STATE (Transact-SQL)
- SET XACT_ABORT (Transact-SQL)