Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql 如何通过SQLCMD有条件地从SQL代码中退出.BAT文件_Tsql_Batch File_Cmd_Error Handling_Sqlcmd - Fatal编程技术网

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

Tsql 如何通过SQLCMD有条件地从SQL代码中退出.BAT文件,tsql,batch-file,cmd,error-handling,sqlcmd,Tsql,Batch File,Cmd,Error Handling,Sqlcmd,我有一个.bat(Windows命令)文件,其中包括对SQLCMD和其他命令的调用。(当然SQLCMD正在将我的T-SQL代码发送到SQL Server。)我想检测SQL代码中的某些条件,并有条件地退出整个批处理文件。我尝试了RAISERROR、THROW和故意除以0(我并不自豪)的各种组合,以及SQLCMD上的各种命令行开关和.bat文件中errorlevel的处理 我试过这个问题的答案,但在我的情况下却没能奏效。这里有两个文件显示了一次失败的尝试。如果有3个以上的表,它将尝试中止。但它不会中

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

我试过这个问题的答案,但在我的情况下却没能奏效。这里有两个文件显示了一次失败的尝试。如果有3个以上的表,它将尝试中止。但它不会中止bat文件,正如您在执行最终命令(echo)时所看到的那样。它甚至不会中止SQLCMD的运行,当它告诉您有多少个表时,您可以看到这一点

例如:蝙蝠 example.sql
%ERRORLEVEL%
不是正常的环境变量。它是一个动态伪变量,返回当前ERRORLEVEL。如果使用
set ERRORLEVEL=0
显式定义了一个真实的环境变量,那么动态特性将被破坏,
%ERRORLEVEL%
将永远返回用户定义的环境变量的值,直到取消定义用户值为止。您应该永远不要定义自己的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,并且可以删除
(调用)
。您只需在运行内部命令之前清除ERRORLEVEL,这些命令在成功后不会将ERRORLEVEL设置为0。(请参阅)

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

代码检查的“错误”是存在名为“master”的数据库。如果将“master”替换为非数据库名称的内容,则它将正常运行

示例.bat

示例.sql


代码基本正常。您正在讲述如何隐藏进程输出。如果要删除命令输出,请将其重定向到
NUL
。因此
sqlcmd-b-sbla.bla.net-E-d my_db-E-i example.sql
将是
sqlcmd-b-sbla.bla.net-E-d my_db-E-i example.sql>NUL
。命令输出被发送到黑洞,但是
ERRORLEVEL
仍然可以访问。或者只删除错误输出,将>NUL更改为2>NUL@elzooilogico-不,这与老年退休金计划问题无关。
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
(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
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.'
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.'