2011-02-09 56 views
1

在下面的脚本中,当出现sql错误时,%errorlevel%为0 - 这是为什么?奇怪的dos批处理脚本报告%errorlevel%

IF %RELEASE% GTR 2 (
    (
    echo WHENEVER SQLERROR EXIT FAILURE 
    echo @release.sql 
    echo exit 
    ) | sqlplus x/[email protected] 
    echo error: %errorlevel% 
    if %errorlevel% gtr 0 goto dberror 
) 

如果我删除if块(下面),那么%errorlevel%是非零!为什么if语句会影响错误级别?

(
    echo WHENEVER SQLERROR EXIT FAILURE 
    echo @release.sql 
    echo exit 
    ) | sqlplus x/[email protected] 
    echo error: %errorlevel% 
    if %errorlevel% gtr 0 goto dberror 

更新:相信这是我为错误检测的方式。我认为不是:

if %errorlevel% gtr 0 goto dberror 

..应该使用:

if errorlevel 1 goto dberror 

有用的链接here

+0

是的。 `如果errorlevel 1`实际上意味着`如果错误级别是1或更大`。 Errorlevel不是和环境变量。它表示最后执行的进程的退出代码,并且具有它自己的小句法。 :D – GolezTrol 2011-02-09 17:27:42

+0

@GolezTrol:它有自己的检查语法,但也是一个环境变量,可以像任何其他变量一样使用:回显,检查值,作为参数传递... – 2011-02-10 12:55:43

回答

4

叹息。这一切都与可怕的DOS解析,以及cmd用其值取代%errorlevel%的点。当您用( ... ),cmd包含命令时,首先会读入这些命令,就好像它们全都写在一行上一样,扩展变量。因此,在您的第一个代码块中,当块被解析时,%errorlevel%被替换为其值。这就好像你写道:

IF 3 GTR 2 (
    (
    echo WHENEVER SQLERROR EXIT FAILURE 
    echo @release.sql 
    echo exit 
    ) | sqlplus x/[email protected] 
    echo error: 0 
    if 0 gtr 0 goto dberror 
) 

(假设$RELEASE是3)。您的if errorlevel修复工作的原因是cmd在该重新配方上不会执行任何(太)早期可变扩展。您可以使用call来避免这个问题:

IF %RELEASE% GTR 2 (
    (
    echo WHENEVER SQLERROR EXIT FAILURE 
    echo @release.sql 
    echo exit 
    ) | sqlplus x/[email protected] 
    call echo error: %%errorlevel%% 
    call if %%errorlevel%% gtr 0 goto dberror 
) 

(我认为这是再清楚不过startlocal ENABLEDELAYEDEXPANSION!errorlevel! -YMMV当然)。