PostgreSQL:使用视图和触发器在多个表中插入元组

PostgreSQL: Inserting tuples in multiple tables using a view and a trigger

我正在尝试构建一个能够插入包含多个项目和金额的复合订单的订单系统。我的数据库布局如下:我有一个 order table,包含一个自动增量 iditem_idamountorder_group_id 列。我还有一个 order_group table 包含一个自动增量 id 和一个 person_id 列。这个想法是,当一个人订购时,一个新的 order_group 条目被创建,并且它的 id 被用作该人已经完成的 orders 中的 fk。

我认为这通常会在应用程序代码中完成。但是,我正在使用 postgrest 为我提供一个 API,这建议创建一个自定义视图以通过该路径插入复合条目。这是描述 here.

这是我目前拥有的:

CREATE FUNCTION kzc.new_order()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
    DECLARE
        group_id int;
    BEGIN
        INSERT INTO kzc.order_group (person) VALUES (new.person) RETURNING id AS group_id;
        INSERT INTO kzc."order" (item, amount, order_group) VALUES (new.item_id, new.amount, group_id);
        RETURN new;
    END;
$$;

CREATE TRIGGER new_order
INSTEAD OF INSERT ON kzc.new_order
FOR EACH ROW
EXECUTE FUNCTION kzc.new_order()

但是,此代码为复合插入中的每个 order 创建一个新的 ordergroup。我怎样才能使我的代码只生成一个新的 ordergroup 条目并将其 id 分配给所有订单?

提前致谢!

我建议您在 new_order 视图中添加一个 order_group_id 列并为其创建一个序列。然后为列创建一个 DEFAULT 值:

ALTER VIEW kzc.new_order
   ALTER order_group_id SET DEFAULT currval('order_group_id_seq');

添加一个 BEFORE INSERT 触发器 FOR EACH STATEMENT,它只为序列调用 nextvalcurrval 调用都将获得相同的生成值。

然后你的触发器中就有了那个数字,可以将它用作 order_group 的主键。

为避免多次添加该行,请使用

INSERT INTO kzc.order_group (id, person)
   VALUES (NEW.order_group_id, NEW.person)
   ON CONFLICT (id) DO NOTHING;