使用函数处理嵌套插入

时间:2014-03-12 11:51:14

标签: sql postgresql-9.3

大家好我需要一些帮助来决定插入表'shop'的最佳方法,该表有一个序列号字段。我还需要插入表'shopbranch'和'shopproperties',它们都引用shop.id。

简而言之,我需要插入一个商店记录。然后是下表中每个表的两条记录,shopproperty和shopbranch,其shopid(FK)引用刚刚创建的shop.id字段

我看到某个地方我可以将'shop'插件包裹在一个名为'insert_shop'的函数中,该函数可以“购买”商店'使用select语句

插入并返回其id

然后在插入shoproperty和shopbranch记录的另一个函数中,我可以调用insert_shop函数来返回商店ID,该商店ID可以作为记录的商店ID传递。

如果我以正确的方式看待这件事,我可以告诉我,因为我是新手。

1 个答案:

答案 0 :(得分:1)

解决此问题的一种方法是在三个表上创建一个视图,显示可以插入或更新的所有三个表中的所有列。然后,如果您在视图上创建INSTEAD OF INSERT触发器,则可以像操作表一样操作视图内容。您可以对UPDATE执行相同操作,甚至将两者合并为INSTEAD OF INSERT OR UPDATE触发器。然后,您的触发器调用的函数有三个INSERT语句,用于将视图上的插入重定向到基础表:

CREATE TABLE shop (
  id serial PRIMARY KEY,
  nm text,
  ...
);

CREATE TABLE shopbranch (
  id serial PRIMARY KEY,
  shop integer NOT NULL REFERENCES shop,
  branchcode text,
  loc text,
  ...
);

CREATE TABLE shopproperties (
  id serial PRIMARY KEY,
  shop integer NOT NULL REFERENCES shop,
  prop1 text,
  prop2 text,
  ...
);

CREATE VIEW shopdetails AS
  SELECT s.*, b.*, p.*
  FROM shop s, shopbranch b, shopproperties p,
  WHERE b.shop = s.id AND p.shop = s.id;

CREATE FUNCTION shopdetails_insert() RETURNS trigger AS $$
DECLARE
  shopid integer;
BEGIN
  INSERT INTO shop (nm, ...) VALUES (NEW.nm, ...) RETURNING id INTO shopid;
  IF NOT FOUND
    RETURN NULL;
  END;
  INSERT INTO shopbranch (shop, branchcode, loc, ...) VALUES (shopid, NEW.branchcode, NEW.loc, ...);
  INSERT INTO shopproperties(shop, prop1, prop2, ...) VALUES (shopid, NEW.prop1, NEW.prop2, ...);
  RETURN NEW;
END; $$ LANGUAGE plpgsql;

CREATE TRIGGER shopdetails_trigger_insert
  INSTEAD OF INSERT
  FOR EACH ROW EXECUTE PROCEDURE shopdetails_insert();

您当然可以使用视图并仅显示可插入或更新的三个表中的列(例如排除主键和外键)。