PL / pgSQL返回SETOF记录错误

时间:2013-05-29 17:34:24

标签: sql postgresql plpgsql

我对postgresql相对较新,并且正在努力熟悉它。我在编写新的pl / sql函数时遇到了错误。 错误:类型“ordered_pa​​rts”不存在

CREATE OR REPLACE FUNCTION get_ordered_parts(var_bill_to integer)
  RETURNS SETOF ordered_parts AS
$BODY$
declare

    var_ordered_id record;
    var_part ordered_parts;

begin

    for var_ordered in select order_id from view_orders where bill_to = var_bill_to
    loop

        for var_part select os.po_num,os.received,os.customer_note,orders.part_num,orders.description,orders.order_id,orders.remaining_quantity from (select vli.part_num,vli.description,vli.order_id,vli.quantity - vli.quantity_shipped as remaining_quantity from view_line_items as vli where vli.order_id in (select order_id from view_orders where bill_to = var_bill_to and order_id = var_ordered.order_id) and vli.quantity - vli.quantity_shipped > 0)as orders left join order_sales as os on orders.order_id = os.order_id
        then

            -- Then we've found a leaf part
            return next var_part;

        end if;

    end loop;

end;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100
  ROWS 1000;
ALTER FUNCTION get_ordered_parts(integer) OWNER TO postgres;

2 个答案:

答案 0 :(得分:2)

请注意 - 您的代码是完美的示例,如何不编写存储过程。对于一些更长的结果,它可能非常慢。最少两个循环可以连接到一个或更好,您只能使用一个RETURN QUERY语句。下一个问题是嵌入式SQL的零格式化 - 良好的行长度在70到100个字符之间 - 将长SQL语句写入一行,使可读性和可维护性代码为零。

Relation数据库不是数组,任何查询都有一些成本,所以如果你真的不需要它,不要使用嵌套的FOR。对于offtopic我很抱歉。

答案 1 :(得分:1)

错误消息告诉您已将函数的返回类型声明为SETOF ordered_parts,但它不知道ordered_parts是什么类型的事物。在Declare块中,您还有一个声明为同一类型的变量(var_part ordered_parts)。

如果你有一个名为ordered_parts的表或视图,那么它的“行类型”将自动创建为一个类型,但这不是这里的情况。如果您只想使用结果集中的任意行,则可以使用泛型类型record

因此,在这种情况下,您的函数应该说RETURNS SETOF recordDeclare阻止var_part record

奖励提示:而不是循环查询结果并在每一行上运行RETURN NEXT,您可以使用RETURN QUERY将整个结果集投入返回一气呵成。请参阅this Postgres manual page