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

时间:2019-05-13 12:27:38

标签: postgresql common-table-expression

我有一个函数,该函数应该返回经理-员工关系表中特定父母的所有孩子。

我有CTE定义了工作问题的递归性,但是为了允许选择任何父级,我将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是包含父子关系的关系,分别是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

1 个答案:

答案 0 :(得分:0)

您在错误的位置输入了RETURN QUERY。它必须位于CTE的顶部。 CTE末尾已经在使用SELECT * FROM HIERARQUIA;,因此您要返回的最终查询是重复的。由于CTE末尾的SELECT没有存储或返回到任何地方,因此您会收到错误消息。

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;