PostgreSQL中如何使用ANYARRAY及转换函数空数组值
如何在PostgreSQL中使用
ANYARRAY多态类型 咱们先从你写的那个函数问题入手,再展开讲ANYARRAY的正确用法。
你原函数的问题所在
你写的函数里,array[]::ANYARRAY这部分是错误的——ANYARRAY是多态类型,它本身不是一个具体的数组类型,PostgreSQL没办法直接把空数组字面量转换成一个“任意数组”类型,它需要明确的具体类型(比如text[]、int[])。
ANYARRAY的核心用法
ANYARRAY的作用是让你的函数能适配任意类型的数组,不用为text[]、int[]、numeric[]等每种数组类型单独写一个函数。使用它的关键是:
- 作为函数参数或返回类型时,PostgreSQL会根据调用时的实际输入,自动推断出具体的数组类型
- 不要直接把
ANYARRAY当作字面量的类型来用,要依赖输入参数的类型来生成对应类型的对象(比如空数组)
修正你的array_coalesce函数
把空数组的构造改成基于输入参数的类型,用typeof($1)来获取输入数组的具体类型,这样就能生成对应类型的空数组了:
CREATE FUNCTION array_coalesce(ANYARRAY) RETURNS ANYARRAY AS $f$ SELECT CASE WHEN $1 IS NULL THEN ARRAY[]::typeof($1) ELSE $1 END; $f$ language SQL IMMUTABLE;
测试这个函数:
select array_coalesce(null::text[]);会返回空的text[]数组select array_coalesce(array[1,2]::int[]);会返回原数组{1,2}select array_coalesce(null::numeric[]);会返回空的numeric[]数组
这样不管传入哪种类型的数组,函数都能正确处理,这就是ANYARRAY的优势——一次定义,适配所有数组类型。
补充:和你提到的其他操作的关联
你说的concat()、||这些操作的“类coalesce特性”,本质上是它们的重载版本支持了ANYARRAY(或对应多态类型),并且做了空值/空数组的友好处理:
concat()对text类型的空值直接忽略,拼接非空内容||对数组的处理逻辑是:如果其中一边是null,就把它当作空数组来拼接,所以null::text[] || array[]::text[]和array[]::text[] || null::text[]都会返回空数组
这些操作的底层也是利用了PostgreSQL的多态类型机制,和ANYARRAY的用法逻辑是一致的。
内容的提问来源于stack exchange,提问作者Peter Krauss
相关产品推荐
相关产品推荐

