如何将递归转换为plpgsql中的函数?

How convert recursive to function in plpgsql?

我有该工作代码,但我需要将其转换为具有动态属性的函数 tid=1645,其中数字 1645 将始终更改。

with recursive r as (
    select tid, boss from titles where tid=1645
    union
    select titles.tid, titles.boss from titles join r on titles.tid = r.boss
)
select * from r

现在,我也有:

DROP FUNCTION bosses_of_rsd_tids(integer);
CREATE OR REPLACE FUNCTION public.bosses_of_rsd_tids(rsd_tid int)
    RETURNS table (c_tid int, c_boss int)
    LANGUAGE plpgsql
AS $function$
    begin
        with recursive r as (
            select tid, boss from titles where tid=rsd_tid
            union
            select titles.tid, titles.boss from titles join r on titles.boss = r.tid
        )

        select c_tid, c_boss;
    end;
 $function$
;

因此我需要 table 个结果...我尝试 return select c_tid, c_boss; 但出现错误:return

附近出错

您必须对所有查询(包括在内)使用 "return query"

您忘记了 "from r" 中的 select

/* 编辑 */ 在你的例子中你 select c_tid 和 c_boss 而不是 tid 和 boss 并且连接的测试是倒置的

请求已更新:

  DROP FUNCTION bosses_of_rsd_tids(integer);
  CREATE OR REPLACE FUNCTION public.bosses_of_rsd_tids(rsd_tid int)
   RETURNS table (c_tid int, c_boss int)
LANGUAGE plpgsql
 AS $function$
    begin
       return query with recursive r as (
        select tid, boss from titles where tid=rsd_tid
        union
        select titles.tid, titles.boss from titles join r on titles.tid = r.boss        )

    select tid, boss from r;
end;
$function$
;
CREATE OR REPLACE FUNCTION public.bosses_of_rsd_tids(rsd_tid int)
  RETURNS TABLE (c_tid int, c_boss int) AS
$func$
BEGIN
   RETURN QUERY
   WITH RECURSIVE r AS (
      SELECT tid, boss
      FROM   titles
      WHERE  tid = rsd_tid

      UNION ALL                           -- ?!
      SELECT t.tid, t.boss
      FROM   r
      JOIN   titles t ON t.tid = r.boss   -- !
      )
   TABLE r;                               -- !
END
$func$  LANGUAGE plpgsql;

您需要 UNION ALL 而不是 UNION,因为尝试折叠攀登层次结构的重复项没有意义。 (重复会引发无限循环。)

TABLE rSELECT * FROM r 的缩写。你的组织。 select c_tid, c_boss错了。参见:

也可以是更简单的SQL函数:

CREATE OR REPLACE FUNCTION public.bosses_of_rsd_tids(rsd_tid int)
  RETURNS TABLE (c_tid int, c_boss int) AS
$func$
   WITH RECURSIVE r AS (
      SELECT tid, boss
      FROM   titles
      WHERE  tid = rsd_tid

      UNION ALL
      SELECT t.tid, t.boss
      FROM   r
      JOIN   titles t ON t.tid = r.boss
      )
   TABLE r;
$func$  LANGUAGE sql;

参见:

  • Difference between language sql and language plpgsql in PostgreSQL functions