将 plpgsql 递归函数翻译回 pg8.1

Posted

技术标签:

【中文标题】将 plpgsql 递归函数翻译回 pg8.1【英文标题】:translate plpgsql recursive function back to pg8.1 【发布时间】:2012-07-24 09:51:12 【问题描述】:

我有以下 plpgsql 函数,它在 pg 8.3 及更高版本上运行良好,但我需要将其转换回 pg 8.1 数据库,我无法缝合以使其正确。

有什么建议吗?我需要摆脱“返回查询”,因为它尚未在 8.1 中引入......

CREATE OR REPLACE FUNCTION specie_children (specie_id INT, self BOOLEAN)
      RETURNS SETOF specie AS
    $BODY$
    DECLARE
      r specie%ROWTYPE;
    BEGIN
      IF self THEN
        RETURN QUERY SELECT * FROM specie WHERE specieid = specie_id;
      END IF;
      FOR r IN SELECT * FROM specie WHERE parent = specie_id
      LOOP
        RETURN NEXT r;
        RETURN QUERY SELECT * FROM specie_children(r.specieid, FALSE);
      END LOOP;
      RETURN;
    END
    $BODY$
    LANGUAGE 'plpgsql';

如何翻译?

【问题讨论】:

也许有这个:***.com/questions/53108/… 您知道 8.1 已死且不受支持吗? 8.3 即将推出。您真的应该继续使用当前版本。 只需使用specie_children 即可完成您对specie 所做的操作。你甚至可以使用相同的变量,因为类型必须匹配。 我知道PG db的支持... Erwin 你这是什么意思?我不会放弃的。 使用相同的LOOPRETURN NEXT r 构造(嵌套)。 @maniek 在他的回答中已经说明了这一点(他使用单独的记录 r2 var 进行循环),但这真的应该很明显吗? (已编辑,最后一部分是错误的。) 【参考方案1】:
RETURN QUERY SELECT * FROM specie_children(r.specieid, FALSE);

可以改写为

for r2 in select * from specie_children(r.specieid, FALSE)
loop
    return next r2
end loop

【讨论】:

我不断收到以下错误:在不能接受集合的上下文中调用集合值函数 @user87400:您必须按照我在示例中显示的方式调用您的函数,SELECT * FROM ... 哎呀,这毕竟是我的问题 ;-) 感谢您的帮助!【参考方案2】:

快速演示。基本上@maniek 已经提供了答案。

测试表:

CREATE TEMP TABLE specie(specieid int, parent int);
INSERT INTO specie VALUES
 (1,0), (2,0), (3,0)
,(11,1), (12,1), (13,1)
,(111,11), (112,11), (113,11);

重写函数:

CREATE OR REPLACE FUNCTION specie_children (specie_id INT, self BOOLEAN)
  RETURNS SETOF specie AS
$BODY$
DECLARE
   r specie%ROWTYPE;
BEGIN
IF self THEN
   FOR r IN SELECT * FROM specie WHERE specieid = $1
   LOOP
      RETURN NEXT r;
   END LOOP;
END IF;

FOR r IN SELECT * FROM specie WHERE parent = $1
LOOP
   RETURN NEXT r;
   FOR r IN SELECT * FROM specie_children(r.specieid, FALSE)
   LOOP
      RETURN NEXT r;
   END LOOP;
END LOOP;

RETURN;
END;
$BODY$
LANGUAGE plpgsql;

呼叫:

SELECT * FROM specie_children (1, true);

返回:

specieid | parent
---------+-------
1        | 0
11       | 1
111      | 11
112      | 11
113      | 11
12       | 1
13       | 1

【讨论】:

以上是关于将 plpgsql 递归函数翻译回 pg8.1的主要内容,如果未能解决你的问题,请参考以下文章

ZF2 从递归 PHP 函数中分离 HTML

Python 函数进阶-递归函数

递归算法

翻译连载 | 第 9 章:递归(上)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

递归

递归