这是一个更加灵活的视图,该视图可以授权给所有的用户,该视图的内容会随着用户角色的不同而不同。
使用 VPD。 Oracle 数据库 10g 中引入的新特性使 VPD 更加有用: 创建视图是没有必要的。 相反,VPD 策略可能抑制显示。 这里,VPD 策略函数和以下类似: 1 create or replace function pd_pol
2 (
3 p_schema in varchar2,
4 p_obj in varchar2
5 )
6 return varchar2
7 is
8 l_ret varchar2(2000);
9 begin
10 if (p_schema = USER) then
11 l_ret := NULL;
12 else
13 l_ret := '1=2';
14 end if;
15 return l_ret;
16 end;
现在构建策略函数: 1 begin
2 dbms_rls.add_policy (
3 object_schema => 'ARUP',
4 object_name => 'PATIENT_DIAGNOSIS',
5 policy_name => 'PD_POL',
6 policy_function => 'PD_POL',
7 statement_types => 'SELECT',
8 update_check => TRUE,
9 sec_relevant_cols => 'DIAGNOSIS_CODE',
10 sec_relevant_cols_opt => dbms_rls.all_rows
11 );
12 end;
注意行号 9 和 10。在第 9 行中,我们提及将列 DIAGNOSIS_CODE 作为敏感列。 在第 10 行中,我们指出如果选择了该列,VPD 显示所有列;但是该列值却显示为 NULL。 这就有效地屏蔽了该列。 在策略函数中,请注意如果表的所有者进行选择,应用的谓词为 NULL。因此,VPD 限制就不被应用,列也不显示。
请记住,没有“更换”策略的方法。 如果旧策略还存在,您必须首先抛弃旧策略。 begin
dbms_rls.drop_policy (
object_schema => 'ARUP',
object_name => 'PATIENT_DIAGNOSIS',
policy_name => 'PD_POL'
);
end;
现在,您可以进行测试。 SQL> conn arup/arup
Connected.
SQL> select * from patient_diagnosis;
PATIENT_ID DIAGNOSIS_ID DI DOCTOR_ID BILLING_CODE
---------- ------------ -- ---------- ------------
1 1 01 1 1003
1 2 02 1 1003
1 3 11 1 1003
2 1 11 1 1005
2 2 41 2 1005
注意:DIAGNOSIS_CODE 列值显示出来了,因为 ARUP 是表的所有者,ARUP 应该看得到这些值。 现在,以对该表有选择权限的另一名用户身份进行连接,执行相同的查询。 SQL> set null ?
SQL> conn ananda/ananda
SQL> select * from arup.patient_diagnosis;
PATIENT_ID DIAGNOSIS_ID D DOCTOR_ID BILLING_CODE
---------- ------------ - ---------- ------------
1 1 ? 1 1003
1 2 ? 1 1003
1 3 ? 1 1003
2 1 ? 1 1005
2 2 ? 2 1005
注意列 DIAGNOSIS_CODE 是如何显示所有空值的。
除了不需要在表上创建视图,不需要创建同义词指向该视图,不需要维护额外的授权之外,该方法是更加优秀的。 如果您需要拥有不同的策略把该值显示给不同的人,您可以很容易地修改策略函数(第 11 行)添加更多的检查。 例如,您的策略可以是:所有用户都可以看到敏感性不强的诊断代码(例如普通感冒)。 因此,您的策略函数和下面的类似,假设一般性感冒的 DIAGNOSIS_CODE 为“01”。 1 create or replace function pd_pol
2 (
3 p_schema in varchar2,
4 p_obj in varchar2
5 )
6 return varchar2
7 is
8 l_ret varchar2(2000);
9 begin
10 if (p_schema = USER) then
11 l_ret := NULL;
12 else
13 l_ret := 'diagnosis_code=''01''';
14 end if;
15 return l_ret;
16* end;
注意:仅当诊断代码为“01”而不是其它时,我们在第 13 行添加要显示的额外谓词。 现在进行测试。 SQL> conn arup/arup
Connected.
SQL> select * from arup.patient_diagnosis;
PATIENT_ID DIAGNOSIS_ID DI DOCTOR_ID BILLING_CODE
---------- ------------ -- ---------- ------------
1 1 01 1 1003
1 2 02 1 1003
1 3 11 1 1003
2 1 11 1 1005
2 2 41 2 1005
SQL> conn ananda/ananda
Connected.
SQL> select * from arup.patient_diagnosis;
PATIENT_ID DIAGNOSIS_ID DI DOCTOR_ID BILLING_CODE
---------- ------------ -- ---------- ------------
1 1 01 1 1003
1 2 ? 1 1003
1 3 ? 1 1003
2 1 ? 1 1005
2 2 ? 2 1005
(编辑:aniston)
|