我有一个可更新的postgres视图,它公开了一个person
表。该视图隐藏了一些私人数据,例如电子邮件。插入时我希望用户能够插入该私有数据的值。使用规则或触发器获得此功能会更好吗?
经过一些测试后,似乎我无法使用触发器插入视图中未定义的列。
答案 0 :(得分:0)
一种可能的方法是使用权限而不是视图来公开列的子集。
例如,给定表
create table person(
first_name text,
last_name text,
email text
);
您可以向用户授予以下权限:
grant select(first_name, last_name) on person to someuser;
grant insert on person to someuser;
这就是它的工作原理:
postgres=> insert into person values('Foo','Bar','foo@bar.com');
INSERT 0 1
postgres=> select * from person;
ERROR: permission denied for relation person
postgres=> select first_name, last_name from person;
first_name | last_name
------------+-----------
Foo | Bar
(1 row)
当然,只有在“每个用户”的基础上才能实现。
另一种方法是使用定义为“安全定义器”的函数。这指定该函数将使用创建它的用户的权限执行。
所以你可以定义一个函数来直接将数据插入到表中; definer必须具有insert权限:
create function person_insert(first_name text, last_name text, email text)
returns void
security definer
as $$
insert into person(first_name, last_name, email) values ($1, $2, $3);
$$ language sql;
然后其他用户可以在没有插入权限的情况下调用它:
postgres=> insert into person(first_name, last_name, email) values ('foo', 'bar', 'foo@bar.com');
ERROR: permission denied for relation person
postgres=> select person_insert('foo','bar','foo@bar.com');
people_insert
---------------
(1 row)
postgres=> select * from person_view;
first_name | last_name
------------+-----------
Foo | Bar
(1 row)