如何通过 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.'
我有一个 .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.'