首页 > 解决方案 > 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 返回文本并且它工作正常。

标签: sqlpostgresqlpostgresql-9.6stored-functions

解决方案


此函数始终返回 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整个函数会更易于阅读(和维护)


推荐阅读