Korzystam z narzędzia sqlcmd z pliku wsadowego i zastanawiałem się, jak sprawić, by zwrócił błąd ERRORLEVEL inny niż 0, gdy coś pójdzie nie tak z kopią zapasową.
Korzystam z narzędzia sqlcmd z pliku wsadowego i zastanawiałem się, jak sprawić, by zwrócił błąd ERRORLEVEL inny niż 0, gdy coś pójdzie nie tak z kopią zapasową.
Odpowiedzi:
Powinieneś użyć opcji -b w sqlcmd.
-b Określa, że sqlcmd kończy działanie i zwraca wartość DOS ERRORLEVEL, gdy wystąpi błąd. Wartość zwracana do zmiennej DOS ERRORLEVEL wynosi 1, gdy komunikat o błędzie programu SQL Server ma poziom ważności większy niż 10; w przeciwnym razie zwracana jest wartość 0
Ze strony narzędzia MSDN SQLCMD pod adresem : http://msdn.microsoft.com/en-us/library/ms162773.aspx
Jeśli RAISERROR zostanie użyty w skrypcie sqlcmd, a stan 127 zostanie podniesiony, sqlcmd zakończy pracę i zwróci identyfikator komunikatu z powrotem do klienta. Na przykład:
RAISERROR (50001, 10, 127)
Możesz więc zawinąć BACKUP DATABASE...
polecenie w TRY...CATCH
blok i wywołać odpowiedni komunikat o błędzie, który sqlcmd
następnie powróci do pliku wsadowego.
Na przykład rozważ następujący errorleveltest.sql
plik:
:ON ERROR EXIT
BEGIN TRY
/* creates error 3147 Backup and restore operations
are not allowed on database tempdb */
BACKUP DATABASE tempdb;
END TRY
BEGIN CATCH
DECLARE @msg NVARCHAR(255);
SET @msg = 'An error occurred: ' + ERROR_MESSAGE();
RAISERROR (50002, 10, 127);
END CATCH
I następujący plik .bat: (pierwszy wiersz jest zawijany dla czytelności, ale musi znajdować się w jednym wierszu).
@echo off
"C:\Program Files\Microsoft SQL Server\110\Tools\Binn\sqlcmd" -S "someinstance" -E
-i .\errorleveltest.sql
ECHO Errorlevel: %ERRORLEVEL%
Zwraca to następujące polecenie z wiersza polecenia cmd.exe:
Msg 18054, Level 16, State 1, Server CP708-D377\MV, Line 9
Error 50002, severity 10, state 127 was raised, but no message with that error number
was found in sys.messages. If error is larger than 50000, make sure the user-defined
message is added using sp_addmessage.
Errorlevel: 1
Jak widać, zwracany jest ERRORLEVEL 1 zamiast normalnej wartości 0. Nie mogę uzyskać ERRORLEVEL odzwierciedlającej faktyczny numer błędu, w tym przypadku 50002; być może jest jakiś problem w moim kodzie, a może jest jakiś problem z moim środowiskiem.
ERRORLEVEL
nie należy oczekiwać, że będą miały tę samą wartość, co numer błędu zgłoszony z SQL Server. ErrorNumber jest wartością specyficzną dla SQL Server, która wskazuje, dlaczego (tj. SQL Server) została zakończona. Z drugiej strony ERRORLEVEL
jest wartością specyficzną dla SQLCMD, która wskazuje, dlaczego (tj. SQLCMD) została zakończona.