Aus der RAISERROR-Dokumentation (Schwerpunkt Mine):
Schweregrade von 0 bis 18 können von jedem Benutzer angegeben werden. Schweregrade von 19 bis 25 können nur von Mitgliedern der festen Serverrolle sysadmin oder von Benutzern mit ALTER TRACE-Berechtigungen angegeben werden. Für Schweregrade von 19 bis 25 ist die Option WITH LOG erforderlich.
Es ist sehr wahrscheinlich, dass der Principal, den Sie ausführen, diese Kriterien nicht erfüllt.
Es ist nichts Falsches an der Verwendung RAISERROR
; Sie verwenden nur einen übermäßigen Schweregrad. Ich verwende Level 16 als Standard für einen Fehler, der ausgelöst wird und die Sequenz wird beendet. Wenn Sie genauer sein möchten, können Sie die von Microsoft selbst angegebenen Stufen befolgen:
Nach alledem ist die Verwendung RAISERROR
möglicherweise nicht ausreichend , je nach Kontext des Skripts, da das Skript nicht von selbst "beendet" wird (bei normalen Schweregraden).
Beispielsweise:
RAISERROR(N'Test', 16, 1);
SELECT 1; /* Executed! */
Dies wird sowohl einen Fehler auslösen und eine Ergebnismenge zurück.
Um das Skript sofort zu beenden, bevorzuge ich die Verwendung RETURN
(von GOTO
Konstrukten des Typs -type wird in den meisten Programmierkreisen, in denen es Alternativen gibt, generell abgeraten):
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
Oder behandeln Sie den Fehler mit TRY/CATCH
, der dazu führt, dass die Ausführung zum CATCH
Block springt, wenn der Schweregrad 11 oder höher ist:
BEGIN TRY
RAISERROR(N'Test', 16, 1);
SELECT 1; /* Not executed */
END TRY
BEGIN CATCH
SELECT 2; /* Executed */
END CATCH
BEGIN TRY
RAISERROR(N'Test', 10, 1);
SELECT 1; /* Executed */
END TRY
BEGIN CATCH
SELECT 2; /* Not executed */
END CATCH
Ein separates Problem besteht darin, dass das Skript mehrere Stapel umfasst undRETURN
nur den Stapel beendet :
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
GO
SELECT 2; /* Executed! */
Um dies zu beheben, können Sie @@ERROR
zu Beginn jedes Stapels Folgendes überprüfen :
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
GO
IF (@@ERROR != 0)
RETURN;
SELECT 2; /* Not executed */
Bearbeiten: Wie Martin Smith in den Kommentaren richtig hervorhebt, funktioniert dies nur für 2 Chargen. Um auf 3 oder mehr Stapel zu erweitern, können Sie Fehler wie GOTO
folgt kaskadieren (Hinweis: Die Methode löst dieses Problem nicht, da das Zieletikett innerhalb des Stapels definiert werden muss):
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
GO
IF (@@ERROR != 0)
BEGIN
RAISERROR(N'Error already raised. See previous errors.', 16, 1);
RETURN;
END
SELECT 2; /* Not executed */
GO
IF (@@ERROR != 0)
BEGIN
RAISERROR(N'Error already raised. See previous errors.', 16, 1);
RETURN;
END
SELECT 3; /* Not executed */
Oder, wie er auch betont, Sie können die SQLCMD
Methode verwenden, wenn dies für Ihre Umgebung geeignet ist.