我正在尝试创建将返回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返回文本,它就可以正常工作。
答案 0 :(得分:1)
此函数始终返回NULL行。我不明白为什么。
您每次迭代都会覆盖arr_len
的值。我实际上很惊讶该函数在向数组分配标量值(单个text
值)时完全起作用-除非该函数返回文本数组(text[]
),否则实际上应该引发错误而不是混淆名称所暗示的text
。
您还错误地使用了FOR循环。 select string_to_array()
仅返回一个数组,不会在数组上循环。另外,变量应该是一条记录,而不是text
变量。
对于loop over array elements,您需要使用FOREACH
,而不是带有select的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
,以便使整个函数更易于阅读(和维护)