$$ double语法在$ postpost函数创建中的语法错误[重复]

问题描述 投票:0回答:2

我正在尝试在postgres实例启动期间创建一个简单的函数。我这样做是通过将某些.sh文件映射到/docker-entrypoint-initdb.d目录。

我通过这个简单的功能不断遇到问题。

#!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
    CREATE OR REPLACE FUNCTION hi() RETURNS TEXT AS $$
    BEGIN
        RETURN 'hi'
    END;
    $$;
EOSQL
2020-01-29 05:12:30.817 UTC [62] ERROR:  syntax error at or near "1" at character 49
2020-01-29 05:12:30.817 UTC [62] STATEMENT:  CREATE OR REPLACE FUNCTION hi() RETURNS TEXT AS 1
        BEGIN
            RETURN 'hi'
        END;
ERROR:  syntax error at or near "1"
LINE 1: CREATE OR REPLACE FUNCTION hi() RETURNS TEXT AS 1

如果我将其更改为具有实际内容的内容:

#!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
    CREATE OR REPLACE FUNCTION hi() RETURNS TEXT AS $func$
    BEGIN
        RETURN 'hi'
    END;
    $func$;
EOSQL

我在同一地方遇到另一个错误:

2020-01-29 05:17:36.161 UTC [62] ERROR:  syntax error at or near "$" at character 49
2020-01-29 05:17:36.161 UTC [62] STATEMENT:  CREATE OR REPLACE FUNCTION hi() RETURNS TEXT AS $
        BEGIN
            RETURN 'hi'
        END;
ERROR:  syntax error at or near "$"
LINE 1: CREATE OR REPLACE FUNCTION hi() RETURNS TEXT AS $

运行最新的postgres版本:12.1

此函数定义到底有什么问题,为什么会出现此错误?

bash postgresql function heredoc
2个回答
1
投票

Bash的此处文档(从<<-EOSQLEOSQL)默认情况下支持参数替换(以及其他类似的扩展);因此$$将被进程ID取代,而$func将被空字符串取代,而PostgreSQL才看到它们。

要禁用该功能,只需将<<-EOSQL更改为<<-'EOSQL'

((相关文档:https://www.gnu.org/software/bash/manual/bash.html#Here-Documents。]


1
投票

$func$$bash中的变量。第一个是shell实例的进程ID,它解释错误输出中的数字;第二个只是普通的用户定义变量,大概为空,因此$test$变为$(因为$test被空字符串替换)。

[您可以使用bash\$\$来逃避\$test\$发现的美元符号,也可以使用<<-'EOSQL'在heredoc上使用单引号(无变量替换)语义。

这与PostgreSQL无关,它是bash做您想做的事。

© www.soinside.com 2019 - 2024. All rights reserved.