2016-12-28 1 views
0

Я пытаюсь сделать выбор в DB постгерра через командный файл. В базе данных postgres DB имеется интерфейс командной строки (psql), где вы можете использовать команды DB, которые здесь выполняются для цикла. Посмотрите, как pg_cmd складывается вместе. Выбранный pd_SelCmd отображается на pg_SelCall. В операторе for выполняется команда, но поскольку выбор содержит круглые скобки, они вызывают интерпретацию пропусков и ошибку: «FROM» не может обрабатываться синтаксически в этот момент.Как сделать postgres Выберите оператор, который содержит круглые скобки в пакете?

Как круглые скобки могут быть экранированы, чтобы заставить запрос работать?

Ожидаемый ответ из БД выглядит следующим образом:

  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.842НО, так как есть четвертая строка в файле , следующая строка также будет обработана, и 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, чтобы быть на стороне сохранения. Я удалил ненужные скобки и добавил строку для замены ')' by '^)', и теперь это работает. Большое спасибо за вашу помощь. –

+0

Поскольку этот небольшой пример содержит несколько сложных операций, я добавил несколько комментариев и улучшил обработку ошибок. Для подобных выборок его можно легко отрегулировать. –