PostgreSQL - 同时将数据插入多个表

时间:2017-01-11 15:42:32

标签: sql postgresql

我在通过外键链接的表中遇到数据插入问题。我在某些地方读到有一个" with"在这些情况下有帮助的命令,但我不太明白它是如何使用的。

我想将用于制作记录的四个表放在一起,但是,所有数据一次插入,在一个查询中,并且它们与最后一个表相关联,以便于将来的咨询。以下是创建表的代码:

    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)
    );

3 个答案:

答案 0 :(得分:6)

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;

答案 1 :(得分:1)

我知道您请求了一个查询,但您可能仍想考虑使用交易:

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;

事务确保参与者,文件和项目中的任何新行都保持currval(' X')的值不变。

答案 2 :(得分:0)

您可以创建一个功能来完成这项工作。看一下这个例子:

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;

请注意UUID - 记录(第二次插入)

address(第一次插入)生成的person如何使用

用法:

SELECT import_test('MR', 'MUSTERMANN', 'Peter', 'john2@doe.com', 54, 'rue du Soleil', '1234', 'Arlon', 'be');
SELECT import_test('MS', 'MUSTERMANN', 'Peter 2', 'peter2@yahoo.com', 55, 'rue de la Lune', '56789', 'Amnéville', 'fr');