我对postgresql相对较新,并且正在努力熟悉它。我在编写新的pl / sql函数时遇到了错误。 错误:类型“ordered_parts”不存在
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;
答案 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 record
,Declare
阻止var_part record
。
奖励提示:而不是循环查询结果并在每一行上运行RETURN NEXT
,您可以使用RETURN QUERY
将整个结果集投入返回一气呵成。请参阅this Postgres manual page。