用于替换视图插入的规则或触发器

时间:2015-11-22 21:46:50

标签: postgresql triggers views

我有一个可更新的postgres视图,它公开了一个person表。该视图隐藏了一些私人数据,例如电子邮件。插入时我希望用户能够插入该私有数据的值。使用规则或触发器获得此功能会更好吗?

经过一些测试后,似乎我无法使用触发器插入视图中未定义的列。

1 个答案:

答案 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)