正如 Jeff French 所指出的,一切都从 PG 9.3 开始工作......除了一些例外(下面的更多信息)。
简单的例子
您可以在 PostgreSQL 上测试此代码。完成后使用级联删除(使用表格删除视图)。
-- create table
--DROP TABLE user_table CASCADE;
CREATE TABLE user_table (
id serial,
lastname varchar(100),
user_type varchar(2) DEFAULT 'nn',
PRIMARY KEY (id)
);
-- initial data
INSERT INTO user_table(lastname) VALUES('Foo');
SELECT * FROM user_table;
-- simple view (note, no id here)
CREATE OR REPLACE VIEW user_view
AS
SELECT lastname, user_type
FROM user_table
;
-- check view (will have initial data)
SELECT * FROM user_view;
-- insert into user_table via view
INSERT INTO user_view VALUES('Bar');
-- check (both will have both records)
SELECT * FROM user_view;
SELECT * FROM user_table;
-- you can run above many times
-- (id will auto-increment even though it is not in the view)
-- update user_table via view
UPDATE user_view SET user_type='v' WHERE lastname = 'Bar';
SELECT * FROM user_table;
限制
不过有一些限制,这取决于你的 PG 版本。
- 在PG 9.3 视图中不能有任何表达式等。也只允许一个表......所以或多或少是一个简单的选择限制、重新排序或重命名列。
- 在PG 9.4 中,视图可以部分更新。所以你可以有表达,但你不能更新它们(至少不是开箱即用的)。
如果你有WHERE
你的观点,那么你可能会得到一些奇怪的结果。所以这仍然适用于插入:
CREATE OR REPLACE VIEW user_view
AS
SELECT lastname as last_name, user_type
FROM user_table
WHERE user_type = 'v'
;
INSERT INTO user_view VALUES('Bar');
但更新可能不起作用。至少这不起作用,因为它将更新 0 行:
UPDATE user_view SET user_type='v';
因为实际上这将等同于以下查询(如果您考虑一下,这很有意义):
UPDATE user_view SET user_type='v' WHERE user_type = 'v';
我想知道他们是否会在某个时候支持联接...但是在撰写本文时,PG 14 已经发布,并且它不支持在视图中加入表格(我的意思是更新)。
备择方案
您仍然可以使用INSTEAD OF
触发器,尤其是对于更复杂的视图。而且您可以使用规则...但是(如CREATE RULE 文档中所述)自动更新的视图将比手动创建的规则更快。