我有一个.bat(Windows命令)文件,其中包含SQLCMD和其他命令的调用。 (当然,SQLCMD会将T-SQL代码发送到SQL Server。)我想检测SQL代码中的某些条件,并有条件地退出整个批处理文件。我尝试了RAISERROR,THROW和故意除以0(我不感到骄傲)的各种组合,以及SQLCMD上的各种命令行开关以及.bat文件中错误级别的处理。
我尝试了5789568的答案,但无法解决我的问题。这是两个文件,显示了一次失败的尝试。如果有3个以上的表,它将尝试中止。但是,它不会终止bat文件,正如您所看到的,当执行最后一条命令(echo)时。它甚至不会中止SQLCMD的运行,正如您所看到的,它告诉您有多少张表。
example.bat
set ERRORLEVEL=0
sqlcmd -b -S dbread.vistaprint.net -E -d columbus -e -i example.sql
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
echo we got to the end of the BAT file
example.sql
SET XACT_ABORT ON
if ((SELECT COUNT(*) FROM sys.tables) > 3)
begin
RAISERROR ('There are more than 3 tables. We will try to stop', 18, -1)
end
SELECT COUNT(*) FROM sys.tables
最佳答案
%ERRORLEVEL%
不是正常的环境变量。它是一个动态伪变量,返回当前的ERRORLEVEL。如果您使用set ERRORLEVEL=0
显式定义了一个真实的环境变量,那么动态性质将被破坏,并且%ERRORLEVEL%
将永远返回用户定义的环境变量的值,直到您取消定义用户值为止。您应该永远不要定义自己的错误级别,随机,CD,时间,日期等值。
如果要清除ERRORLEVEL,则必须执行将值设置为0的命令。我喜欢使用(call )
。
假设您的代码没有其他问题,应使用以下方法解决:
(call )
sqlcmd -b -S dbread.vistaprint.net -E -d columbus -e -i example.sql
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
echo we got to the end of the BAT file
sqlcmd
是一个外部命令(exe程序),因此它始终设置为ERRORLEVEL。因此,您不必清除ERRORLEVEL,并且可以删除(call )
。您实际上只需要担心在运行内部命令(在成功时未将ERRORLEVEL设置为0)之前清除ERRORLEVEL即可。 (请参阅Which cmd.exe internal commands clear the ERRORLEVEL to 0 upon success?)关于tsql - 如何有条件地从通过SQLCMD运行的SQL代码中退出.BAT文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41246554/