You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在AWS RDS PostgreSQL 16.3中创建函数失败,美元符号引发语法错误

问题

在运行PostgreSQL 16.3的AWS RDS实例及本地PostgreSQL实例中,创建函数时持续触发由$$符号引发的语法错误,即使使用PostgreSQL官网标注的规范语法也无法解决。相关代码及错误信息如下:

代码:

CREATE OR REPLACE FUNCTION public.get_current_user_id()
    RETURNS uuid
    LANGUAGE plpgsql
   AS 
$$
    SELECT current_setting('app.current_user_id', true)::uuid;
$$;

CREATE OR REPLACE FUNCTION public.user_has_role(p_role_names text[])
    RETURNS boolean
    LANGUAGE plpgsql
AS $$
BEGIN
    RETURN EXISTS (
        SELECT 1
        FROM public.um_user_roles ur
        JOIN public.um_roles r ON ur.role_id = r.id
        WHERE ur.user_id = public.get_current_user_id()
        AND r.role_name = ANY(p_role_names)
        AND ur.status = 'active'
        AND (ur.valid_until IS NULL OR ur.valid_until > CURRENT_TIMESTAMP)
    );
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

错误信息:

Error at line 37:
Statement: CREATE OR REPLACE FUNCTION public.get_current_user_id() RETURNS uuid LANGUAGE plpgsql AS $$ DECLARE BEGIN RETURN current_setting('app.current_user_id', true)::uuid;
Error message: unterminated dollar-quoted string at or near "$$ DECLARE BEGIN RETURN current_setting('app.current_user_id', true)::uuid;"
LINE 1: ...urrent_user_id() RETURNS uuid LANGUAGE plpgsql AS $$ DECLARE...
                                                             ^
解决方案

1. 修复第一个函数的PL/pgSQL语法

get_current_user_id指定了LANGUAGE plpgsql,但函数体直接写了SELECT语句,未遵循PL/pgSQL必须用BEGIN...END包裹逻辑的规范。有两种修复方式:

方式一:保留PL/pgSQL语言,补充BEGIN...END块

CREATE OR REPLACE FUNCTION public.get_current_user_id()
    RETURNS uuid
    LANGUAGE plpgsql
AS 
$$
BEGIN
    RETURN current_setting('app.current_user_id', true)::uuid;
END;
$$;

方式二:改用SQL语言(无需BEGIN...END)

如果不需要PL/pgSQL的流程控制等特性,直接用SQL语言更简洁:

CREATE OR REPLACE FUNCTION public.get_current_user_id()
    RETURNS uuid
    LANGUAGE sql
AS 
$$
    SELECT current_setting('app.current_user_id', true)::uuid;
$$;

2. 删除第二个函数的冗余语言声明

user_has_role函数末尾重复写了LANGUAGE plpgsql,函数开头已指定语言,需删除该冗余内容:

CREATE OR REPLACE FUNCTION public.user_has_role(p_role_names text[])
    RETURNS boolean
    LANGUAGE plpgsql
AS $$
BEGIN
    RETURN EXISTS (
        SELECT 1
        FROM public.um_user_roles ur
        JOIN public.um_roles r ON ur.role_id = r.id
        WHERE ur.user_id = public.get_current_user_id()
        AND r.role_name = ANY(p_role_names)
        AND ur.status = 'active'
        AND (ur.valid_until IS NULL OR ur.valid_until > CURRENT_TIMESTAMP)
    );
END;
$$ SECURITY DEFINER;

3. 关于$$错误的说明

错误提示中的unterminated dollar-quoted string并非$$本身的问题,而是语法错误导致解析器无法正确识别结束标记。修复上述语法问题后,$$的使用会恢复正常。

内容的提问来源于stack exchange,提问作者Raphael Heard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 13:23:17