4

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

1 Answer 1

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:

Sign up to request clarification or add additional context in comments.

1 Comment

Might get overseen: better also write the create type t_data as (x int, y text); for the variadic block.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.