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

2024-03-18

我有一个 .bat(Windows 命令)文件,其中包含 SQLCMD 和其他命令的调用。 (当然,SQLCMD 正在将我的 T-SQL 代码发送到 SQL Server。)我想检测 SQL 代码中的某些条件,并有条件地退出整个批处理文件。我尝试过 RAISERROR、THROW 和故意除以 0 的各种组合(我并不自豪)以及 SQLCMD 上的各种命令行开关以及 .bat 文件中错误级别的处理。

我尝试了答案5789568 https://stackoverflow.com/questions/5789568/sqlcmd-utility-from-bat-file-how-to-return-errorlevel-in-case-of-syntax-error但无法让它在我的情况下工作。以下两个文件显示了一次失败的尝试。如果有超过 3 个表,它会尝试中止。但它不会中止 bat 文件,正如您在最终命令 (echo) 执行时所看到的那样。它甚至不会中止 SQLCMD 的运行,正如您在它告诉您有多少个表时所看到的那样。

示例.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

示例.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%不是一个正常的环境变量。它是一个动态伪变量,返回当前的错误级别。如果您使用显式定义一个真实的环境变量set ERRORLEVEL=0,那么动态性质就被破坏了,并且%ERRORLEVEL%将永远返回用户定义的环境变量的值,直到您取消定义用户值。你应该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 即可。(See 哪些 cmd.exe 内部命令在成功后将 ERRORLEVEL 清除为 0? https://stackoverflow.com/q/34968009/1012053)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐