I have the following code in a shell script that initializes the postgres
database in a docker
container:
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
In the if
and else
statement the SQL query is identical and I would like to put in a variable so I don't have to repeat it.
I tried to do QUERY="..."
, then psql ... -c "$QUERY"
but I get errors on the \
char.
Is there a way to store this multiline SQL query in a variable and run it with psql
CodePudding user response:
I always endeavor to avoid these cases and try to come up with a way around it if possible. You could do it this way (and not change anything in your query code which works already!):
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
This way, hostoption
is empty for development. And adding a space after psql
will not break anything.
For other environments, it contains the host option.
CodePudding user response:
To easily test your query, it's best to store it in a script and use -f
from psql
. But if you really need this query in the shell-script itself, you can use apostrophes to enclose your delimiter word (EOF
) and inhibit shell expansion, than you can just copy-paste your tested sql-script into shell-script, like:
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
A better programming logic for your question was already pointed out by @Nic3500.