如何通过 SQLCMD 从 SQL 代码 运行 有条件地退出 .BAT 文件

How to conditionally exit .BAT file from SQL code run through SQLCMD

我有一个 .bat(Windows 命令)文件,其中包含对 SQLCMD 和其他命令的调用。 (当然 SQLCMD 正在将我的 T-SQL 代码发送到 SQL 服务器。)我想检测 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% 不是正常的环境变量。 return 是当前 ERRORLEVEL 的动态伪变量。如果您使用 set ERRORLEVEL=0 显式定义一个真正的环境变量,那么动态性质就会被破坏,并且 %ERRORLEVEL% 将永远 return 您的用户定义环境变量的值,直到您取消定义您的用户值。您应该 never 为 ERRORLEVEL、RANDOM、CD、TIME、DATE 等定义您自己的值

如果你想清除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。 (见

@dbenson 的回答解决了.bat 文件的问题。但是 .sql 文件也有问题,其症状是尽管有错误,最后一行仍然执行。这是一个完整的解决方案。也就是说,这两个文件可以正常工作。

代码正在检查的 "error" 是存在名为 'master' 的数据库。如果将 'master' 替换为不是数据库名称的内容,它会正常运行。

example.bat </p> <pre><code>REM Replace the server name with any SQL Server server to which you REM have at least read access. The contents of the server don't matter. sqlcmd -b -S dbread.vistaprint.net -E -i example.sql if %errorlevel% neq 0 exit /b %errorlevel% echo 'In the .bat file, we got past the error check, so run was successful.'

example.sql </p> <pre><code>if exists (select * from master.sys.databases where name = 'master') begin RAISERROR ('Found an error condition', 18, 10) return end print 'In the SQL file, we got past the error check, so run was successful.'