SQL Server-zatrzymanie lub przerwanie wykonywania skryptu SQL
Czy istnieje sposób, aby natychmiast zatrzymać wykonywanie skryptu SQL w SQL server, jak polecenie" break "lub" exit"?
Mam skrypt, który wykonuje walidację i wyszukiwanie przed rozpoczęciem wstawiania i chcę, aby przestał, jeśli którekolwiek z walidacji lub wyszukiwania nie powiedzie się.
18 answers
Metoda raiserror
raiserror('Oh no a fatal error', 20, -1) with log
Spowoduje to przerwanie połączenia, tym samym zatrzymując resztę skryptu przed uruchomieniem.
Zauważ, że zarówno poziom dotkliwości 20 lub wyższy, jak i opcja WITH LOG
są niezbędne, aby działać w ten sposób.
To działa nawet z deklaracjami GO, np.
print 'hi'
go
raiserror('Oh no a fatal error', 20, -1) with log
go
print 'ho'
Da ci wyjście:
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.
Zauważ, że 'ho' nie jest drukowany.
Zastrzeżenia:
- to działa tylko wtedy, gdy jesteś zalogowany jako admin (rola' sysadmin'), a także pozostawia cię bez połączenia z bazą danych.
- jeśli nie jesteś zalogowany jako admin, wywołanie RAISEERROR() nie powiedzie się , a skrypt będzie kontynuował wykonywanie.
- podczas wywoływania z sqlcmd.exe, kod wyjścia 2745 zostanie zgłoszony.
Odniesienie: http://www.mydatabasesupport.com/forums/ms-sqlserver/174037-sql-server-2000-abort-whole-script.html#post761334
Noexec metoda
Inną metodą, która działa z poleceniami GO jest set noexec on
. Powoduje to pominięcie reszty skryptu. Nie przerywa połączenia, ale musisz ponownie wyłączyć noexec
, zanim jakiekolwiek polecenia zostaną wykonane.
Przykład:
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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-18 16:43:00
Wystarczy użyć RETURN (będzie działać zarówno wewnątrz, jak i na zewnątrz procedury składowanej).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-18 17:23:19
Jeśli możesz użyć trybu SQLCMD, to inkantacja
:on error exit
(łącznie z dwukropkiem) spowoduje, że RAISERROR faktycznie zatrzyma skrypt. Np.,
:on error exit
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SOMETABLE]') AND type in (N'U'))
RaisError ('This is not a Valid Instance Database', 15, 10)
GO
print 'Keep Working'
Wyświetli:
Msg 50000, Level 15, State 10, Line 3
This is not a Valid Instance Database
** An error was encountered during execution of batch. Exiting.
I Partia zatrzyma się. Jeśli tryb SQLCMD nie jest włączony, pojawi się błąd analizy dwukropka. Unfultuantely, to nie jest całkowicie kuloodporne, jak gdyby skrypt jest uruchamiany bez bycia w trybie SQLCMD, SQL Managment Studio breezes prawo przeszłości nawet parse błędy czasu! / Align = "left" / im z linii poleceń, to jest w porządku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-07 06:13:39
Nie użyłbym RAISERROR-SQL ma poleceń IF, które mogą być użyte do tego celu. Wykonaj walidację i wyszukiwanie oraz ustaw zmienne lokalne, a następnie użyj wartości zmiennych w instrukcjach IF, aby wstawianie było warunkowe.
Nie trzeba sprawdzać zmiennego wyniku każdego testu walidacyjnego. Zazwyczaj można to zrobić tylko z jedną zmienną flag, aby potwierdzić, że wszystkie warunki przeszły:
declare @valid bit
set @valid = 1
if -- Condition(s)
begin
print 'Condition(s) failed.'
set @valid = 0
end
-- Additional validation with similar structure
-- Final check that validation passed
if @valid = 1
begin
print 'Validation succeeded.'
-- Do work
end
Nawet jeśli Walidacja jest bardziej złożona, powinieneś potrzebować tylko kilku znaczników zmienne, które należy uwzględnić w końcowych kontrolach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-17 11:24:33
Możesz zawinąć instrukcję SQL w pętlę WHILE I użyć BREAK w razie potrzeby
WHILE 1 = 1
BEGIN
-- Do work here
-- If you need to stop execution then use a BREAK
BREAK; --Make sure to have this break at the end to prevent infinite loop
END
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-18 17:27:14
Rozszerzyłem rozwiązanie noexec on / off pomyślnie z transakcją, aby uruchomić skrypt w sposób wszystko lub nic.
set noexec off
begin transaction
go
<First batch, do something here>
go
if @@error != 0 set noexec on;
<Second batch, do something here>
go
if @@error != 0 set noexec on;
<... etc>
declare @finished bit;
set @finished = 1;
SET noexec off;
IF @finished = 1
BEGIN
PRINT 'Committing changes'
COMMIT TRANSACTION
END
ELSE
BEGIN
PRINT 'Errors occured. Rolling back changes'
ROLLBACK TRANSACTION
END
Najwyraźniej kompilator " rozumie "zmienną @ finished W IF, nawet jeśli wystąpił błąd i wykonanie zostało wyłączone. Wartość jest jednak ustawiona na 1 tylko wtedy, gdy wykonanie nie zostało wyłączone. Dlatego mogę odpowiednio zatwierdzić lub wycofać transakcję.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-25 12:27:31
W SQL 2012+ możesz użyć THROW.
THROW 51000, 'Stopping execution because validation failed.', 0;
PRINT 'Still Executing'; -- This doesn't execute with THROW
Z MSDN:
Podnosi wyjątek i przenosi wykonanie do bloku CATCH z konstrukcji try ... CATCH ... Jeśli konstrukcja try ... CATCH nie jest dostępna, sesja zostaje zakończona. Ustawia się numer linii i procedurę, w której podnoszony jest wyjątek. Stopień ciężkości jest ustawiony na 16.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-19 16:21:15
Czy to procedura składowana? Jeśli tak, myślę, że możesz po prostu zrobić Return, np. "Return NULL";
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-18 17:07:52
Dalsze udoskonalanie metody Sglasses, powyższe linie wymuszają użycie trybu SQLCMD, i albo treminuje scirpt, jeśli nie używa trybu sqlcmd lub używa :on error exit
, aby zakończyć przy jakimkolwiek błędzie
CONTEXT_INFO jest używany do śledzenia stanu.
SET CONTEXT_INFO 0x1 --Just to make sure everything's ok
GO
--treminate the script on any error. (Requires SQLCMD mode)
:on error exit
--If not in SQLCMD mode the above line will generate an error, so the next line won't hit
SET CONTEXT_INFO 0x2
GO
--make sure to use SQLCMD mode ( :on error needs that)
IF CONTEXT_INFO()<>0x2
BEGIN
SELECT CONTEXT_INFO()
SELECT 'This script must be run in SQLCMD mode! (To enable it go to (Management Studio) Query->SQLCMD mode)\nPlease abort the script!'
RAISERROR('This script must be run in SQLCMD mode! (To enable it go to (Management Studio) Query->SQLCMD mode)\nPlease abort the script!',16,1) WITH NOWAIT
WAITFOR DELAY '02:00'; --wait for the user to read the message, and terminate the script manually
END
GO
----------------------------------------------------------------------------------
----THE ACTUAL SCRIPT BEGINS HERE-------------
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-24 15:55:50
Proponuję zawinąć odpowiedni blok kodu w blok try catch. Następnie możesz użyć zdarzenia Raiserror o wadze 11, aby przebić się do bloku catch, jeśli chcesz. Jeśli chcesz tylko zwiększyć liczbę błędów, ale kontynuować wykonywanie w ramach bloku try, użyj niższej wagi.
Ma sens?
Cheers, John
[Edited to include BOL Reference]
Http://msdn.microsoft.com/en-us/library/ms175976(SQL. 90). aspx
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-19 12:29:49
Możesz użyć RAISERROR .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-18 17:05:27
Możesz zmienić przebieg wykonania używając GOTO poleceń:
IF @ValidationResult = 0
BEGIN
PRINT 'Validation fault.'
GOTO EndScript
END
/* our code */
EndScript:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-09 15:21:25
Żaden z nich nie działa z wyrażeniami "GO". W tym kodzie, niezależnie od tego, czy dotkliwość wynosi 10 czy 11, otrzymasz ostateczną instrukcję PRINT.
Skrypt Testowy:
-- =================================
PRINT 'Start Test 1 - RAISERROR'
IF 1 = 1 BEGIN
RAISERROR('Error 1, level 11', 11, 1)
RETURN
END
IF 1 = 1 BEGIN
RAISERROR('Error 2, level 11', 11, 1)
RETURN
END
GO
PRINT 'Test 1 - After GO'
GO
-- =================================
PRINT 'Start Test 2 - Try/Catch'
BEGIN TRY
SELECT (1 / 0) AS CauseError
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ErrorMessage
RAISERROR('Error in TRY, level 11', 11, 1)
RETURN
END CATCH
GO
PRINT 'Test 2 - After GO'
GO
Wyniki:
Start Test 1 - RAISERROR
Msg 50000, Level 11, State 1, Line 5
Error 1, level 11
Test 1 - After GO
Start Test 2 - Try/Catch
CauseError
-----------
ErrorMessage
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Divide by zero error encountered.
Msg 50000, Level 11, State 1, Line 10
Error in TRY, level 11
Test 2 - After GO
Jedynym sposobem, aby to zadziałało, jest napisanie skryptu bez GO
instrukcji. Czasami to proste. Czasami jest to dość trudne. (Użyj czegoś w rodzaju IF @error <> 0 BEGIN ...
.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-27 12:59:20
To było moje rozwiązanie:
...
BEGIN
raiserror('Invalid database', 15, 10)
rollback transaction
return
END
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-27 08:40:44
Możesz użyć polecenia GOTO. Spróbuj tego. To jest pełne wykorzystanie dla Ciebie.
WHILE(@N <= @Count)
BEGIN
GOTO FinalStateMent;
END
FinalStatement:
Select @CoumnName from TableName
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-07 06:58:18
Thx za odpowiedź!
raiserror()
działa dobrze, ale nie należy zapominać return
oświadczenie inaczej skrypt kontynuuje bez błędu! (hense raiserror nie jest "throwerror"; -)) i oczywiście robi rollback jeśli to konieczne!
raiserror()
miło jest powiedzieć osobie, która wykonuje scenariusz, że coś poszło nie tak.
Jeśli po prostu wykonujesz skrypt w Management Studio i chcesz zatrzymać wykonanie lub transakcję rollback (jeśli jest używana) przy pierwszym błędzie, najlepszym moim zdaniem sposobem jest użycie try catch block (SQL 2005). Działa to dobrze w Management studio, jeśli wykonujesz plik skryptu. Przechowywany proc również może z niego korzystać.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-05 07:34:31
Używam RETURN
tutaj cały czas, działa w skrypcie lub Stored Procedure
Upewnij się, że ROLLBACK
transakcja, jeśli jesteś w jednym, w przeciwnym razie RETURN
natychmiast spowoduje otwarcie niezakontraktowanej transakcji
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-28 19:02:36