当.sql脚本失败时,如何使sqlcmd返回非0的错误级别?


38

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


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

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

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

Answers:



9

从以下位置的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文件:

: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

以及以下.bat文件:(第一行是为了便于阅读而包装的,但必须在一行上。)

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

这将从我的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

如您所见,返回了ERRORLEVEL 1而不是正常的返回值0。也许我的代码有问题,或者我的环境有问题。


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

5
仅供参考,关于最后一段:ERRORLEVEL不应与SQL Server报告的错误号相同。ErrorNumber是特定于SQL Server的值,以指示其终止原因(即SQL Server)。另一方面,ERRORLEVEL是SQLCMD特定的值,以指示其终止的原因(即SQLCMD)。
所罗门·鲁兹基
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.