2013-09-10 4 views
19

Возможно ли использовать переменную среды Linux в файле .sql? Я использую запрос copy/select для записи в выходной файл, и я хотел бы поместить этот каталог в переменную. Поэтому я хочу сделать что-то вроде:Использование переменной среды в сценарии PSQL

COPY (SELECT * FROM a) 
TO $outputdir/a.csv 

Outputdir будет установлен в моей среде. Это возможно?

+0

_NB: _ Как и в случае замены переменной, она не будет работать так, как ожидалось, потому что COPY ... TO ожидает, что путь к выходному файлу будет одинарным. См. Здесь: http://www.postgresql.org/docs/9.2/static/sql-copy.html – benjwadams

ответ

24

Вы можете сохранить результат команды оболочки внутри psql переменной, как это:

\set afile `echo "$outputdir/a.csv"` 
COPY (SELECT * FROM a) TO :'afile'; 

Другой (лучше, на мой взгляд) решение заключается в использовании только psql переменных см this answer of mine about psql variables, который похож на ваш пример. Пример из вашего случая будет:

\set outputdir '/path/to/output' 
\set afile :outputdir '/a.csv' 
COPY (SELECT * FROM a) TO :'afile'; 

Обратите внимание, что в примере, вам нужно установить переменную внутри файла сценария, но вы можете пропустить первую строку, если вы установите его, когда вы звоните psql:

psql --set=outputdir="$outputdir" <conn parameters> -f /path/to/yourscript.sql 
+2

Я был очень взволнован этим ответом, но это не совсем работает для меня. Используя ваш первый пример, «afile» просто оценивает «echo» $ outputdir/a.csv ». Ничто внутри кавычек не расширяется. – user1660256

+0

Примеры работают для меня на psql 9.2.4. Какую версию psql вы используете? – benjwadams

+0

Используем 9.0.2. – user1660256

-1

Это, похоже, работает для вашего случая использования, если вы указали одиночное предложение имени выходного файла, как я уже упоминал. Он избежит любых двойных кавычек, также содержащихся в SQL.

psql -c "$(eval echo '"' $(<envvars.sql | sed 's/"/\\"/g') '"')" 

Конечно, обратите внимание, что если ваш файл содержит любой доллар цитируемого переменные, оболочка будет пытаться интерпретировать как переменные, и ваш сценарий будет ломаться, так что вам нужно будет, чтобы избежать каких-либо знаков доллара, нужно сохранились буквально с обратной косой чертой.

См. Также второй фрагмент в принятом ответе на this question для возможного более надежного ответа.

Смежные вопросы