我正在尝试从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.*;
这有可能吗?除了审计触发器之外,我找不到类似的东西,而那些只是将NEW
和OLD
记录保存为字符串。在这个人为的示例中,随着base
/ sub
表的更改,添加新列或删除它们会很容易,但只要有更多的子表和更多的列,这就变得几乎无法维护。
答案 0 :(得分:0)
就像Craig建议的那样,我最终直接在我的应用程序中解决它,而不是在数据库上。我的应用程序知道视图中的所有相关列以及基类型,因此最终更容易在迁移中创建触发器和视图。