如何通过多个表的视图隐式插入SERIAL ID

时间:2013-08-13 13:44:39

标签: postgresql

我有两个表,通过is-relation连接在E / R中。一个代表“母亲表”

CREATE TABLE PERSONS(
      id                SERIAL NOT NULL,
      name              character varying NOT NULL,
      address           character varying NOT NULL,
      day_of_creation   timestamp NOT NULL DEFAULT current_timestamp,
      PRIMARY KEY (id)
)

另一个代表“子表”

CREATE TABLE EMPLOYEES (
      id               integer NOT NULL,
      store            character varying NOT NULL,
      paychecksize     integer NOT NULL,
      FOREIGN KEY (id)
              REFERENCES PERSONS(id),
      PRIMARY KEY (id)
)

现在这两个表在一个视图中加入

CREATE VIEW EMPLOYEES_VIEW AS
    SELECT 
       P.id,name,address,store,paychecksize,day_of_creation
    FROM 
       PERSONS AS P
    JOIN
       EMPLOYEES AS E ON P.id = E.id

我想写一个规则或一个触发器来让db用户在该视图上插入一个插件,将分裂列的讨厌细节留给不同的表。

但是我也想让它变得方便,因为id是SERIAL而day_of_creation有一个默认值,用户不需要提供那些,因此像

这样的语句
INSERT INTO EMPLOYEES_VIEW (name, address, store, paychecksize)
VALUES ("bob", "top secret", "drugstore", 42)

应该足以导致

PERSONS

id|name|address   |day_of_creation
-------------------------------
1 |bob |top secret| 2013-08-13 15:32:42

EMPLOYEES

id|   store |paychecksize
---------------------
1 |drugstore|42

基本规则很容易

CREATE RULE EMPLOYEE_VIEW_INSERT AS ON INSERT TO EMPLOYEE_VIEW
DO INSTED (
    INSERT INTO PERSONS
    VALUES (NEW.id,NEW.name,NEW.address,NEW.day_of_creation),
    INSERT INTO EMPLOYEES
    VALUES (NEW.id,NEW.store,NEW.paychecksize)
)

应该足够了。但这不方便,因为用户必须提供id和时间戳,即使实际上没有必要。

如何重写/扩展该代码库以符合我的便利标准?

1 个答案:

答案 0 :(得分:1)

类似的东西:

CREATE RULE EMPLOYEE_VIEW_INSERT AS ON INSERT TO EMPLOYEES_VIEW
DO INSTEAD 
(
    INSERT INTO PERSONS (id, name, address, day_of_creation)
    VALUES (default,NEW.name,NEW.address,default);
    INSERT INTO EMPLOYEES (id, store, paychecksize)
    VALUES (currval('persons_id_seq'),NEW.store,NEW.paychecksize)
);

这样,persons.idpersons.day_of_creation的默认值将成为默认值。另一种选择是简单地从插入中删除这些列:

INSERT INTO PERSONS (name, address)
VALUES (NEW.name,NEW.address);

定义规则后,以下插入应该有效:

insert into employees_view (name, address, store, paychecksize)
values ('Arthur Dent', 'Some Street', 'Some Store', 42);

顺便说一下:使用当前的Postgres版本,instead of触发器是使视图可更新的首选方法。