PostgreSQL遍历JSON数组元素报错,求非RECORD变量解决方案
解决PL/pgSQL遍历JSONB数组的问题(不用FOR循环和RECORD变量)
你遇到的问题核心是:jsonb_array_elements返回的是行集合,而FOREACH ... IN ARRAY需要的是PostgreSQL原生的数组类型,直接混用就会报返回多行的错误;第二个尝试的语法错误则是因为FOREACH后面不能直接跟SELECT语句,得先把行集转换成数组并赋值给变量。
要满足你「不用FOR r IN (...)和RECORD变量」的要求,有两种简洁的写法:
方法1:用jsonb_array_to_text_array直接转成原生数组
PostgreSQL 12及以上版本提供了jsonb_array_to_text_array函数,可以直接把JSONB数组转成text类型的PostgreSQL数组,这样就能直接用FOREACH遍历了:
do $$ declare datajson jsonb := '{ "elements": [ "element1", "element2", "element3", "element4" ] }'; element varchar(128); elements_array text[] := jsonb_array_to_text_array(datajson->'elements'); begin foreach element in array elements_array loop raise notice '%', element; end loop; end; $$;
方法2:用array()构造器把行集转成数组
如果你的PostgreSQL版本低于12,可以用array()把jsonb_array_elements_text的结果转成数组(jsonb_array_elements_text直接返回text类型值,避免额外类型转换):
do $$ declare datajson jsonb := '{ "elements": [ "element1", "element2", "element3", "element4" ] }'; element varchar(128); elements_array text[] := array(select jsonb_array_elements_text(datajson->'elements')); begin foreach element in array elements_array loop raise notice '%', element; end loop; end; $$;
为什么之前的写法不对?
- 第一个错误:
jsonb_array_elements返回的是行数据,不是PostgreSQL原生数组,FOREACH ... IN ARRAY无法直接处理行集,所以触发「返回多于一行」的报错。 - 第二个错误:
FOREACH ... IN ARRAY语法要求后面必须跟一个数组变量,不能直接嵌套SELECT语句,因此导致语法解析失败。
内容的提问来源于stack exchange,提问作者lapots
相关产品推荐
相关产品推荐

