1.是什么?
context是与session绑定,保存在服务器端的信息。类似web的session。
dbms_session是在plsql中alter session、set role和其他方法的系统程序包。
2.为什么?
貌似知识点比较冷门,没想到必须用的场景;目前遇到的1个实际场景是在拼动态sql,但和常规方法区别不大。
只能参考别人的用法,见chapter4.
3.如何做?
1.创建context
create context mycontext using pkg_context_test;
2.创建修改context的sp
为了保证安全,context只允许通过提前制定sp访问。
create or replace package body pkg_context_test is
procedure sp_set(is_val varchar2) as
begin
dbms_session.set_context('mycontext','par1',is_val);
end;
procedure sp_set(is_val varchar2, is_user varchar2) as
begin
dbms_session.set_context(namespace =>'mycontext',
attribute =>'par_user',
value =>is_val,
username =>is_user);
end;
procedure sp_clear as
begin
dbms_session.clear_context('mycontext','par1');
end;
end pkg_context_test;
3.查询
select * from v$context;
NAMESPACE ATTRIBUTE VALUE
MYCONTEXT PAR_USER val_user1
MYCONTEXT PAR1 val2
select sys_context('MYCONTEXT','PAR_USER') from dual;
val_user1
4.哪里用?
1.动态视图
基本原理是sys_context()取可变参数的值。
create or replace view v_t_limit
as
select a, end_date
from t_limit
where end_date = sys_context('my_context', 'order_date');
参考:https://blog.csdn.net/clg10051/article/details/100224881
2.虚拟专用数据库(Virtual Private Database)
基本原理是:Row Level Security行级安全。
通过DBMS_RLS.ADD_POLICY()给特定对象、方法增加策略;当在特定对象执行sql时,触发策略,Oracle自动改写sql。
在数据库层级实现了数据安全,但与Oracle耦合度太高;且系统一般用业务用户区分权限,而不是物理的数据库用户。
VPD = Virtual Private Database。同义词有RLS : Row Level Security, FGAC: Fine Grained Access Control。
用于行级访问控制。假设有需求,只有用户’SCOTT’能访问emp表所有记录,其他人只能访问manager以下员工的记录。
CREATE FUNCTION emp_policy(schema_in IN VARCHAR2,object_in IN VARCHAR2)
RETURN VARCHAR2
IS
l_return_value VARCHAR2(32767);
BEGIN
IF SYS_CONTEXT('USERENV', 'SESSION_USER') = 'SCOTT' THEN
l_return_value := '1=1';
ELSE
l_return_value := 'JOB NOT IN (''PRESIDENT'',''MANAGER'')';
END IF;
RETURN l_return_value;
END;
BEGIN
DBMS_RLS.ADD_POLICY (
object_schema => 'SCOTT',
object_name => 'EMP',
policy_name => 'EMP_POLICY',
function_schema => 'SCOTT',
policy_function => 'emp_policy',
statement_types => 'SELECT, INSERT, UPDATE, DELETE'
);
END;
控制访问权限的函数-emp_policy有特定的声明,如上所示,它的返回值是where语句部分。对于scott.emp表的select/insert/update/delete,Oracle将自动将l_return_value加入where部分。
我们测试一下:
[oracle@odilab ~]$ sqlplus scott/a123456
SQL*Plus: Release 11.2.0.1.0 Production on Sun Jan 19 22:52:20 2014
Copyright (c) 1982, 2009, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
$scott@ORCL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7935 HUIYE PRESIDENT (null) 03-NOV-13 9999 (null) 10
7369 SMITH CLERK 7902 17-DEC-80 800 (null) 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 (null) 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 (null) 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 (null) 10
7788 SCOTT ANALYST 7566 19-APR-87 3000 (null) 20
7839 KING PRESIDENT (null) 17-NOV-81 5000 (null) 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 (null) 20
7900 JAMES CLERK 7698 03-DEC-81 950 (null) 30
7902 FORD ANALYST 7566 03-DEC-81 3000 (null) 20
7934 MILLER CLERK 7782 23-JAN-82 1300 (null) 10
15 rows selected.
$scott@ORCL> connect scott1/a123456
Connected.
$scott1@ORCL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 (null) 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7788 SCOTT ANALYST 7566 19-APR-87 3000 (null) 20
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 (null) 20
7900 JAMES CLERK 7698 03-DEC-81 950 (null) 30
7902 FORD ANALYST 7566 03-DEC-81 3000 (null) 20
7934 MILLER CLERK 7782 23-JAN-82 1300 (null) 10
10 rows selected.
在数据库层面,oracle直接改写sql了!不知道这个知识点的,估计直接蒙圈了。
参考:https://blog.csdn.net/hustzw07/article/details/79688787