【问题标题】:PSQL Error Level in Batch For Loop批处理 For 循环中的 PSQL 错误级别
【发布时间】:2015-06-10 21:15:09
【问题描述】:

我正在尝试从批处理文件中运行 postgres 查询。但是,到目前为止,我一直无法检测到命令何时失败。以下是我迄今为止尝试过的:

@FOR /F %%A IN ('PSQL -U userName -d dbName -t -c "SELECT * FROM nonExistantTable" 2^>^&1') DO @(
    ECHO !ERRORLEVEL!
)

我也尝试了以下方法:

1) 在sql命令前添加“CALL”(CALL PSQL -U ...)
2)在sql命令中添加“-v ON_ERROR_STOP=1”,无论有无“CALL”命令(PSQL -U ... -v ON_ERROR_STOP=1

但是,ERRORLEVEL 的值始终为零。有谁知道如何使用批处理检测对 PSQL 的调用中的错误?具体来说,我得到的错误是该表不存在。谢谢。

【问题讨论】:

    标签: batch-file for-loop postgresql-9.3 psql


    【解决方案1】:

    for /f 在单独的cmd 实例中执行命令,并且此实例中的errorlevel 不会导出到do 子句中的代码。

    纯批处理的更好方法是:

    • 将程序的输出发送到临时文件
    • 检查错误级别
    • 如果没有错误处理文件输出
    • 无论如何删除最后的临时文件

    类似

    set "tempFile=%temp%\%~n0.%random%%random%%random%.tmp"
    > "%tempFile%" 2>&1 (
        PSQL -U userName -d dbName -t -c "SELECT * FROM nonExistantTable"
    )
    if not errorlevel 1 (
        for /f "usebackq delims=" %%g in ("%tempFile%") do (
            echo %%g
        )
    ) else (
        echo ERRORLEVEL: %errorlevel%
    )
    del /q "%tempFile%"
    

    【讨论】:

      【解决方案2】:

      @MCND 的回答可以概括为:

      1) 正常运行命令,将stdout重定向到临时文件
      2)根据ERRORLEVEL

      处理文件内容

      基于这个答案,我想出了一个解决方案,可以用更少的代码满足我的特殊需求。我的情况有点特殊,因为 PSQL 命令执行以下操作之一:

      1) 将结果写入标准输出,并返回零
      2) 向 stderr 写入错误,并返回非零值

      在情况 #1 中,我希望我的批处理文件打印结果并返回 0。在情况 #2 中,我想执行一些自定义逻辑,打印错误并返回非零值。对于这种逻辑,我发现以下方法效果更好:

      :: Get a temporary file name
      @SETLOCAL
      @SET TEMP_OUT="%TEMP%\myScriptError.log"
      
      :: Create the command that will be executed
      @SET DB_SELECT=SELECT * FROM nonExistantTable
      @SET DB_COMMAND=PSQL -U userName -d dbName -t -c "%DB_SELECT%"
      
      :: Run the command
      @FOR /F %%A IN ('%DB_COMMAND% 2^>%TEMP_OUT%') DO @(
          REM This code only runs if there are no errors
          SET EXIT_CODE=0
          GOTO :CLEANUP
      )
      
      :: Uh-oh, there was an error.  Print it to stderr, and set the exit code.
      @MORE %TEMP_OUT% 1>&2
      @SET EXIT_CODE=1
      ...
      
      :: Clean up the temp file and return the result
      :CLEANUP
      @DEL /F /Q %TEMP_OUT%
      @ENDLOCAL & EXIT /B %EXIT_CODE%
      

      【讨论】:

      • 我包含这个答案是为了充分说明我如何在我的特定案例中解决这个问题,以防将来对某人有所帮助。但是,@MCND 完全回答了这个问题,这就是我将其标记为这样的原因。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      相关资源
      最近更新 更多