PostgreSQL中如何获取子数组长度及嵌套数组查询报错问题解析
问题根源分析
你遇到的这个问题其实是个容易混淆的小坑——你误以为自己在操作嵌套数组,但实际上你的a是一个一维数组,里面的元素是普通的text字符串。
PostgreSQL有个特殊的语法支持:你可以对字符串使用[n]的索引方式来访问它的单个字符,比如'hello'[2]会返回'e'。那你写的a[1][2][1]实际执行逻辑是:
- 先取一维数组
a的第1个元素:这是一个text字符串; - 再取这个字符串的第2个字符;
- 最后取这个单个字符的第1个字符(结果还是它自己)。
所以这条语句能正常返回值,但本质上和嵌套数组一点关系都没有。而当你执行array_length(a[1], 1)时,a[1]是text类型的字符串,不是数组,自然找不到接收text和integer参数的array_length函数,就出现了你看到的报错。
正确的嵌套数组用法
如果你确实需要处理嵌套数组(数组的数组的数组),得先创建真正的嵌套结构。比如在PL/pgSQL里可以这么定义和使用:
DO $$ DECLARE -- 定义一个数组的数组的数组:三层嵌套 a text[] := ARRAY[ ARRAY[ARRAY['a', 'b'], ARRAY['c']], ARRAY[ARRAY['d', 'e', 'f']] ]; BEGIN -- 访问嵌套数组的元素:这才是真正的多维索引 RAISE NOTICE '%', a[1][2][1]; -- 返回 'c' -- 获取外层数组的长度 RAISE NOTICE '%', array_length(a, 1); -- 返回 2 -- 获取a[1]这个内层数组的长度 RAISE NOTICE '%', array_length(a[1], 1); -- 返回 2 -- 获取a[1][2]这个最内层数组的长度 RAISE NOTICE '%', array_length(a[1][2], 1); -- 返回 1 END $$;
如何区分两种情况?
你可以用pg_typeof()函数来查看变量或表达式的类型,比如执行RAISE NOTICE '%', pg_typeof(a[1]);:
- 如果返回
text,说明你的a是一维数组,元素是字符串; - 如果返回
text[],说明你的a[1]确实是一个数组,这时候array_length(a[1],1)就能正常工作。
内容的提问来源于stack exchange,提问作者holden321
相关产品推荐
相关产品推荐

