2016-12-28 77 views
0

我试图通过批处理文件做一个选择到一个Postgres数据库。 Postgres的DB提供,你可以管在DB命令出我们的循环中完成一个命令行界面(PSQL)。看看pg_cmd是如何固定在一起的。 select pd_SelCmd被回显到pg_SelCall。 在for语句执行的命令,但由于选择包含圆括号,它们造成小姐解释和错误: “FROM”语法不能在这一点上进行处理。如何在批处理中包含圆括号的postgres Select语句?

圆括号怎么能种逃到获得请求的工作?

从DB预期的反应是这样的:

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

到目前为止所使用的批次是这样

setlocal enabledelayedexpansion 
Set "PgRootPath=C:\Program Files\PostgreSql\9.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 

回答

0

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

首先,标签不允许在代码块(括号中的系列声明)和::是一个破碎的标签。在代码块中,应使用rem进行说明。

接着,更换您'!pg_cmd!for环与type q41353737.txt(其中q41353737.txt是含有从您发布的命令输出所期望的数据的文件)然后dataval设为09:40:09.842BUT由于在文件中的第四行,下一行也将被处理并且dataval将被设置为Line)

为了克服这一点,你可以简单地将其更改为

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:)=^)!" 

应适当前缀的所有)在命令withh必要的插入符。

我怀疑你也有与其他问题的字符的麻烦,从而应用到|类似的过程将可能是必需的,即。

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

这是我不得不离开它,因为我没有正确地执行命令本身的方式。

+0

我已经更新了代码。 双冒号问题的更多细节可以在这里http://www.robvanderwoude.com/comments.php红色。 尽管我在将来的所有Windows版本> = 7中都没有发现它存在问题,但我将使用REM进行保存。 我已经删除了一些不必要的括号,并添加了用'^)'代替')'的行,现在它可以工作。 非常感谢您的帮助。 –

+0

由于这个小例子包含几个复杂的操作,我添加了一些注释并改进了错误处理。对于类似的选择,它可以很容易地调整。 –