2015-11-22 29 views
0

我有一個可更新的postgres視圖,它暴露了person表。該視圖隱藏了一些私人數據,例如電子郵件。插入時,我希望用戶能夠爲該私人數據插入值。使用規則或觸發器來獲得此功能會更好嗎?規則或觸發器替換視圖插入

經過一些測試,似乎我不能使用觸發器插入未在視圖中定義的列。

回答

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','[email protected]'); 
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) 

當然,它只能在「每個用戶」的基礎上進行。


另一種方法是使用定義爲「安全定義者」的函數。這指定該函數將以創建它的用戶的特權執行。

所以你可以定義一個函數來直接在表中插入數據;定義者必須具有插入特權:

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', '[email protected]'); 
ERROR: permission denied for relation person 

postgres=> select person_insert('foo','bar','[email protected]'); 
people_insert 
--------------- 

(1 row) 

postgres=> select * from person_view; 
first_name | last_name 
------------+----------- 
Foo  | Bar 
(1 row)