简体   繁体   中英

PL/pgSQL Return SETOF Records Error

I am relatively new to postgresql and battling my way to get familiarized with it. I had run in to an error while writing a new pl/sql function. ERROR: type "ordered_parts" does not exist

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;

just note - your code is perfect example how don't write stored procedure ever. For some longer results it can be extremely slow. Minimally two cycles can be joined to one, or better, you can use just only one RETURN QUERY statement. Next issue is zero formatting of embedded SQL - good length of line is between 70 and 100 chars - writing long SQL statement to one line going to zero readability and maintainability code.

Relation database is not array, and any query has some cost, so don't use nested FOR if you really don't need it. I am sorry for offtopic.

The error message is telling you that you have declared the return type of your function to be SETOF ordered_parts , but it doesn't know what kind of thing ordered_parts is. Within your Declare block you also have a variable declared as this same type ( var_part ordered_parts ).

If you had a table or view called ordered_parts , then its "row type" would be automatically created as a type, but this is not the case here. if you just want to use an arbitrary row from a result set, you can just use the generic type record .

So in this case your function should say RETURNS SETOF record , and your Declare block var_part record .

Bonus tip: rather than looping over the result of your query and running RETURN NEXT on each row, you can use RETURN QUERY to throw the whole result set into the returned set in one go. See this Postgres manual page .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM