将多行 EOSQL 和 with \ char 查询存储在变量中,并使用 psql 运行

Store multiline EOSQL and with \ char query in variable and run it with psql

我在 shell 脚本中有以下代码,用于初始化 docker 容器中的 postgres 数据库:

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

ifelse 语句中,SQL 查询是相同的,我想放入一个变量,这样我就不必重复了。

我尝试执行 QUERY="...",然后 psql ... -c "$QUERY" 但我在 \ 字符上遇到错误。

有没有办法将此多行 SQL 查询存储在变量中,并 运行 使用 psql

我总是努力避免这些情况,并尽可能想出解决办法。您可以这样做(并且不更改已经有效的查询代码中的任何内容!):

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 之后添加 space 不会破坏任何东西。

对于其他环境,它包含主机选项。

要轻松测试您的查询,最好将其存储在脚本中并使用 psql 中的 -f。但是,如果您确实需要在 shell-脚本本身中进行此查询,则可以使用撇号将分隔符 (EOF) 括起来并禁止 shell 扩展,而不是复制粘贴您测试的 sql-script 到 shell-script,例如:

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 已经为您的问题指出了更好的编程逻辑。