Как использовать рекурсивный запрос внутри функции? - PullRequest
0 голосов
/ 16 октября 2019

Внизу у меня есть рабочая рекурсивная функция, которая возвращает иерархию элемента .Net, в этом примере 'ImageBrush'

    WITH RECURSIVE r AS (
    SELECT id, name, dependent_id, 1 AS level
    FROM dotNetHierarchy
    WHERE name = 'ImageBrush'
    UNION ALL
    SELECT g.id, lpad(' ', r.level) || g.name, g.dependent_id, r.level + 1
    FROM dotNetHierarchy g JOIN r ON g.id = r.dependent_id
    )
    SELECT name FROM r;

Теперь я хочу использовать ее внутри функции, где вводтекст наподобие 'ImageBrush', который вставляется в оператор WHERE рекурсивного запроса.

Таблица dotNetHierarchy имеет 3 столбца: id, name, independent_id

Следующее не работает с PgAdminпросто запросы навсегда без ошибок:

    CREATE OR REPLACE FUNCTION get_hierarchy(inp text) RETURNS 
    TABLE (id int, name text, id int, lev int) AS
    $BODY$
    DECLARE
    BEGIN
        WITH RECURSIVE r AS (
        SELECT id, name, dependent_id, 1 AS level
        FROM dotNetHierarchy
        WHERE name = inp
      UNION ALL
        SELECT g.id, lpad(' ', r.level) || g.name, g.dependent_id, r.level + 1
        FROM dotNetHierarchy g JOIN r ON g.id = r.dependent_id
        )

        SELECT name FROM r;
        return;
    END
    $BODY$
    LANGUAGE plpgsql;

Я пытался найти в Google поиск рекурсивных запросов в функциях, но результаты оказались неэффективными.

Буду признателен за любую помощь, спасибозаранее.

1 Ответ

0 голосов
/ 16 октября 2019

Ваша функция ничего не возвращает. По крайней мере, вам понадобится return query, но более эффективно использовать функцию language sql для инкапсуляции запроса:

CREATE OR REPLACE FUNCTION get_hierarchy(inp text) 
  RETURNS TABLE (id int, name text, id int, lev int) AS
$BODY$
WITH RECURSIVE r AS (
  SELECT id, name, dependent_id, 1 AS level
  FROM dotNetHierarchy
  WHERE name = inp
  UNION ALL
  SELECT g.id, lpad(' ', r.level) || g.name, g.dependent_id, r.level + 1
  FROM dotNetHierarchy g JOIN r ON g.id = r.dependent_id
)
SELECT name
FROM r;
$BODY$
LANGUAGE sql;
...