2011-02-09 43 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當然)。