如何批量执行包含圆括号的postgres Select语句?

How to do a postgres Select statement which contains round brackets in a batch?

我正在尝试通过批处理文件对 postgres 数据库执行 select。 postgres 数据库提供了一个命令行界面 (psql),您可以在其中输入数据库命令,这些命令在这里是在 for 循环中完成的。看看 pg_cmd 是如何拼接在一起的。 select pd_SelCmd 回显到 pg_SelCall。 在 for 语句中执行命令,但由于 select 包含圆括号,它们会导致错误解释和错误: "FROM"此时无法进行句法处理。

如何转义圆括号以使请求正常工作?

DB 的预期响应如下所示:

          max
-------------------------
2016-12-29 09:40:09.842
(1 Line)

目前使用的批次是这个

setlocal enabledelayedexpansion
Set "PgRootPath=C:\Program Files\PostgreSql.5.5-1\bin"
Call :GetDoneTime 56665454 DONE_TIME
echo = DONE_TIME=!DONE_TIME!
Goto :EOF

:GetDoneTime
set "ERRORLEVEL="
set "MC_UID=%~1"
set "ReturnDoneTimeValueRef=%~2"
set "DataVal=NULL"
set "PGPASSWORD=frontenduser"
set "PGCLIENTENCODING=utf-8"

set pd_SelCmd=SELECT max(t.endDate) FROM Ticket t JOIN Device d on t.device_id = d.id WHERE t.state in ('APPROVED','IN_PROGRESS', 'IN_ACTIVITY') AND d.uid='!MC_UID!';
set pg_SelCall="!PgRootPath!\psql" -U frontenduser -h localhost -d ppsdb
REM if call to psql produces an fatal error, the error number will be passed to for loop on third parameter in third line
set pg_cmd="echo !pd_SelCmd! | !pg_SelCall! || echo/ & echo/ & call echo NULL NULL %%^^^errorlevel%%"
set "pg_cmd=!pg_cmd:)=^)!"

REM Execute PG command. Resulting DataValue obtained from third row
REM Check for errors of call
for /f "skip=2 tokens=1,2,3" %%i in ('!pg_cmd!') do (       
    REM Get value in first and second parameter from split - which is from third row
    set "DataVal=%%i %%j"
    REM If error happend, report it. Error code is obtained in 3rd parameter.
    if "!DataVal!"=="NULL NULL" (
        echo ## Postgres DB operation failed with ERROR: %%~k
        set "DataVal=NULL"
    ) else (
        REM Check if result is not valid
        if "!DataVal:~0,1!"=="(" set "DataVal=NULL"
    )
    goto GotDoneTime
)
:GotDoneTime
    if not '!ReturnDoneTimeValueRef!'=='' set "!ReturnDoneTimeValueRef!=!DataVal!"
    if "!DataVal!"=="NULL" exit /b 1
    exit /b 0

这里只是一些错误。不幸的是,我不知道 postgresql,也没有必要的数据库,所以我无法测试它,但是这里是...

首先,代码块(带括号的语句系列)中不允许使用标签,:: 是损坏的标签。在一个代码块中,应使用rem进行注释。

接下来,将 for 循环中的 '!pg_cmd! 替换为 type q41353737.txt(其中 q41353737.txt 是包含您发布的命令的预期数据输出的文件)然后dataval 设置为 09:40:09.842 BUT 由于文件中有第四行,下一行也将被处理并设置 datavalLine).

要解决这个问题,您只需将其更改为

   rem If error happened, report it. Error code is obtained in 3rd parameter.
   if not '%%~k'=='' echo ## Postgres DB operation failed with ERROR: %%~k
   rem If operation succeeded, get value in second parameter from split - which is from second data column
   if '%%~k'=='' SET DataVal=%%~j
goto done
)
:done

因此只处理第三行,然后 for 循环被毫不客气地终止。

下一个问题是您投诉的问题。 ) 正在终止 for ... (,因此您需要告诉 cmd 那个特定的 ) 要执行的命令的一部分 , 不是 for, 所以你需要用插入符号转义它 (( 变成 ^))

最简单的方法大概就是在for之前加一行

set "pg_cmd=!pg_cmd:)=^)!"

应该在命令中适当地为所有 ) 添加必要的插入符号前缀。

我怀疑您还会遇到其他问题字符的问题,因此可能需要对 | 应用类似的过程,即

set "pg_cmd=!pg_cmd:|=^|!"

这是我必须离开的地方,因为我无法正确执行命令本身。