所谓虚拟专用数据库(VPD)指的是,通过在数据库里进行配置,从而让不同的用户只能查看某 个表里的部分数据。VPD分为以下两个级别。
Select * from sales_list ;
Select * from sales_list where seller_id=‘S0020‘;
Select * from sales_list where values>1000 ;
Select * from sales_list where qty_sold>1000 and seller_id=‘S0020‘;
SQL> select sys_context(‘userenv‘,‘ip_address‘) "IP",sys_context(‘userenv‘,‘db_name‘) "DB" from dual;IP DB--------------- ---------152.68.32.60 ora10g
SQL> create or replace context sales_ctx using oe.sales_app_pkg;
SQL> drop context sales _ctx;
dbms_session.set_context (‘context_name‘, ‘attribute_name‘, ‘attribute_value‘)
SQL> show userUSER is "SYS"SQL> exec dbms_session.set_context(‘sales_ctx‘,‘seller_id‘,‘S0020‘);BEGIN dbms_session.set_context(‘sales_ctx‘,‘seller_id‘,‘S0020‘); END;*ERROR at line 1:ORA-01031: insufficient privilegesORA-06512: at "SYS.DBMS_SESSION", line 90ORA-06512: at line 1
SQL> connect oe/oeSQL> create or replace package sales_app_pkg is2 procedure set_sales_context;3 end;4 /SQL> create or replace package body sales_app_pkg is2 procedure set_sales_context is3 begin4 dbms_session.set_context(‘sales_ctx‘,‘seller_id‘,user);5 end;6 end;7 /SQL> grant select on sales_list to public;SQL> grant update on sales_list to public;SQL> grant execute on sales_app_pkg to public;
SQL> connect hr/hrSQL> exec oe.sales_app_pkg.set_sales_context;SQL> select sys_context(‘sales_ctx‘,‘seller_id‘) from dual;SYS_CONTEXT(‘SALES_CTX‘,‘SELLER_ID‘)--------------------------------------------------------------------------------HR
SQL> create or replace package sales_app_pkg is2 procedure set_sales_context;3 function where_condition4 (p_schema_name varchar2,p_tab_name varchar2)5 return varchar2;6 end;7 /SQL> create or replace package body sales_app_pkg is2 procedure set_sales_context is3 v_user varchar2(30);4 begin5 dbms_session.set_context(‘sales_ctx‘,‘seller_id‘,user);6 end;78 function where_condition9 (p_schema_name varchar2,p_tab_name varchar2) return varchar2 is10 v_seller_id varchar2(100) := upper(sys_context(‘sales_ctx‘,‘seller_id‘));11 v_where_condition varchar2(2000);12 begin13 if v_seller_id like ‘S%‘ then14 v_where_condition := ‘seller_id = ‘ || ‘‘‘‘ || v_seller_id || ‘‘‘‘;15 else16 v_where_condition := null;17 end if;18 return v_where_condition;19 end;20 end;21 /
SQL> connect / as sysdbaSQL> begin2 dbms_rls.add_policy(3 OBJECT_SCHEMA=>‘oe‘,4 OBJECT_NAME=>‘sales_list‘,5 POLICY_NAME=>‘oe_sales_list_fgac‘,6 FUNCTION_SCHEMA=>‘oe‘,7 POLICY_FUNCTION=>‘sales_app_pkg.where_condition‘,8 STATEMENT_TYPES=>‘select,update‘,9 UPDATE_CHECK=>true,10 ENABLE=>true);11 end;12 /
SQL> connect / as sysdbaSQL> create or replace trigger set_seller_id_on_logon2 after logon on DATABASE3 begin4 oe.sales_app_pkg.set_sales_context;5 end;6 /
SQL> connect oe/oeSQL> select seller_id,count(*) from sales_list group by seller_id;SELLER_ID COUNT(*)--------- ---------S0010 1067S0030 968S0020 1465
SQL> connect s0010/s0010SQL> select sys_context(‘sales_ctx‘,‘seller_id‘) from dual;SYS_CONTEXT(‘SALES_CTX‘,‘SELLER_ID‘)---------------------------------------S0010SQL> select seller_id,count(*) from oe.sales_list group by seller_id;SELLER_ID COUNT(*)--------- ---------S0010 1067
SQL> select seller_id,qty_sold from oe.sales_list where id=300;SELLER_ID QTY_SOLD--------- --------S0010 1SQL> update oe.sales_list set seller_id=‘S0020‘ where id=300;update oe.sales_list set seller_id=‘S0020‘ where id=300*ERROR at line 1:ORA-28115: policy with check option violation
SQL> begin2 dbms_rls.drop_policy(3 OBJECT_SCHEMA=>‘oe‘,4 OBJECT_NAME=>‘sales_list‘,5 POLICY_NAME=>‘oe_sales_list_fgac‘);6 end;7 /
SQL> connect hr/hrSQL> create or replace function hr_col_vpd2 (p_owner in varchar2,p_obj in varchar2)3 return varchar24 is5 l_ret varchar2(2000);6 begin7 if (p_owner = USER) then8 l_ret := NULL;9 else10 l_ret := ‘1=2‘;11 end if;12 return l_ret;13 end;14 /
SQL> begin2 dbms_rls.add_policy(object_schema=>‘hr‘,3 object_name=>‘employees‘,4 policy_name=>‘hr_emp_col_policy‘,5 function_schema=>‘hr‘,6 policy_function=>‘hr_col_vpd‘,7 statement_types=>‘select‘,8 sec_relevant_cols=>‘salary‘,9 sec_relevant_cols_opt => dbms_rls.all_rows10 );11 end;12 /
SQL> connect hr/hrSQL> select employee_id,last_name,salary from hr.employees where rownum<4;EMPLOYEE_ID LAST_NAME SALARY----------- ------------- -------198 OConnell 2600199 Grant 2600200 Whalen 4400
SQL> connect oe/oeSQL> select employee_id,last_name,salary from hr.employees where rownum<4;EMPLOYEE_ID LAST_NAME SALARY----------- ------------- -------198 OConnell199 Grant200 Whalen
原文:http://blog.csdn.net/sunansheng/article/details/52587044