标签:
所谓虚拟专用数据库(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 user
USER 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 privileges
ORA-06512: at "SYS.DBMS_SESSION", line 90
ORA-06512: at line 1
SQL> connect oe/oe
SQL> create or replace package sales_app_pkg is
2 procedure set_sales_context;
3 end;
4 /
SQL> create or replace package body sales_app_pkg is
2 procedure set_sales_context is
3 begin
4 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/hr
SQL> 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 is
2 procedure set_sales_context;
3 function where_condition
4 (p_schema_name varchar2,p_tab_name varchar2)
5 return varchar2;
6 end;
7 /
SQL> create or replace package body sales_app_pkg is
2 procedure set_sales_context is
3 v_user varchar2(30);
4 begin
5 dbms_session.set_context(‘sales_ctx‘,‘seller_id‘,user);
6 end;
7
8 function where_condition
9 (p_schema_name varchar2,p_tab_name varchar2) return varchar2 is
10 v_seller_id varchar2(100) := upper(sys_context(‘sales_ctx‘,‘seller_id‘));
11 v_where_condition varchar2(2000);
12 begin
13 if v_seller_id like ‘S%‘ then
14 v_where_condition := ‘seller_id = ‘ || ‘‘‘‘ || v_seller_id || ‘‘‘‘;
15 else
16 v_where_condition := null;
17 end if;
18 return v_where_condition;
19 end;
20 end;
21 /
SQL> connect / as sysdba
SQL> begin
2 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 sysdba
SQL> create or replace trigger set_seller_id_on_logon
2 after logon on DATABASE
3 begin
4 oe.sales_app_pkg.set_sales_context;
5 end;
6 /
SQL> connect oe/oe
SQL> select seller_id,count(*) from sales_list group by seller_id;
SELLER_ID COUNT(*)
--------- ---------
S0010 1067
S0030 968
S0020 1465
SQL> connect s0010/s0010
SQL> select sys_context(‘sales_ctx‘,‘seller_id‘) from dual;
SYS_CONTEXT(‘SALES_CTX‘,‘SELLER_ID‘)
---------------------------------------
S0010
SQL> 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 1
SQL> 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> begin
2 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/hr
SQL> create or replace function hr_col_vpd
2 (p_owner in varchar2,p_obj in varchar2)
3 return varchar2
4 is
5 l_ret varchar2(2000);
6 begin
7 if (p_owner = USER) then
8 l_ret := NULL;
9 else
10 l_ret := ‘1=2‘;
11 end if;
12 return l_ret;
13 end;
14 /
SQL> begin
2 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_rows
10 );
11 end;
12 /
SQL> connect hr/hr
SQL> select employee_id,last_name,salary from hr.employees where rownum<4;
EMPLOYEE_ID LAST_NAME SALARY
----------- ------------- -------
198 OConnell 2600
199 Grant 2600
200 Whalen 4400
SQL> connect oe/oe
SQL> select employee_id,last_name,salary from hr.employees where rownum<4;
EMPLOYEE_ID LAST_NAME SALARY
----------- ------------- -------
198 OConnell
199 Grant
200 Whalen
标签:
原文地址:http://blog.csdn.net/sunansheng/article/details/52587044