Die Raiserror- Methode
raiserror('Oh no a fatal error', 20, -1) with log
Dadurch wird die Verbindung beendet und der Rest des Skripts wird nicht mehr ausgeführt.
Beachten Sie, dass sowohl der Schweregrad 20 oder höher als auch die WITH LOG
Option erforderlich sind, damit dies funktioniert.
Dies funktioniert sogar mit GO-Anweisungen, z.
print 'hi'
go
raiserror('Oh no a fatal error', 20, -1) with log
go
print 'ho'
Wird Ihnen die Ausgabe geben:
hi
Msg 2745, Level 16, State 2, Line 1
Process ID 51 has raised user error 50000, severity 20. SQL Server is terminating this process.
Msg 50000, Level 20, State 1, Line 1
Oh no a fatal error
Msg 0, Level 20, State 0, Line 0
A severe error occurred on the current command. The results, if any, should be discarded.
Beachten Sie, dass 'ho' nicht gedruckt wird.
CAVEATS:
- Dies funktioniert nur, wenn Sie als Administrator ('sysadmin'-Rolle) angemeldet sind und Sie keine Datenbankverbindung haben.
- Wenn Sie NICHT als Administrator angemeldet sind, schlägt der Aufruf von RAISEERROR () selbst fehl und das Skript wird weiter ausgeführt .
- Beim Aufrufen mit sqlcmd.exe wird der Exit-Code 2745 gemeldet.
Referenz: http://www.mydatabasesupport.com/forums/ms-sqlserver/174037-sql-server-2000-abort-whole-script.html#post761334
Die noexec-Methode
Eine andere Methode, die mit GO-Anweisungen funktioniert, ist set noexec on
. Dadurch wird der Rest des Skripts übersprungen. Die Verbindung wird nicht beendet, Sie müssen noexec
sie jedoch erneut ausschalten, bevor Befehle ausgeführt werden.
Beispiel:
print 'hi'
go
print 'Fatal error, script will not continue!'
set noexec on
print 'ho'
go
-- last line of the script
set noexec off -- Turn execution back on; only needed in SSMS, so as to be able
-- to run this script again in the same session.
Verwenden Sie einfach eine RETURN (diese funktioniert sowohl innerhalb als auch außerhalb einer gespeicherten Prozedur).
quelle
Wenn Sie den SQLCMD-Modus verwenden können, dann die Beschwörung
(EINSCHLIESSLICH des Doppelpunkts) bewirkt, dass RAISERROR das Skript tatsächlich stoppt. Z.B,
wird ausgegeben:
und die Charge wird gestoppt. Wenn der SQLCMD-Modus nicht aktiviert ist, wird ein Analysefehler für den Doppelpunkt angezeigt. Leider ist es nicht vollständig kugelsicher, als ob das Skript ausgeführt wird, ohne sich im SQLCMD-Modus zu befinden. SQL Managment Studio ist selbst nach Analysezeitfehlern ein Kinderspiel! Wenn Sie sie jedoch über die Befehlszeile ausführen, ist dies in Ordnung.
quelle
Ich würde RAISERROR nicht verwenden. SQL verfügt über IF-Anweisungen, die für diesen Zweck verwendet werden können. Führen Sie Ihre Validierung und Suche durch und legen Sie lokale Variablen fest. Verwenden Sie dann den Wert der Variablen in IF-Anweisungen, um die Einfügungen bedingt zu machen.
Sie müssten nicht bei jedem Validierungstest ein variables Ergebnis überprüfen. Normalerweise können Sie dies mit nur einer Flag-Variablen tun, um alle übergebenen Bedingungen zu bestätigen:
Selbst wenn Ihre Validierung komplexer ist, sollten Sie nur wenige Flag-Variablen benötigen, um sie in Ihre endgültige (n) Prüfung (en) aufzunehmen.
quelle
RAISERROR
, insbesondere wenn Sie nicht wissen, wer die Skripte mit welchen Berechtigungen ausführen wird.declare @i int = 0; if @i=0 begin select '1st stmt in IF block' go end else begin select 'ELSE here' end go
In SQL 2012+ können Sie THROW verwenden .
Von MSDN:
quelle
Ich habe die Ein / Aus-Lösung von noexec erfolgreich um eine Transaktion erweitert, um das Skript vollständig oder gar nicht auszuführen.
Anscheinend "versteht" der Compiler die Variable @finished in der IF, auch wenn ein Fehler aufgetreten ist und die Ausführung deaktiviert wurde. Der Wert wird jedoch nur dann auf 1 gesetzt, wenn die Ausführung nicht deaktiviert wurde. Daher kann ich die Transaktion entsprechend gut festschreiben oder zurücksetzen.
quelle
IF (XACT_STATE()) <> 1 BEGIN Set NOCOUNT OFF ;THROW 525600, 'Rolling back transaction.', 1 ROLLBACK TRANSACTION; set noexec on END;
Aber die Ausführung wurde nie gestoppt und ich bekam drei Fehler bei "Rolling Back Transaction". Irgendwelche Ideen?Sie können Ihre SQL-Anweisung in eine WHILE-Schleife einschließen und bei Bedarf BREAK verwenden
quelle
DECLARE @ST INT; SET @ST = 1; WHILE @ST = 1; BEGIN; SET @ST = 0; ...; END
Ausführlicher, aber zum Teufel, es ist sowiesoSie können den Ausführungsfluss mithilfe von GOTO- Anweisungen ändern :
quelle
Bei der weiteren Verfeinerung der Sglasses-Methode erzwingen die obigen Zeilen die Verwendung des SQLCMD-Modus und zittern entweder den Scrirpt, wenn der SQLCMD-Modus nicht verwendet wird, oder verwenden ihn
:on error exit
, um einen Fehler zubeenden. CONTEXT_INFO wird verwendet, um den Status zu verfolgen.
quelle
Ist das eine gespeicherte Prozedur? Wenn ja, könnten Sie einfach eine Rückgabe durchführen, z. B. "Return NULL".
quelle
Ich würde vorschlagen, dass Sie Ihren entsprechenden Codeblock in einen try catch-Block einschließen. Sie können dann das Raiserror-Ereignis mit einem Schweregrad von 11 verwenden, um auf Wunsch zum catch-Block zu gelangen. Wenn Sie nur Fehler auslösen möchten, aber die Ausführung innerhalb des try-Blocks fortsetzen möchten, verwenden Sie einen niedrigeren Schweregrad.
Sinn ergeben?
Prost, John
[Bearbeitet, um BOL-Referenz einzuschließen]
http://msdn.microsoft.com/en-us/library/ms175976(SQL.90).aspx
quelle
Sie können RAISERROR verwenden .
quelle
Keine dieser Anweisungen funktioniert mit 'GO'-Anweisungen. In diesem Code erhalten Sie unabhängig davon, ob der Schweregrad 10 oder 11 beträgt, die endgültige PRINT-Anweisung.
Testskript:
Ergebnisse:
Die einzige Möglichkeit, dies zu erreichen, besteht darin, das Skript ohne
GO
Anweisungen zu schreiben . Manchmal ist das einfach. Manchmal ist es ziemlich schwierig. (Verwenden Sie so etwas wieIF @error <> 0 BEGIN ...
.)quelle
Ich benutze
RETURN
hier die ganze Zeit, arbeitet in Skript oderStored Procedure
Stellen Sie sicher, dass Sie
ROLLBACK
die Transaktion haben, wenn Sie sich in einer befinden. Andernfalls wirdRETURN
sofort eine offene, nicht festgeschriebene Transaktion angezeigtquelle
Das war meine Lösung:
...
quelle
Sie können die GOTO-Anweisung verwenden. Versuche dies. Dies ist voll für Sie zu nutzen.
quelle
Danke für die Antwort!
raiserror()
funktioniert gut, aber Sie sollten diereturn
Anweisung nicht vergessen , sonst wird das Skript ohne Fehler fortgesetzt! (hense der Raiserror ist kein "Throwerror" ;-)) und natürlich bei Bedarf einen Rollback machen!raiserror()
Es ist schön, der Person, die das Skript ausführt, mitzuteilen, dass ein Fehler aufgetreten ist.quelle
Wenn Sie einfach ein Skript in Management Studio ausführen und die Ausführung oder Rollback-Transaktion (falls verwendet) beim ersten Fehler stoppen möchten, ist es meiner Meinung nach am besten, den try catch-Block zu verwenden (ab SQL 2005). Dies funktioniert gut in Management Studio, wenn Sie eine Skriptdatei ausführen. Gespeicherte Prozesse können dies auch immer verwenden.
quelle
Früher haben wir Folgendes verwendet ... hat am besten funktioniert:
quelle
Schließen Sie es in einen try catch-Block ein, dann wird die Ausführung an catch übertragen.
quelle