Estou executando o sqlcmd a partir de um arquivo em lotes e queria saber como fazê-lo retornar um ERRORLEVEL diferente de 0 quando algo der errado com o backup.
Estou executando o sqlcmd a partir de um arquivo em lotes e queria saber como fazê-lo retornar um ERRORLEVEL diferente de 0 quando algo der errado com o backup.
Respostas:
Você deve usar a opção -b no sqlcmd.
-b Especifica que o sqlcmd sai e retorna um valor DOS ERRORLEVEL quando ocorre um erro. O valor retornado para a variável DOS ERRORLEVEL é 1 quando a mensagem de erro do SQL Server tem um nível de gravidade maior que 10; caso contrário, o valor retornado é 0
Na página Utilitário MSDN SQLCMD em: http://msdn.microsoft.com/en-us/library/ms162773.aspx
Se RAISERROR for usado em um script sqlcmd e um estado 127 for aumentado, o sqlcmd será encerrado e retornará o ID da mensagem ao cliente. Por exemplo:
RAISERROR (50001, 10, 127)
Portanto, você pode agrupar o BACKUP DATABASE...
comando em um TRY...CATCH
bloco e gerar a mensagem de erro apropriada, que sqlcmd
retornaria ao seu arquivo em lotes.
Por exemplo, considere o seguinte errorleveltest.sql
arquivo:
: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
E o seguinte arquivo .bat: (a primeira linha está ajustada para facilitar a leitura, mas precisa estar em uma única linha.)
@echo off
"C:\Program Files\Microsoft SQL Server\110\Tools\Binn\sqlcmd" -S "someinstance" -E
-i .\errorleveltest.sql
ECHO Errorlevel: %ERRORLEVEL%
Isso retorna o seguinte do meu prompt do 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
Como você pode ver, ERRORLEVEL 1 é retornado em vez do valor normal de retorno 0. Não consigo fazer com que ERRORLEVEL reflita o número de erro real, neste caso 50002; talvez haja um problema no meu código ou talvez haja algum problema no meu ambiente.
ERRORLEVEL
não se deve esperar o mesmo valor que o número do erro relatado no SQL Server. O ErrorNumber é um valor específico do SQL Server para indicar por que ele (ou seja, SQL Server) foi encerrado. Por outro lado, ERRORLEVEL
é um valor específico do SQLCMD para indicar por que ele (ou seja, SQLCMD) terminou.