我正在从批处理文件运行sqlcmd,我想知道当备份出问题时如何使其返回0以外的错误级别。

评论

您是否考虑过使用比批处理文件更强大的功能(尤其是在错误处理方面)?

哦,您是说像Powershell吗?我们只是针对公司使用的产品使用公司推荐的方法。麻烦的是,推荐方法假设您正在备份一个数据库;但我克服了这个障碍。因此,如果备份不起作用,有没有办法让它仅仅抛出错误代码?

不管是什么价值,在我目前的工作中,我们使用Ola Hallengren的备份存储过程(周围有一些内部包装存储过程)在数百个服务器上备份数千个数据库,而我们没有遇到任何问题。 br />

#1 楼

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

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

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

#2 楼

从以下位置的MSDN SQLCMD实用工具页面:http://msdn.microsoft.com/zh-cn/library/ms162773.aspx

如果在sqlcmd脚本中使用RAISERROR且状态为127 ,sqlcmd将退出,并将消息ID返回给客户端。例如:
RAISERROR(50001,10,127)

所以您可以将BACKUP DATABASE...命令包装在TRY...CATCH块中并引发相应的错误消息,然后sqlcmd将返回到批处理文件..例如,考虑以下errorleveltest.sql文件: br />
: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

这从我的cmd.exe提示符返回以下内容:
@echo off
"C:\Program Files\Microsoft SQL Server0\Tools\Binn\sqlcmd" -S "someinstance" -E 
    -i .\errorleveltest.sql
ECHO Errorlevel: %ERRORLEVEL%

如您所见,ERRORLEVEL 1返回,而不是正常的返回值0。获取ERRORLEVEL以反映实际的错误号,在这种情况下为50002;也许我的代码有问题,或者我的环境有问题。

评论


我发现只有在提供数字值作为RAISERROR的第一个参数时,此方法才有效。例如:这将返回%errorlevel%= 1:RAISERROR(50002,10,127)但这将返回%errorlevel%= 0:RAISERROR('myErrMsg。',10,127)

–user73342
15年8月21日在20:43

仅供参考,关于最后一段:ERRORLEVEL不应与SQL Server报告的错误号相同。 ErrorNumber是特定于SQL Server的值,以指示其终止原因(即SQL Server)。另一方面,ERRORLEVEL是特定于SQLCMD的值,以指示其终止原因(即SQLCMD)。

–所罗门·鲁兹基
2015年12月4日19:00

@SolonmonRutzky好点。我今天早上提交了一份用于改进sqlcmd实用程序最佳实践部分的PR,并在此处合并了您的注释(进行了一些编辑,以使措词与页面的其他部分一致,例如“ DOS ERRORLEVEL”而非“ ERRORLEVEL”)。 github.com/MicrosoftDocs/sql-docs/pull/5858

– John Zabroski
1月1日下午17:43