2016-09-20 5 views
2
create table public.orders (
    orderID serial PRIMARY KEY, 
    orderdate timestamp NOT NULL 
); 

create table public.orderdetails (
    orderdetailID serial PRIMARY KEY, 
    orderID integer REFERENCES public.orders(orderID), 
    item varchar(20) NOT NULL, 
    quantity INTEGER NOT NULL 
); 

私は(上記のように非常に単純化された)テーブルを持っています。このテーブルには、注文の詳細と注文の詳細を1つのアクションで挿入します。Postgres 2つのテーブルに複数のレコードを挿入する機能

私は取引に精通していて、以下のようなSQLコマンドを使用してデータを挿入できます。しかし、理想的な私ではなく、機能可能であれば上記のようなクエリを持っているしたいと思います

DO $$ 
    DECLARE inserted_id integer; 
    BEGIN 
    INSERT INTO public.orders(orderdate) VALUES (NOW()) RETURNING orderID INTO inserted_id; 

    INSERT INTO public.orderdetails(orderID, item, quantity) 
    VALUES (inserted_id, 'Red Widget', 10), 
      (inserted_id, 'Blue Widget', 5); 
    END 
$$ LANGUAGE plpgsql; 

私のアプリケーション内に格納されています。

postgres関数に複数のレコードを提供するという正しい方向に私を指摘できますか?あるいは、私がやろうとしていることが悪い習慣とみなされている場合は、私が他のどのルートに従うべきかを教えてください。

ありがとうございます。

+0

この種の関係、なぜ 'orderdetails'テーブルの必要性? 1つのテーブルを使用し、トランザクションに問題はありません – ad4s

+0

HI ad4s、 注文テーブルに注文日、出荷日、配送先住所などのものがありますが、orderdetailsテーブルには内訳があります注文したもののアイテムごとのアイテム。 – Devasta

+0

おそらくこれは助けるかもしれないhttp://stackoverflow.com/questions/6822460/getting-an-id-inside-a-postgresql-transaction-block – ad4s

答えて

4

タプルの配列を使用して、複数の行を関数に渡すことができます。関数の引数のために、このタイプの

create type order_input as (
    item text, 
    quantity integer); 

使用アレー:カスタムタイプを必要とする

create or replace function insert_into_orders(order_input[]) 
returns void language plpgsql as $$ 
declare 
    inserted_id integer; 
begin 
    insert into public.orders(orderdate) 
    values (now()) 
    returning orderid into inserted_id; 

    insert into public.orderdetails(orderid, item, quantity) 
    select inserted_id, item, quantity 
    from unnest($1); 
end $$; 

使用法:私は本当に持つのポイントを得ることはありません

select insert_into_orders(
    array[ 
     ('Red Widget', 10), 
     ('Blue Widget', 5) 
    ]::order_input[] 
); 

select * from orderdetails; 

orderdetailid | orderid | item  | quantity 
---------------+---------+-------------+---------- 
      1 |  1 | Red Widget |  10 
      2 |  1 | Blue Widget |  5 
(2 rows) 
+0

それは完璧に働いた、感謝klin。 :) – Devasta

関連する問題