2017-01-11 34 views
2

外部キーでリンクされたテーブルにデータ挿入の問題があります。私はいくつかの場所で、このような状況に役立つ "with"コマンドがあることを読みましたが、どのように使用されているかはよく分かりません。PostgreSQL - 複数のテーブルに同時にデータを挿入する

レコードを作成するために使用される4つのテーブルをまとめておきますが、すべてのデータが一度に1つのクエリで挿入され、最後のテーブルに関連付けられていますので、相談。ここでは、テーブルを作成するためのコードは次のとおりです。

CREATE TABLE participante 
    (
     id serial NOT NULL, 
     nome character varying(56) NOT NULL, 
     CONSTRAINT participante_pkey PRIMARY KEY (id), 
    ); 

    CREATE TABLE venda 
    (
     id serial NOT NULL, 
     inicio date NOT NULL, 
     CONSTRAINT venda_pkey PRIMARY KEY (id) 
    ); 

    CREATE TABLE item 
    (
     id serial NOT NULL, 
     nome character varying(256) NOT NULL, 
     CONSTRAINT item_pkey PRIMARY KEY (id) 
    ); 


    CREATE TABLE lances_vendas 
    (
     id serial NOT NULL, 
     venda_id integer NOT NULL, 
     item_id integer NOT NULL, 
     participante_id integer NOT NULL, 
     valor numeric NOT NULL, 
     CONSTRAINT lance_vendas_pkey PRIMARY KEY (id), 
     CONSTRAINT lances_vendas_venda_id_fkey FOREIGN KEY (venda_id) 
     REFERENCES venda (id), 
     CONSTRAINT lances_vendas_item_id_fkey FOREIGN KEY (item_id) 
     REFERENCES item (id), 
     CONSTRAINT lances_vendas_participante_id_fkey FOREIGN KEY (participante_id) 
     REFERENCES participante (id) 
    ); 

答えて

4
WITH par_key AS 
     (INSERT INTO participante (nome) VALUES ('Laurenz') RETURNING id), 
    ven_key AS 
     (INSERT INTO venda (inicio) VALUES (current_date) RETURNING id), 
    item_key AS 
     (INSERT INTO item (nome) VALUES ('thing') RETURNING id) 
INSERT INTO lances_vendas (venda_id, item_id, participante_id, valor) 
    SELECT ven_key.id, item_key.id, par_key.id, numeric '3.1415' 
    FROM par_key, ven_key, item_key; 
0

私はあなたが単一のクエリを要求したことを知っているが、あなたはまだトランザクションを使用して検討する必要があります。

BEGIN; 
INSERT INTO participante (nome) VALUES ('Laurenz'); 
INSERT INTO venda (inicio) VALUES (current_date); 
INSERT INTO item (nome) VALUES ('thing'); 
INSERT INTO lances_vendas (venda_id, item_id, participante_id, valer) 
VALUES (currval('venda_id_seq'), currval('item_id_seq'), currval('participante_id_seq'), 3.1415); 
COMMIT; 

トランザクションがあることを保証しますparticipante、venda、およびitem内の新しい行は、currval( 'X')の値を変更しません。

+1

配列この例を見てみますトランザクションではないため、ここでトランザクションに頼るのは安全ではありません。 – fpietka

+0

どうして危険ですか? nextval()の副作用はトランザクションの外ですぐに見ることができるので、その結果を使用するのが安全であると思われます。 –

+0

以下の説明は、あなたのことをより明確にするかもしれません:p http://stackoverflow.com/questions/2095917/sequences-not-affected-by-transactions –

0

そのジョブを実行する関数を作成することができます。 address(最初の挿入)のために生成さUUIDperson -record(第2のインサート)で使用される方法

CREATE OR REPLACE FUNCTION import_test(p_title character varying, p_last_name character varying, p_first_name character varying, p_house_num integer, p_street character varying, p_zip_code character varying, p_city character varying, p_country character varying) 
RETURNS integer 
LANGUAGE plpgsql 
AS 
$body$ 
DECLARE 

    address_id uuid; 
    parent_id uuid; 
    ts timestamp; 

BEGIN 

    address_id := uuid_generate_v4(); 
    parent_id := uuid_generate_v4(); 
    ts := current_timestamp; 

    insert into address (id, number, street, zip_code, city, country, date_created) values (address_id, p_house_num, p_street, p_zip_code, p_city, p_country, ts); 
    insert into person (id, title, last_name, first_name, home_address, date_created) values (parent_id, p_title, p_last_name, p_first_name, address_id, ts); 

RETURN 0; 
END; 
$body$ 
VOLATILE 
COST 100; 

COMMIT; 

使用:

SELECT import_test('MR', 'MUSTERMANN', 'Peter', '[email protected]', 54, 'rue du Soleil', '1234', 'Arlon', 'be'); 
SELECT import_test('MS', 'MUSTERMANN', 'Peter 2', '[email protected]', 55, 'rue de la Lune', '56789', 'Amnéville', 'fr'); 
関連する問題