#postgresql #bash #shell #psql
Вопрос:
У меня есть следующий код в сценарии оболочки, который инициализирует postgres
базу данных в docker
контейнере:
if [ "$ENV" == "development" ];
then
psql --username "postgres" --dbname "postgres" <<EOSQL
SELECT 'CREATE DATABASE $DATABASE' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DATABASE');gexec
connect "$DATABASE";
DO $
BEGIN
-- Some stuff
END
$;
-- Other stuff
EOSQL
else
psql --host "$HOST" --username "postgres" --dbname "postgres" <<EOSQL
SELECT 'CREATE DATABASE $DATABASE' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DATABASE');gexec
connect "$DATABASE";
DO $
BEGIN
-- Some stuff
END
$;
-- Other stuff
EOSQL
fi
В операторе if
and else
SQL-запрос идентичен, и я хотел бы ввести переменную, чтобы мне не пришлось ее повторять.
Я пытался это сделать QUERY="..."
, psql ... -c "$QUERY"
но потом получаю ошибки в
символе.
Есть ли способ сохранить этот многострочный SQL-запрос в переменной и запустить его с помощью psql
Ответ №1:
Я всегда стараюсь избегать подобных случаев и стараюсь по возможности найти способ обойти их. Вы могли бы сделать это таким образом (и ничего не менять в своем коде запроса, который уже работает!):
hostoption=""
if [[ "$ENV" != "development" ]]
then
hostoption="--host $HOST"
fi
psql $hostoption --username "postgres" --dbname "postgres" <<EOSQL
SELECT 'CREATE DATABASE $DATABASE' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DATABASE');gexec
connect "$DATABASE";
DO $
BEGIN
-- Some stuff
END
$;
-- Other stuff
EOSQL
Этот путь hostoption
пуст для развития. И добавление пробела после psql
ничего не нарушит.
Для других сред он содержит параметр хост.
Ответ №2:
Чтобы легко протестировать ваш запрос, лучше всего сохранить его в скрипте и использовать -f
из psql
. Но если вам действительно нужен этот запрос в самом сценарии оболочки, вы можете использовать апострофы, чтобы заключить слово-разделитель ( EOF
) и запретить расширение оболочки, чем вы можете просто скопировать и вставить проверенный sql-скрипт в сценарий оболочки, например:
psql $hostoption --username "postgres" --dbname "postgres" <<'EOSQL'
SELECT 'CREATE DATABASE $DATABASE' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DATABASE');gexec
connect "$DATABASE";
DO $
BEGIN
-- Some stuff
END
$;
-- Other stuff
EOSQL
Лучшая логика программирования для вашего вопроса уже была указана @Nic3500.