3

I am currently learning PostgreSQL and have hit a wall when it comes to stored procedures.

I have an order table with these columns:

OrderId
OrderStatus
OrderTime

I also have an order line table

OrderId
OrderLineId
OrderLineAmount
OrderLineCost

I am trying to write a stored procedure which would create an order and then insert a list of order lines into the second table.

Here is what I have so far:

CREATE OR REPLACE FUNCTION public.createcustomerorder(
_orderstatus integer, 
_ordertimestamp timestamp)
RETURNS int4 AS
$BODY$
  DECLARE 
    last_id int4;
  BEGIN

  INSERT INTO "Order"
    (orderstatus, ordertimestamp)
    VALUES(_orderstatus, _ordertimestamp)
    RETURNING orderid INTO last_id;
RETURN last_id;

END;
$BODY$
LANGUAGE plpgsql;

I am finding it difficult for figure out how I can pass in the parameters, and then how to do the actual insert.

Thanks for your time

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Giulio Ladu
  • 182
  • 2
  • 13

1 Answers1

9

There are several ways to pass a list of records to a function.

Using the simple table for examples, you can to adapt it to your schema:

create table t(id serial primary key, x int, y text);

JSON

create function foo_j(data JSON) returns void language plpgsql as $$
begin
  insert into t(x, y)
  select (d->>'x')::int, (d->>'y')::text
  from json_array_elements(data) as d;
  return;
end $$;

Usage:

select foo_j('[{"x": 1, "y": "a"}, {"x": 2, "y": "b"}]');

Array

To use the array you need to declare the type for its elements. It will contains variable fields for your table, in our example all except id:

create type t_data as (x int, y text);

create function foo_a(data t_data[]) returns void language plpgsql as $$
begin
  insert into t(x, y)
  select d.x, d.y
  from unnest(data) as d;
  return;
end $$;

Usage:

select foo_a(array[(1, 'a'), (2, 'b')]::t_data[]);

Variadic

Almost same but difference in the function declaration and its call:

create function foo_v(variadic data t_data[]) returns void language plpgsql as $$
begin
  insert into t(x, y)
  select d.x, d.y
  from unnest(data) as d;
  return;
end $$;

Usage:

select foo_v((1, 'a'), (2, 'b'));

Documentation:

Abelisto
  • 14,826
  • 2
  • 33
  • 41