sql - Postgres 9.6:返回字符串数组的函数
问题描述
我正在尝试创建将返回 text/varchar 类型数组的函数。这是一个例子:
CREATE OR REPLACE FUNCTION schema.someFunction(text, text, text)
RETURNS character varying[]
LANGUAGE plpgsql
AS $function$
DECLARE
i text;
arr_len varchar[];
BEGIN
FOR i in (select string_to_array($1,','))
LOOP
arr_len := schema.someOtherFunctionThatReturnsText(i::text, $2, $3)::varchar;
END LOOP;
RETURN arr_len;
END
$function$
;
此函数始终返回 NULL 行。我不明白为什么。有什么建议么?
只是提到 schema.someOtherFunctionThatReturnsText 返回文本并且它工作正常。
解决方案
此函数始终返回 NULL 行。我不明白为什么。
arr_len
每次迭代都会覆盖 的值。我实际上很惊讶该函数在您将标量值(单个text
值)分配给数组时完全起作用 - 实际上应该引发错误,除非该函数返回文本数组(text[]
)而不是text
像混淆名称所暗示的那样。
您还错误地使用了 FOR 循环。仅返回单个数组,select string_to_array()
它不会循环遍历数组。加上变量应该是记录,而不是text
变量。
要遍历数组元素,您需要使用FOREACH
,而不是带有选择的 FOR 循环。然后你需要将函数调用的结果附加到你的结果变量中。但是为了让它工作,你需要先初始化变量。
CREATE OR REPLACE FUNCTION some_function(text, text, text)
RETURNS text[]
LANGUAGE plpgsql
AS $function$
DECLARE
i text;
arr_len text[] := array[]::text[]; -- initialize the array
BEGIN
FOREACH i in ARRAY string_to_array(p_elements,',')
LOOP
arr_len := arr_len || schema.someotherfunctionthatreturnstext(i::text, $2, $3));
END LOOP;
RETURN arr_len;
END
$function$
;
但是你把整个事情复杂化了。
为此,您不需要循环或 PL/pgSQL:
只需取消您获得并array_agg()
用于组装结果的数组:
CREATE OR REPLACE FUNCTION schema.some_function(text, text, text)
RETURNS text[]
LANGUAGE sql
AS
$function$
select array_agg(schema.someotherfunctionthatreturnstext(x.element, $2, $3)::text)
from unnest(string_to_array($1,',')) as x(element);
$function$
;
如果您使用正确的数组类型(例如text[]
)声明参数而不是依赖于逗号分隔的文本值,那会更好。请使用参数名称而不是$1
,否则$2
整个函数会更易于阅读(和维护)