如何在函数内部使用递归查询?

Posted

技术标签:

【中文标题】如何在函数内部使用递归查询?【英文标题】:How to use a recursive query inside of a function? 【发布时间】:2019-10-16 18:43:44 【问题描述】:

我在下面有一个有效的递归函数,它返回 .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、dependent_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;

我尝试在谷歌上搜索在函数中使用递归查询,但少数结果证明不起作用。

如果有任何帮助,我将不胜感激,在此先感谢。

【问题讨论】:

【参考方案1】:

您的函数不返回任何内容。您至少需要一个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;

【讨论】:

以上是关于如何在函数内部使用递归查询?的主要内容,如果未能解决你的问题,请参考以下文章

mysql递归查询

mysql如何递归汇总?

sql用啥方法可以实现递归函数?

SQL递归查询知多少

MySQL怎样做递归查询

函数之递归