Liste der Fehler beim Batch-Abbruch in SQL Server


9

Wenn in SQL Server XACT_ABORT deaktiviert ist, beenden einige Fehler die aktuelle Anweisung (z. B. die falsche Anzahl von Parametern für eine gespeicherte Prozedur, die einige Parameter akzeptiert), und einige Fehler brechen den gesamten Stapel ab (z. B. die Bereitstellung von Parametern für eine gespeicherte Prozedur) Prozedur, die keine Parameter akzeptiert). [Referenz]: http://www.sommarskog.se/error-handling-I.html#scope-abortion .

Was ich wissen möchte, ist, ob es eine endgültige Liste gibt, welche Fehler den Stapel abbrechen und welche die Anweisung beenden.

Antworten:


6

Ich glaube, es gibt einige Ausnahmen, aber von Database Engine Error Severities (MSDN) :

Fehlermeldungen mit einem Schweregrad von 19 oder höher stoppen die Ausführung des aktuellen Stapels.

Fehler, die die Datenbankverbindung beenden, normalerweise mit einem Schweregrad von 20 bis 25, werden vom CATCH-Block nicht behandelt, da die Ausführung beim Beenden der Verbindung abgebrochen wird.

Es scheint also, als könnten Sie eine endgültige Liste aus der folgenden Abfrage erhalten (natürlich können Sie dadurch nicht herausfiltern, welche durch den Benutzer T-SQL verursacht werden können):

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

In SQL Server 2012 werden 210 Zeilen erstellt.

In SQL Server 2016 werden dadurch 256 Zeilen erzeugt.

Ich glaube übrigens nicht, dass die beiden Szenarien, die Sie in Ihrer Frage beschreiben, so funktionieren, wie Sie denken, zumindest nicht in modernen Versionen von SQL Server. Ich habe dies sowohl 2012 als auch 2016 versucht (ich glaube, Erlands Artikel beschreibt das Verhalten von SQL Server 2000, an das ich mich nicht erinnere, wenn es anders war, aber heute nicht sehr relevant, selbst wenn dies der Fall ist).

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

Diese führen alle zu Fehlern des Schweregrads 16, und alle fahren mit dem Stapel fort, wie aus der Druckausgabe hervorgeht:

Nachricht 8146, Ebene 16, Status 2, Prozedur pA, Zeile 11
Prozedur pA enthält keine Parameter, und es wurden Argumente angegeben.
### Aufruf einer Prozedur, die keine Parameter mit einem Parameter
Msg 201, Level 16, Status 4, Prozedur pB, Zeile 14
akzeptiert Prozedur oder Funktion 'pB' erwartet den Parameter '@x', der nicht angegeben wurde.
### Aufruf einer Prozedur, die 2 Parameter ohne Parameter akzeptiert
Msg 201, Level 16, Status 4, Prozedur pB, Zeile 18
Prozedur oder Funktion 'pB' erwartet den Parameter '@y', der nicht angegeben wurde.
### Aufrufprozedur, die 2 Parameter mit nicht genügend Parametern
akzeptiert Msg 8144, Ebene 16, Status 2, Prozedur pB, Zeile 22
Prozedur oder Funktion pB hat zu viele Argumente angegeben.
### Aufruf einer Prozedur, die 2 Parameter mit zu vielen Parametern akzeptiert

Wie ich vermutet habe, gibt es natürlich Ausnahmen, wie in den Kommentaren erwähnt. Der Konvertierungsfehler hat den Schweregrad 16, bricht den Stapel jedoch ab:

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

Die Ergebnisse enthalten diesmal nicht die Druckausgabe:

Meldung 245, Ebene 16,
Status 1 Die Konvertierung ist fehlgeschlagen, wenn der Varchar-Wert 'foo' in den Datentyp int konvertiert wurde.


Vielen Dank! Ich dachte, ich könnte den Schweregrad aufgrund der vorherigen Inkonsistenz nicht als Indikator verwenden. Sehr froh zu hören, dass dies nicht der Fall ist.
Jamie Alford

Aargh! Es gibt immer noch einige Fehler der Schwerestufe 16, die den Stapel abbrechen. Wenn ich auswähle und ausführe: begin tran print @@ TRANCOUNT print convert (int, 'abc') gefolgt von: print @@ TRANCOUNT Es wird ein Fehler der Stufe 16 angezeigt, aber der Stapel wird abgebrochen.
Jamie Alford

Übrigens, wenn Sie Fälle entdecken, in denen die Ausnahme mit einem anderen Schweregrad als dem deklarierten
ausgelöst wird

2

Zusätzlich zu den von @Aaron festgestellten Fehlertypen (dh Schweregrad> = 19 und Konvertierungsfehler) brechen die folgenden Fehlertypen, die auf der MSDN-Seite für TRY ... CATCH angegeben sind , auch einen Stapel ab:

Die folgenden Fehlertypen werden von einem CATCH-Block nicht behandelt, wenn sie auf derselben Ausführungsebene wie das Konstrukt TRY… CATCH auftreten:

  • Kompilierungsfehler, z. B. Syntaxfehler, die die Ausführung eines Stapels verhindern.

  • Fehler, die während der Neukompilierung auf Anweisungsebene auftreten, z. B. Fehler bei der Auflösung von Objektnamen, die nach der Kompilierung aufgrund der verzögerten Namensauflösung auftreten.

Diese Fehler werden auf die Ebene zurückgegeben, auf der der Stapel, die gespeicherte Prozedur oder der Trigger ausgeführt wurden.

Beachten Sie in den folgenden Beispielen, dass drei davon sogar den Schweregrad 15 aufweisen.

BEISPIEL 1

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

Kehrt zurück:

Meldung 137, Ebene 15,
Status 2, Zeile 2 Muss die Skalarvariable "@NotDeclared" deklarieren.

BEISPIEL 2

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

Kehrt zurück:

Meldung 102, Ebene 15,
Status 1, Zeile 2 Falsche Syntax in der Nähe von 'InvalidSQL'.

BEISPIEL 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?';

Kehrt zurück:

Meldung 102, Ebene 15,
Status 1, Zeile 3 Falsche Syntax in der Nähe von '50505'.

BEISPIEL 4

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

Kehrt zurück:

Meldung 207, Ebene 16,
Status 1, Zeile 3 Ungültiger Spaltenname 'NoSuchColumn'.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.