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

PostgreSQL遍历JSON数组列表报错:FOREACH表达式不可为null

PostgreSQL遍历JSON数组报错:FOREACH expression must not be null 排查与解决

问题场景

需要在PostgreSQL中遍历JSON数组,编写了以下PL/pgSQL代码:

do $$
    declare 
    jsn JSONB;
    j JSONB;
    arj JSONB[];
    begin
        jsn = to_jsonb('{"lst" : [{"a":"1"}, {"b":"2"}]}'::TEXT);
        arj = jsn->>'lst';
        FOREACH j IN ARRAY arj LOOP
              SELECT j;
        END LOOP;
    end;
$$;

运行后触发错误:

ERROR:  FOREACH expression must not be null
CONTEXT:  PL/pgSQL function inline_code_block line 9 at FOREACH over array
SQL state: 22004

错误原因分析

  1. JSON解析错误:to_jsonb('{"lst"...}'::TEXT)是把JSON格式的字符串转成了JSONB类型的字符串值,而非解析成JSONB对象。实际jsn存储的是带转义的字符串,而非预期的JSON结构,导致后续提取lst字段时返回null。
  2. 类型不匹配:即使jsn是正确的JSONB对象,->>操作符返回的是TEXT类型,直接赋值给JSONB[]类型变量arj会导致隐式转换失败,最终arj为null,触发FOREACH的非空检查错误。

解决方法

提供两种可行方案:

方案一:修正解析与类型转换

先正确解析JSON为JSONB对象,再将JSON数组转为PostgreSQL原生数组:

do $$
    declare 
    jsn JSONB;
    j JSONB;
    arj JSONB[];
    begin
        -- 直接将JSON字符串转为JSONB类型
        jsn = '{"lst" : [{"a":"1"}, {"b":"2"}]}'::JSONB;
        -- 将JSON数组转为PostgreSQL的JSONB数组
        arj = array(select jsonb_array_elements(jsn->'lst'));
        FOREACH j IN ARRAY arj LOOP
              -- 用RAISE NOTICE输出结果,DO块中SELECT不会返回给客户端
              RAISE NOTICE '%', j;
        END LOOP;
    end;
$$;

方案二:直接遍历JSON数组(更简洁)

无需转换为PostgreSQL数组,直接通过jsonb_array_elements函数遍历:

do $$
    declare 
    jsn JSONB;
    j JSONB;
    begin
        jsn = '{"lst" : [{"a":"1"}, {"b":"2"}]}'::JSONB;
        -- 遍历JSON数组的每个元素
        FOR j IN SELECT jsonb_array_elements(jsn->'lst') LOOP
              RAISE NOTICE '%', j;
        END LOOP;
    end;
$$;

补充说明

  • ->操作符返回JSONB类型,->>返回TEXT类型,需根据场景选择。
  • DO块中的SELECT j不会将结果返回给客户端,需用RAISE NOTICE、插入表等方式处理结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:01:06