而不是PostgreSQL中的触发器,如何停止重复列名?

时间:2015-09-07 15:31:28

标签: sql postgresql

我正在尝试从PostgreSQL中的实体关系模型创建一个简单的表继承层次结构。

为此,我创建了以下表格:

CREATE TABLE base (
    id integer PRIMARY KEY,
    title varchar(40),
    test integer
);

CREATE TABLE sub (
    id integer REFERENCES base(id) PRIMARY KEY,
    count integer
);

现在,由于在DB上如何解决继承不需要关注应用程序,我还创建了一个应用程序将访问的视图。应用程序中的所有操作都应该在视图上执行,因此,我还需要一个instead of触发器来执行更新,插入和删除。视图定义和触发器如下所示:

CREATE VIEW sub_view AS
    SELECT s.count, b.title, b.test, b.id FROM sub s 
    JOIN base b ON b.id = s.id;

--TRIGGER
CREATE OR REPLACE FUNCTION instead_of_f()
  RETURNS trigger AS
$$
BEGIN
    IF TG_OP = 'INSERT' THEN
        INSERT INTO base(id, title, test) VALUES (NEW.id, NEW.title, NEW.test);
        INSERT INTO sub(id, test) VALUES (NEW.id, NEW.test);
        RETURN NEW;
    ELSIF TG_OP = 'UPDATE' THEN
        UPDATE base SET title = NEW.title, test = NEW.test WHERE id = OLD.id;
        UPDATE sub SET count = NEW.count WHERE id = OLD.id;
        RETURN NEW;
    ELSIF TG_OP = 'DELETE' THEN
        DELETE FROM sub WHERE id = OLD.id;
        DELETE FROM base WHERE id = OLD.id;
        RETURN NULL;
    END IF;
END;
$$ LANGUAGE PLPGSQL;

CREATE TRIGGER instead_of_dml_trig
    INSTEAD OF INSERT OR UPDATE OR DELETE ON
      sub_view FOR EACH ROW 
      EXECUTE PROCEDURE instead_of_f();

这基本上可以正常工作,但是必须一遍又一遍地重复所有列名称,这是乏味且不易维护的。理想情况下,我想为视图编写类似的内容:

CREATE VIEW sub_view AS
   SELECT * FROM sub s JOIN base b ON b.id = s.id;

而不是触发器中的insert语句:

INSERT INTO base VALUES NEW.*;
INSERT INTO sub VALUES NEW.*;

这有可能吗?除了审计触发器之外,我找不到类似的东西,而那些只是将NEWOLD记录保存为字符串。在这个人为的示例中,随着base / sub表的更改,添加新列或删除它们会很容易,但只要有更多的子表和更多的列,这就变得几乎无法维护。

1 个答案:

答案 0 :(得分:0)

就像Craig建议的那样,我最终直接在我的应用程序中解决它,而不是在数据库上。我的应用程序知道视图中的所有相关列以及基类型,因此最终更容易在迁移中创建触发器和视图。