如何return函数内定义的一组cte行?

How to return a set of rows of a cte defined within the function?

我有一个函数应该 return manager-employee 的 table 关系中特定 parent 的所有 children。

我有定义问题递归性的 CTE,但为了允许选择任何 parent,我将 CTE 嵌套在一个函数中。它创建了函数,但是当我调用它时出现错误:查询没有结果数据的目的地

CREATE OR REPLACE FUNCTION  display_full_cat(
    PROCURA VARCHAR
)
    RETURNS SETOF (categoria varchar, super_categoria varchar) AS $BODY$
    BEGIN
        WITH RECURSIVE HIERARQUIA AS (
        SELECT C.CATEGORIA, C.SUPER_CATEGORIA
        FROM CONSTITUIDA C
        WHERE C.SUPER_CATEGORIA = PROCURA
        UNION
        SELECT C.CATEGORIA, C.SUPER_CATEGORIA
        FROM CONSTITUIDA C
        INNER JOIN HIERARQUIA H ON H.CATEGORIA = C.SUPER_CATEGORIA
    ) SELECT * FROM HIERARQUIA;

    RETURN QUERY
        SELECT * FROM HIERARQUIA;
    RETURN;

    END
    $BODY$  LANGUAGE PLPGSQL;

注意:CONSTITUIDA是包含parent-child关系的关系,分别是super_categoria和categoria。

对于数据

super_categoria | categoria
Organism        | Plant
Organism        | Animal
Animal          | Lion
Animal          | Cat
Plant           | Apple
Rock            | Obsidian

结果应该是

super_categoria | categoria
Organism        | Plant
Organism        | Animal
Animal          | Lion
Animal          | Cat
Plant           | Apple

但我却得到了错误:

ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function display_full_cat(character varying) line 3 at SQL statement

您的 RETURN QUERY 位置错误。它需要位于 CTE 的顶部。您已经在 CTE 末尾使用 SELECT * FROM HIERARQUIA;,因此您尝试 return 的最终查询是重复的。您收到错误是因为 CTE 末尾的 SELECT 未存储或 return 在任何地方编辑。

CREATE OR REPLACE FUNCTION  display_full_cat(PROCURA VARCHAR)
RETURNS SETOF (categoria varchar, super_categoria varchar) 
AS $BODY$
BEGIN
    RETURN QUERY -- This will return the result from the last query in the CTE.
    WITH RECURSIVE HIERARQUIA 
    AS (
        SELECT C.CATEGORIA, C.SUPER_CATEGORIA
        FROM CONSTITUIDA C
        WHERE C.SUPER_CATEGORIA = PROCURA
        UNION
        SELECT C.CATEGORIA, C.SUPER_CATEGORIA
        FROM CONSTITUIDA C
        JOIN HIERARQUIA H ON H.CATEGORIA = C.SUPER_CATEGORIA
    ) SELECT * FROM HIERARQUIA; -- Prior to moving RETURN QUERY, this was causing the error
END;
$BODY$  LANGUAGE PLPGSQL;