liste des erreurs d'abandon de lot dans SQL Server

9

Dans SQL Server, si XACT_ABORT est désactivé, certaines erreurs mettront fin à l'instruction en cours (par exemple, fournir le nombre incorrect de paramètres à une procédure stockée qui prend certains paramètres) et certaines erreurs abandonneront le lot entier (par exemple, fournir des paramètres à un stocké qui ne prend pas de paramètres). [Référence]: http://www.sommarskog.se/error-handling-I.html#scope-abortion .

Ce que j'aimerais savoir, c'est s'il existe une liste définitive des erreurs qui abandonnent par lots et celles qui terminent l'instruction.

Jamie Alford
la source

Réponses:

6

Je crois qu'il y a quelques exceptions, mais à partir des gravités d'erreur du moteur de base de données (MSDN) :

Les messages d'erreur avec un niveau de gravité de 19 ou supérieur arrêtent l'exécution du lot en cours.

Les erreurs qui mettent fin à la connexion à la base de données, généralement avec une gravité de 20 à 25, ne sont pas gérées par le bloc CATCH car l'exécution est abandonnée à la fin de la connexion.

Il semble donc que vous puissiez obtenir une liste définitive de la requête suivante (bien sûr, cela ne vous permettra pas de filtrer celles qui peuvent être causées par l'utilisateur T-SQL):

SELECT message_id, severity, [text]
FROM sys.messages
WHERE language_id = 1033 
AND severity >= 19
ORDER BY severity, message_id;

Dans SQL Server 2012, cela produit 210 lignes.

Dans SQL Server 2016, cela produit 256 lignes.

Soit dit en passant, je ne crois pas que les deux scénarios que vous décrivez dans votre question fonctionnent comme vous le pensez, du moins pas dans les versions modernes de SQL Server. J'ai essayé cela à la fois sur 2012 et 2016 (je crois que l'article d'Erland décrit le comportement de SQL Server 2000, dont je ne me souviens pas s'il était différent, mais pas très pertinent aujourd'hui, même si c'est le cas).

USE tempdb;
GO

CREATE PROCEDURE dbo.pA -- no parameters
AS PRINT 1
GO
CREATE PROCEDURE dbo.pB -- two parameters
@x INT, @y INT
AS PRINT 1
GO

SET XACT_ABORT OFF;
GO

EXEC dbo.pA @foo = 1; 
PRINT '### Calling procedure that doesn''t take parameters with a parameter';
GO

EXEC dbo.pB; 
PRINT '### Calling procedure that takes 2 parameters with no parameters';
GO

EXEC dbo.pB @x = 1; 
PRINT '### Calling procedure that takes 2 parameters with not enough parameters';
GO

EXEC dbo.pB @x = 1, @y = 2, @z = 3; 
PRINT '### Calling procedure that takes 2 parameters with too many parameters';
GO

Tous ces éléments produisent des erreurs de niveau de gravité 16, et tous continuent avec le lot, comme en témoigne la sortie d'impression:

Msg 8146, niveau 16, état 2, procédure pA, ligne 11 La
procédure pA n'a aucun paramètre et aucun argument n'a été fourni.
### Procédure d'appel qui ne prend pas de paramètres avec un paramètre
Msg 201, niveau 16, état 4, procédure pB, ligne 14 La
procédure ou la fonction 'pB' attend le paramètre '@x', qui n'a pas été fourni.
### Procédure d'appel qui prend 2 paramètres sans paramètres
Msg 201, niveau 16, état 4, procédure pB, ligne 18 La
procédure ou la fonction 'pB' attend le paramètre '@y', qui n'a pas été fourni.
### Procédure d'appel qui prend 2 paramètres avec pas assez de paramètres
Msg 8144, niveau 16, état 2, procédure pB, ligne 22 La
procédure ou la fonction pB a trop d'arguments spécifiés.
### Procédure d'appel qui prend 2 paramètres avec trop de paramètres

Comme je le soupçonnais, il y a des exceptions, bien sûr, comme indiqué dans les commentaires. L'échec de la conversion est de gravité 16 mais abandonne le lot:

SET XACT_ABORT OFF;
SELECT CONVERT (INT, 'foo');
PRINT 'Made it.'; -- no print happens

Les résultats n'incluent pas la sortie d'impression cette fois:

Msg 245, niveau 16, la
conversion de l' état 1 a échoué lors de la conversion de la valeur varchar 'foo' en type de données int.

Aaron Bertrand
la source
Merci beaucoup! Je pensais que je ne serais pas en mesure d'utiliser le niveau de gravité comme indicateur en raison de l'incohérence antérieure. Très heureux d'apprendre que ce n'est pas le cas.
Jamie Alford
Aargh! Il y a encore des erreurs de niveau de gravité 16 qui annuleront le lot. Si je sélectionne et exécute: commencez tran print @@ TRANCOUNT print convert (int, 'abc') suivi de: print @@ TRANCOUNT Il y aura une erreur de niveau 16 mais le lot sera abandonné.
Jamie Alford
BTW, si vous découvrez des cas où l'exception est déclenchée avec une gravité différente de celle déclarée, veuillez les signaler via connect
Remus Rusanu
2

En plus des types d'erreurs notés par @Aaron (c'est-à-dire Gravité> = 19 et échecs de conversion), les types d'erreurs suivants, notés dans la page MSDN pour TRY ... CATCH , annuleront également un lot:

Les types d'erreurs suivants ne sont pas traités par un bloc CATCH lorsqu'ils se produisent au même niveau d'exécution que la construction TRY… CATCH:

  • Compiler des erreurs, telles que des erreurs de syntaxe, qui empêchent l'exécution d'un lot.

  • Erreurs qui se produisent lors de la recompilation au niveau de l'instruction, telles que les erreurs de résolution de nom d'objet qui se produisent après la compilation en raison d'une résolution de nom différée.

Ces erreurs sont renvoyées au niveau qui a exécuté le lot, la procédure stockée ou le déclencheur.

Dans les exemples ci-dessous, veuillez noter que trois d'entre eux sont même de niveau de gravité 15.

EXEMPLE 1

SET XACT_ABORT OFF;
SELECT @NotDeclared; -- parse error
PRINT 'Do you see me?';

Retour:

Msg 137, niveau 15, état 2, ligne 2
Doit déclarer la variable scalaire "@NotDeclared".

EXEMPLE 2

SET XACT_ABORT OFF;
InvalidSQL; -- parse error
PRINT 'Do you see me?';

Retour:

Msg 102, niveau 15, état 1, ligne 2
Syntaxe incorrecte près de 'InvalidSQL'.

EXEMPLE 3

SET XACT_ABORT OFF;
SELECT 1 -- statement preceding THROW not terminated by semicolon
THROW 50505, N'Error, yo', 1; -- parse error
PRINT 'Do you see me?';

Retour:

Msg 102, niveau 15, état 1, ligne 3
Syntaxe incorrecte près de '50505'.

EXEMPLE 4

SET XACT_ABORT OFF;
SELECT NoSuchColumn FROM sys.objects; -- compilation error
PRINT 'Do you see me?';

Retour:

Msg 207, niveau 16, état 1, ligne 3
Nom de colonne non valide «NoSuchColumn».

Solomon Rutzky
la source