将plpgsql递归函数转换回pg8.1

时间:2012-07-24 09:51:12

标签: postgresql recursion plpgsql

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

任何提示?我需要摆脱" RETURN QUERY"因为它还没有在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';

我该如何翻译?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

快速演示。基本上@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