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

PostgreSQL函数处理枚举类型JSON数组时触发无效令牌错误

解决PostgreSQL 15中枚举类型JSON数组参数的转换错误

问题根源

传递自定义枚举my_category的数组参数时,枚举值以无引号的纯文本形式(比如type5)存在,而JSON语法要求字符串必须被双引号包裹,直接转换为JSONB时就会触发invalid input syntax for type json错误。整数类型本身符合JSON的数字语法规则,所以不会出现这类问题。

解决方案

1. 构造参数时主动给枚举值加引号

调用函数传递JSON参数时,确保枚举值是带双引号的字符串数组,示例格式:

{"categories": ["type1", "type5", "type3"]}

避免使用无引号的纯文本写法:

{"categories": [type1, type5, type3]}

2. 在函数内部处理枚举值的转换

如果无法修改参数传入形式,可以在函数里先把枚举值转为带引号的字符串,再拼接成合法的JSON数组后转JSONB。示例函数修改如下:

CREATE OR REPLACE FUNCTION select_ids(query_params JSON)
RETURNS SETOF INTEGER AS $$
DECLARE
    category_array JSONB;
BEGIN
    -- 处理枚举参数:提取枚举值转为字符串并添加引号,拼接为合法JSON数组
    IF query_params ? 'categories' THEN
        category_array := ('["' || array_to_string(array(
            SELECT unnest((query_params->>'categories')::TEXT::my_category[])::TEXT
        ), '", "') || '"]')::JSONB;
    ELSE
        category_array := '[]'::JSONB;
    END IF;

    -- 执行筛选逻辑
    RETURN QUERY
    SELECT id FROM features
    WHERE (category_array = '[]'::JSONB OR category = ANY(category_array::my_category[]));
END;
$$ LANGUAGE plpgsql;

3. 用to_json函数自动序列化枚举值

利用PostgreSQL的to_json函数,它会自动将枚举值序列化为符合JSON规范的带引号字符串,写法更简洁:

CREATE OR REPLACE FUNCTION select_ids(query_params JSON)
RETURNS SETOF INTEGER AS $$
BEGIN
    RETURN QUERY
    SELECT id FROM features
    WHERE (
        query_params->>'categories' IS NULL
        OR category = ANY(
            ARRAY(SELECT jsonb_array_elements_text(to_json((query_params->>'categories')::my_category[])::JSONB))::my_category[]
        )
    );
END;
$$ LANGUAGE plpgsql;

关键说明

  • JSON语法中,字符串必须用双引号包裹,无引号的纯文本标识符不符合规范,只有数字、布尔值、null可以不用引号。
  • PostgreSQL的自定义枚举类型以纯文本形式存储,但转换为JSON时必须显式处理为带引号的字符串,否则会触发语法错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 17:02:39