我非常非常擅长编写Postgres函数。我通过从孩子的id开始递归地搜索父母来编写一个函数来为孩子建立物化路径。这是我的功能,但我不断收到错误ERROR: RETURN cannot have a parameter in function returning set
create or replace function build_mp(child_id text)
returns SETOF text
language plpgsql
as $$
begin
select parentid from account where childid = child_id;
if parentid IS NULL then
return ARRAY[child_id];
else
return build_mp(parentid) || ARRAY[child_id];
end if;
end $$;
SELECT build_mp('mychild');
我做错了什么?
这是工作解决方案。它需要一个孩子的id,然后递归搜索它上面的所有父母,为新的子项建立一个物质路径。
create or replace function build_mp(child_id text)
returns text[]
language plpgsql
as $$
declare
parent text;
begin
execute 'select parentid from account where childid = $1' INTO parent USING child_id;
if parent IS NULL THEN
return ARRAY[child_id];
else
return build_mp(parent) || ARRAY[child_id];
end if;
end $$;
SELECT build_mp('mychild') AS mp;
答案 0 :(得分:3)
要克服" 错误:查询没有结果数据的目的地"错误,你不需要动态SQL。
你可以select into a variable directly:
select parentid into parent from account where childid = child_id;
但是您可以使用recursive CTE和SQL函数来简化您的功能。这将会表现得更好,尤其是在大量关卡中:
create or replace function build_mp(child_id text)
returns text[]
language sql
as
$$
with recursive all_levels (childid, parentid, level) as (
select childid, parentid, 1
from account
where childid = child_id
union all
select c.childid, c.parentid, p.level + 1
from account c
join all_levels p on p.parentid = c.childid
)
select array_agg(childid order by level)
from all_levels;
$$;
答案 1 :(得分:1)
如果要返回text
数组,则必须将该函数声明为
... RETURNS text[]
而不是
... RETURNS SETOF text
set return函数返回一个表,而数组是text[]
类型的单个值。在set return函数中,您将为返回的每一行使用RETURN NEXT child_id
并使用RETURN
(不带参数)来终止函数处理。
PostgreSQL抱怨你在集合返回函数中使用RETURN value
,这是不允许的。