LinuxOracleWf 2012-11-03
环境:
sys@ORCL> select * from v$version where rownum=1;  
  
BANNER  
----------------------------------------------------------------   
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod  
  
sys@ORCL> !uname -a  
Linux localhost.localdomain 2.6.18-308.el5xen #1 SMP Fri Jan 27 17:59:00 EST 2012 i686 i686 i386 GNU/Linux
实验过程如下:
scott@ORCL> create table tvpd (name varchar2(20),salary number(8,2),department_id number(5));  
  
Table created.  
  
scott@ORCL> insert into tvpd values('张三',5000,10);  
  
1 row created.  
  
scott@ORCL> insert into tvpd values('李四',250,20);  
  
1 row created.  
  
scott@ORCL> commit;  
  
Commit complete.  
  
  
sys@ORCL> grant connect to zhangsan identified by zhangsan;  
  
Grant succeeded.  
  
sys@ORCL> grant select on scott.tvpd to zhangsan;  
  
Grant succeeded.  
  
sys@ORCL> grant connect to lisi identified by lisi;  
  
Grant succeeded.  
  
sys@ORCL> grant select on scott.tvpd to lisi;  
  
Grant succeeded.  
  
sys@ORCL> conn zhangsan/zhangsan  
Connected.  
zhangsan@ORCL> select * from scott.tvpd;  
  
NAME                     SALARY DEPARTMENT_ID  
-------------------- ---------- -------------   
张三                       5000            10  
李四                        250            20  
  
zhangsan@ORCL> conn scott/tiger  
Connected.  
scott@ORCL> create or replace function func_vpd  
(owner varchar2,objname varchar2)  
return varchar2  
is  
  v_where_clause varchar2(2000);  
begin  
  v_where_clause :='name=initcap(sys_context(''userenv'',''session_user''))';  
  return v_where_clause;  
end;  2    3    4    5    6    7    8    9    
 10  /  
  
Function created.  
  
scott@ORCL> conn / as sysdba  
Connected.  
sys@ORCL> select * from dba_policies where object_owner='SCOTT';  
  
no rows selected  
  
sys@ORCL> BEGIN  
  dbms_rls.add_policy(object_schema => 'SCOTT',  
  object_name => 'TVPD',  
  policy_name => 'scott_policy123',  
  function_schema =>'SCOTT',  
  policy_function => 'func_vpd',  
  statement_types  =>'select',  
  sec_relevant_cols=>'salary');  
END;  2    3    4    5    6    7    8    9    
 10  /  
  
PL/SQL procedure successfully completed.  
  
sys@ORCL> select * from dba_policies where object_owner='SCOTT';  
  
OBJECT_OWNER                   OBJECT_NAME                    POLICY_GROUP  
------------------------------ ------------------------------ ------------------------------   
POLICY_NAME                    PF_OWNER                       PACKAGE  
------------------------------ ------------------------------ ------------------------------   
FUNCTION                       SEL INS UPD DEL IDX CHK ENA STA POLICY_TYPE              LON  
------------------------------ --- --- --- --- --- --- --- --- ------------------------ ---   
SCOTT                          TVPD                           SYS_DEFAULT  
SCOTT_POLICY123                SCOTT  
FUNC_VPD                       YES NO  NO  NO  NO  NO  YES NO  DYNAMIC                  NO  
scott@ORCL> conn zhangsan/zhangsan  
Connected.  
zhangsan@ORCL> select * from scott.tvpd;  
  
no rows selected  
  
zhangsan@ORCL> select name from scott.tvpd;  
  
NAME  
--------------------   
张三  
李四 
在本测试中,我们只是对列salary作精细化控制,如果不查工资还是可以全部看到的,正如上面所示。
但是请注意,sys仍然不受影响,因为他有个权限叫“exempt access policy”,这个的性质和sysdba一样。
zhangsan@ORCL> conn / as sysdba  
Connected.  
sys@ORCL> grant exempt access policy to zhangsan;  
  
Grant succeeded.  
  
sys@ORCL> conn zhangsan/zhangsan  
Connected.  
zhangsan@ORCL> select * from scott.tvpd;  
  
NAME                     SALARY DEPARTMENT_ID  
-------------------- ---------- -------------   
张三                       5000            10  
李四                        250            20 
同时,受策略保护的表若被drop是不进recyclebin,也就无法用flashback ... to before drop。
zhangsan@ORCL> conn scott/tiger  
Connected.  
scott@ORCL> show recyclebin  
scott@ORCL> drop table tvpd;  
  
Table dropped.  
  
scott@ORCL> show recyclebin  
scott@ORCL> flashback table tvpd to before drop;  
flashback table tvpd to before drop  
*  
ERROR at line 1:  
ORA-38305: object not in RECYCLE BIN