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...CATCHbloco e gerar a mensagem de erro apropriada, que sqlcmdretornaria ao seu arquivo em lotes.
Por exemplo, considere o seguinte errorleveltest.sqlarquivo:
: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.
ERRORLEVELnã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.