Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function 函数返回节点所有子节点的表_Function_Postgresql_Recursion_Plpgsql_Children - Fatal编程技术网

Function 函数返回节点所有子节点的表

Function 函数返回节点所有子节点的表,function,postgresql,recursion,plpgsql,children,Function,Postgresql,Recursion,Plpgsql,Children,假设我得到了以下表格结构: | ID | ParentID | Name | 我想编写一个递归PostgreSQL函数,用于获取作为参数传递给它的节点ID的所有子节点 以下是我的代码,到目前为止,我只有函数的一部分可以获取传递ID的所有子项,现在我需要递归部分: CREATE OR REPLACE FUNCTION GetAllChildren(IN NodeID INTEGER) RETURNS INTEGER AS $$ DECLARE Crs CURSOR FOR SELECT

假设我得到了以下表格结构:

| ID | ParentID | Name |
我想编写一个递归PostgreSQL函数,用于获取作为参数传递给它的节点ID的所有子节点

以下是我的代码,到目前为止,我只有函数的一部分可以获取传递ID的所有子项,现在我需要递归部分:

CREATE OR REPLACE FUNCTION GetAllChildren(IN NodeID INTEGER) RETURNS INTEGER AS $$
DECLARE
    Crs CURSOR FOR SELECT ID, ParentID, Name FROM Tree WHERE ParentID=NodeID;
    VarRow Tree%ROWTYPE;
BEGIN
    OPEN Crs;

    CREATE TEMPORARY TABLE TBL(
        ID SERIAL,
        ParentID INTEGER,
        Name CHARACTER(100)
    );

    LOOP
        FETCH Crs INTO VarRow;
        IF VarRow IS NULL THEN
            EXIT;
        END IF;
        INSERT INTO TBL(ID, ParentID, Name) VALUES(VarRow.ID, VarRow.ParentID, VarRow.Name);
    END LOOP;

    CLOSE Crs;

    RETURN 0;
END;
$$ LANGUAGE plpgsql;
也许最大的问题是我不知道在递归调用之间将输出保存在哪里

如果到目前为止还没有弄清楚,那就是邻接列表,获取节点的所有子节点并将它们打印到表中


有人有解决方案吗?

有关信息,Postgres中有一些常用的表表达式,这可能会在这里有所帮助:

改编文档中的示例:

WITH RECURSIVE rec_tree(parent_id, node_id, data, depth) AS (
        SELECT t.parent_id, t.node_id, t.data, 1
        FROM tree t
      UNION ALL
        SELECT t.parent_id, t.node_id, t.data, rt.depth + 1
        FROM tree t, rec_tree rt
        WHERE t.parent_id = rt.node_id
)
SELECT * FROM rec_tree;

有关防止图表循环的示例,请参见文档。

有关信息,Postgres中有一些常见的表表达式,这些表达式可能会在这里有所帮助:

改编文档中的示例:

WITH RECURSIVE rec_tree(parent_id, node_id, data, depth) AS (
        SELECT t.parent_id, t.node_id, t.data, 1
        FROM tree t
      UNION ALL
        SELECT t.parent_id, t.node_id, t.data, rt.depth + 1
        FROM tree t, rec_tree rt
        WHERE t.parent_id = rt.node_id
)
SELECT * FROM rec_tree;
请参阅文档,以了解阻止图表循环的示例

PostgreSQL不知道本地过程限制的临时表-您的临时表在被调用函数的所有实例中都可见,并且在函数外部也可见-它具有会话可见性

但PostgreSQL函数PostgreSQL并没有过程可以直接返回表,所以不需要使用辅助表来存储数据

这个表单更快,因为您不填写任何表格,尽管临时表格通常只在RAM中

您不需要在PostgreSQL-statement中使用显式游标来完成所有操作,它更短、更友好

最好的解决方案是Denis idea-使用CTE-递归SQL。 PostgreSQL不知道本地过程限制的临时表-您的临时表在被调用函数的所有实例中都可见,并且在函数外部也可见-它具有会话可见性

但PostgreSQL函数PostgreSQL并没有过程可以直接返回表,所以不需要使用辅助表来存储数据

这个表单更快,因为您不填写任何表格,尽管临时表格通常只在RAM中

您不需要在PostgreSQL-statement中使用显式游标来完成所有操作,它更短、更友好

最好的解决方案是Denis idea-使用CTE-递归SQL。