VPD 即Virtual Private Databases,提供了对数据库的精密访问控制 (graind access control (FGAC) ),使用VPD,可以在数据记录集定义用户的访问权限。
通过VPD 策略,相当于用户操作数据库中的数据时隐式添加一些条件。比如我们要实现特定角色只能操作数据库表中的特定行的数据,这就可以用 VPD 策略实现。现在以车队长只能操作员工表中的属于他的车队的员工的数据信息为例具体说明:
1. 构造策略函数:
CREATE OR REPLACE FUNCTION "VPD"."FUN_MOTORCADE" (
p_schema in varchar2, p_table in varchar2
)
return varchar2
as
l_retstr varchar2(100);
eid number(5, 0);
did number(5, 0);
begin
if lower(user)<> 'admin'
then
l_retstr := null;
for user_rec in
(
select eid, did
from dpmanager
where loginname = lower(user)
) loop
eid := user_rec.eid;
did := user_rec.did;
end loop;
l_retstr := 'did = ' || did ;--|| 'eid = ' || eid;
return l_retstr;
else
l_retstr := null;
return l_retstr;
end if;
end;
2. 授予执行策略函数的权限:
grant execute on FUN_MOTORCADE to public;
3. 向数据库表添加策略:
Begin
Dbms_Rls.Add_Policy(
Object_Schema =>'admin', --数据表(或视图)所在的Schema名称
Object_Name =>'employee', --数据表(或视图)的名称
Policy_Name =>'motorcade_ply', --POLICY的名称,主要用于将来对Policy的管理
Function_Schema =>'vpd', --返回Where子句的函数所在Schema名称
Policy_Function =>'fun_motorcade', --返回Where子句的函数名称
Statement_Types =>'Select,Insert,Update,Delete', --要使用该Policy的DML类型,如'Select,Insert,Update,Delete'
Update_Check =>True, --仅适用于Statement_Type为'Insert,Update',值为'True'或'False'
Enable =>True --是否启用,值为'True'或'False'
);
end;
最开始不明白策略函数的作用,花了好几天上网查资料才知道原来函数的返回值便是你想往表上加的隐式约束。
比如,你向EMP表添加了下面的策略函数:
CREATE OR REPLACE FUNCTION "VPD"."TEST" (
p_schema in varchar2, p_table in varchar2
)
return varchar2
as
l_retstr varchar2(100);
begin
if user = ‘admin’
then
l_retstr := ‘1 = 1’;
else
l_retstr := ‘1 = 2’;
end if;
return l_retstr;
end;
现在,如果你以admin身份登录执行 ‘SELECT * FROM EMP’ , 则实际执行的是 ‘SELECT * FROM EMP WHERE 1 = 1’ , 其中 ‘1 = 1’ 这个条件是策略函数的返回值;如果你以其他身份登录执行 ‘SELECT * FROM EMP’ , 则实际执行的是 ‘SELECT * FROM EMP WHERE 1 = 2’ 。