Postgres 递归查询,CTE 使用 sql 在 postgres 函数内进入无限循环?

Postgres Recursive Query, CTE goes in infinite loop inside postgres function using sql?

尝试制作一个 postgres 函数,在其中我制作了一个 CTE,以递归迭代分层数据(父子关系) 我的Table结构

在此我需要递归迭代 if text_id != new_text_id 并在 text_id == new_[=34= 时停止(终止条件) ]

Table供参考的架构

create table demoTextTable
(
    text_id serial primary key,
    text_details character varying,
    new_text_id integer
)

insert into demoTextTable(text_details, new_text_id)
values ('Comment 1', 2),
       ('Comment 1 updated 1st Time',3),
       ('Comment 1 updated 2nd Time',4),
       ('Comment 1 updated 3rd Time',5),
       ('Comment 1 updated 4th Time',5);

我的 Postgres 函数

create or replace function get_text_history(textId integer)
RETURNS Table (
    text_id integer,
    text_details varchar,
    new_text_id integer)
AS $$
BEGIN
WITH RECURSIVE textHierarchy AS (

    select tm.text_id, tm.text_details, tm.new_text_id
    from text_master tm where tm.text_id = textId

    UNION ALL

    select tm.text_id, tm.text_details, tm.new_text_id
    FROM textHierarchy AS txtHr, text_master AS tm where tm.text_id != txtHr.new_text_id
    and txtHr.new_text_id is not null
)
select * from textHierarchy;
END;
$$ Language plpgsql;

好的所以尝试了更多并让内部 CTE 工作但是如果我在函数内部执行它那么它会在执行函数时出错 as

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 get_text_history(integer) line 3 at SQL statement
SQL state: 42601

我更新的函数:-

create or replace function get_text_history(textId integer)
RETURNS Table (
    text_id integer,
    text_details varchar,
    new_text_id integer)
AS $$
BEGIN
WITH RECURSIVE textHierarchy AS (

    select dtbl.text_id, dtbl.text_details, dtbl.new_text_id
    from demoTextTable dtbl where dtbl.text_id = textId

    UNION

    select dtbl.text_id, dtbl.text_details, dtbl.new_text_id
    FROM demoTextTable dtbl where dtbl.text_id != dtbl.new_text_id or 
    dtbl.text_id = dtbl.new_text_id order by text_id asc

)
select * from textHierarchy;
END;
$$ Language plpgsql;

您想使用 SQL,而不是 PL/pgSQL,您需要 UNION 而不是 UNION ALL,并且您需要加入 = 而不是<>:

CREATE OR REPLACE FUNCTION get_text_history(textId integer)
RETURNS TABLE (
    text_id integer,
    text_details varchar,
    new_text_id integer
) LANGUAGE sql AS
$$WITH RECURSIVE textHierarchy AS (
    SELECT tm.text_id, tm.text_details, tm.new_text_id
    FROM demotexttable tm 
    WHERE tm.text_id = textId
  UNION
    SELECT tm.text_id, tm.text_details, tm.new_text_id
    FROM textHierarchy AS txtHr 
        JOIN demotexttable AS tm ON tm.text_id = txtHr.new_text_id
    WHERE txtHr.new_text_id IS NOT NULL
)
SELECT * FROM textHierarchy$$;