Plpgsql:非递归类别树函数不返回任何行:(

时间:2015-11-19 17:05:34

标签: sql postgresql plpgsql

所以,这是返回给定类别及其子类别的产品的函数。它是一个3级树。该函数很好,但是当我运行它时,它会返回0行。有什么想法吗?

编辑:parents1和parents2应该是父类别子节点的数组。父母1个孩子1美元,父母2个孩子,所有父母1个节点。

CREATE OR REPLACE FUNCTION ecommerce.select_products_by_category(par bigint)
  RETURNS SETOF ecommerce.product AS
$BODY$ 
declare 
    result ecommerce.product;
    parents bigint[];
    parents2 bigint[];
    i int;
begin 
        parents := array(
        select category_id from ecommerce.category where parent_id = par
        );
        return query select * from ecommerce.product where category_id = par;
        for i in 1..array_upper(parents,1)
        loop 
            return query select * from ecommerce.product where category_id = parents[i];
            raise notice 'p %',parents[i];

        end loop;

        for i in 1..array_upper(parents,1) 
        loop 
            parents2  := array(
            select category_id from ecommerce.category where parent_id = parents[i] 
                );
        end loop;
        for i in 1..array_upper(parents2,1)
        loop 
            return query select * from ecommerce.product where category_id = parents2[i];
            raise notice 'p2 %',parents2[i];

    end loop; 

    --return query theset;

end ; $BODY$

这就是我运行它的方式

SELECT * From ecommerce.select_products_by_category(
    1
);

1 个答案:

答案 0 :(得分:1)

您的代码无法正常工作。表函数的结果与表函数的任何单个CALL有关,而与表函数的全局CALL无关。任何返回递归函数的表都必须使用模式:

CREATE OR REPLACE FUNCTION foo(_parent_id integer)
RETURNS TABLE (node_id integer, node_val, parent_id integer) AS $$
BEGIN
  FOR node_id, node_val, parent_id IN
      SELECT f.node_id, f.node_val, f.parent_id
         FROM footab f
        WHERE f.parent_id = _parent_id
  LOOP
    RETURN NEXT;

    /*
     * Copy result of recursive call to function result
     */
    RETURN QUERY SELECT * FROM foo(node_id);
  END LOOP;
  RETURN;
END;
$$ LANGUAGE plpgsql;

当你使用CTE时,那么你可以更快地获得结果,代码将更具可读性:

WITH RECURSIVE t AS (
     SELECT node_id, node_val, parent_id FROM footab
       WHERE parent_id = <<root_id>>
     UNION ALL
     SELECT node_id, node_val, parent_id FROM footab, t
       WHERE footab.parent_id = t.id
) SELECT * FROM t;