2015-11-19 61 views
0

所以,這裏是返回給定類別及其子類別的產品的函數,它是一個3級樹,函數很好,但是當我運行它,它說0行返回的任何想法Plpgsql:非遞歸類別樹函數不返回任何行:(

編輯:。?。PARENTS1和PARENTS2應該是父類的兒童陣列$ 1 PARENTS1孩子,和所有PARENTS1節點PARENTS2兒童

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

爲什麼AREN」你只需使用遞歸公用表表達式? http://www.postgresql.org/docs/current/static/queries-with.html –

回答

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;