当 .sql 脚本失败时,如何使 sqlcmd 返回 0 以外的 ERRORLEVEL?

lee*_*d00 45 sql-server sql-server-2008-r2 sqlcmd

我正在从一个批处理文件运行 sqlcmd,我想知道如何让它在备份出现问题时返回 0 以外的 ERRORLEVEL。

Ola*_*ren 63

您应该在 sqlcmd 中使用选项 -b。

-b 指定 sqlcmd 在发生错误时退出并返回 DOS ERRORLEVEL 值。当 SQL Server 错误消息的严重性级别大于 10 时,返回给 DOS ERRORLEVEL 变量的值为 1;否则返回值为 0

http://msdn.microsoft.com/en-us/library/ms162773.aspx


Han*_*non 11

从 MSDN SQLCMD 实用程序页面:http : //msdn.microsoft.com/en-us/library/ms162773.aspx

如果在 sqlcmd 脚本中使用了 RAISERROR 并引发了 127 状态,则 sqlcmd 将退出并将消息 ID 返回给客户端。例如:

RAISERROR(50001, 10, 127)

因此,您可以将BACKUP DATABASE...命令包装在一个TRY...CATCH块中并引发适当的错误消息,sqlcmd然后返回到您的批处理文件。

例如,考虑以下errorleveltest.sql文件:

: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
Run Code Online (Sandbox Code Playgroud)

以及以下 .bat 文件:(为了可读性,第一行被换行,但需要在一行上。)

@echo off
"C:\Program Files\Microsoft SQL Server\110\Tools\Binn\sqlcmd" -S "someinstance" -E 
    -i .\errorleveltest.sql
ECHO Errorlevel: %ERRORLEVEL%
Run Code Online (Sandbox Code Playgroud)

这将从我的 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
Run Code Online (Sandbox Code Playgroud)

如您所见,返回 ERRORLEVEL 1 而不是正常的返回值 0。我无法获得 ERRORLEVEL 以反映实际错误编号,在本例中为 50002;也许我的代码有问题,或者我的环境有问题。

  • 关于最后一段的仅供参考:不应期望 `ERRORLEVEL` 与 SQL Server 报告的错误号具有相同的值。ErrorNumber 是特定于 SQL Server 的值,用于指示它(即 SQL Server)终止的原因。另一方面,`ERRORLEVEL` 是一个特定于SQLCMD 的值,用于指示它(即SQLCMD)终止的原因。 (7认同)
  • 我发现这仅在您提供数值作为 RAISERROR 的第一个参数时才有效。例如:这会返回 %errorlevel% = 1: RAISERROR(50002, 10,127) 但是这会返回 %errorlevel% = 0: RAISERROR('myErrMsg.', 10,127) (2认同)