Как преобразовать рекурсивную функцию в plpgsql? - PullRequest
0 голосов
/ 07 мая 2019

у меня есть этот рабочий код, но мне нужно преобразовать его в функцию с динамическим атрибутом 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$
;

В результате мне нужна таблица результатов ... Я пытался return select c_tid, c_boss;, но есть ошибка: ошибка около возврата

Ответы [ 2 ]

2 голосов
/ 07 мая 2019
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 r - это сокращение от SELECT * 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;

См .:

1 голос
/ 07 мая 2019

Вы должны использовать «запрос возврата» для всего запроса (с включенным)

Вы забыли "из r" в главном списке

/ * РЕДАКТИРОВАТЬ * / в вашем примере вы выбираете 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$
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...