Estoy ejecutando sqlcmd desde un archivo por lotes y me preguntaba cómo hacer que devuelva un ERRORLEVEL que no sea 0 cuando algo sale mal con la copia de seguridad.
Estoy ejecutando sqlcmd desde un archivo por lotes y me preguntaba cómo hacer que devuelva un ERRORLEVEL que no sea 0 cuando algo sale mal con la copia de seguridad.
Respuestas:
Debe usar la opción -b en sqlcmd.
-b Especifica que sqlcmd sale y devuelve un valor de ERRORLEVEL de DOS cuando se produce un error. El valor que se devuelve a la variable ERRORLEVEL de DOS es 1 cuando el mensaje de error de SQL Server tiene un nivel de gravedad mayor que 10; de lo contrario, el valor devuelto es 0
Desde la página de MSDN SQLCMD Utility en: http://msdn.microsoft.com/en-us/library/ms162773.aspx
Si se utiliza RAISERROR dentro de un script sqlcmd y se genera un estado de 127, sqlcmd se cerrará y devolverá la ID del mensaje al cliente. Por ejemplo:
RAISERROR (50001, 10, 127)
Entonces, podría envolver el BACKUP DATABASE...
comando en un TRY...CATCH
bloque y generar el mensaje de error apropiado, que sqlcmd
luego volvería a su archivo por lotes.
Por ejemplo, considere el siguiente errorleveltest.sql
archivo:
: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
Y el siguiente archivo .bat: (la primera línea está ajustada para facilitar la lectura, pero debe estar en una sola línea).
@echo off
"C:\Program Files\Microsoft SQL Server\110\Tools\Binn\sqlcmd" -S "someinstance" -E
-i .\errorleveltest.sql
ECHO Errorlevel: %ERRORLEVEL%
Esto devuelve lo siguiente desde mi indicador 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 puede ver, ERRORLEVEL 1 se devuelve en lugar del valor de retorno normal de 0. No puedo hacer que ERRORLEVEL refleje el número de error real, en este caso 50002; quizás haya un problema en mi código, o quizás haya algún problema con mi entorno.
ERRORLEVEL
no se debe esperar que sea el mismo valor que el Número de error informado desde SQL Server. ErrorNumber es un valor específico de SQL Server para indicar por qué terminó (es decir, SQL Server). Por otro lado, ERRORLEVEL
es un valor específico de SQLCMD para indicar por qué terminó (es decir, SQLCMD).