首先我们要明白什么是上下文。
context其实说白了,和文章的上下文是一个意思,在通俗一点,我觉得叫环境更好。
....
林冲大叫一声“啊也!”
....
问:这句话林冲的“啊也”表达了林冲怎样的心里?
答:啊你妈个头啊!
看一篇文章,给你摘录一段,没前没后,你读不懂,因为有语境,就是语言环境存在,一段话说了什么,要通过上下文(文章的上下文)来推断。
子程序之于程序,进程之于操作系统,甚至app的一屏之于app,都是一个道理。
程序执行了部分到达子程序,子程序要获得结果,要用到程序之前的一些结果(包括但不限于外部变量值,外部对象等等);
app点击一个按钮进入一个新的界面,也要保存你是在哪个屏幕跳过来的等等信息,以便你点击返回的时候能正确跳回,如果不存肯定就无法正确跳回了。
看这些都是上下文的典型例子,理解成环境就可以了。
其次oracle中的上下文又是什么意思呢?
Application Context是内存中的一组name-value对,application context从属于某个命名空间(namespace)。
用户只能通过一个自定义procedure调用dbms_session.set_context来设置application context的值。用户使用sys_context(<namespace>,<name>)来获取某个application context的值。
分类
网上有两种说法,现整合如下:
一、Application context分为三种
- dabase session-based application context,又称为local application context。
- global application context
- client session-based application context。通常被OCI使用,存储在客户端内存,而不是Oracle服务器端,也由OCI程序管理。
Local application context存储在UGA中,dedicated server mode, UGA在PGA中,shared server mode,UGA在SGA中。local application context是会话/server process级别的。只有本会话能够访问。当会话/server process终止时,local application context的生命周期也结束了。
Global application context存储在SGA中,只要SGA不消亡,global application context就一直存在。global application context常常用于跨会话,与会话无关的场景
二、另外一种说法:上下文可以根据数据的来源分类四类:
1.Built-in Context:内置的上下文叫USEREVN,主要包括几种类型的属性:(查看sys_context函数并测试)
1)客户端属性:例如客户端IP;
2)用户属性:例如代理,会话和操作系统的登录用户名等;
3)认证信息:认证类型,操作系统和语言设置;
2.Local Application Contexts:在FGAC的应用中可以查询任何数据库对象的属性,比如可以从HR.EMPLOYEES表中得到用户的名称和部门信息;也可以从一个存储过程或者函数中得到返回值;
3.Externalized Application Contexts:外部初始化应用程序上下文的特征是使用外部资源,例如OCI调用;语法为:CREATE CONTEXT external USINGext_package INITIALIZED EXTERNALLY;
4.Global Application Contexts:组织集中化的用户信息和管理使用LDAP或者活动目录,Oracle中类似的是OID(Oracle Internet Directory),应用程序上下文属性值可以存储在OID中;创建语法:CREATE CONTEXT hrgapp USING hr_g_context INITIALIZED GLOBALLY。
使用
我们知道,oracle不允许采用不可信任的方式直接调用 DBMS_SESSION.SET_CONTEXT 等过程,所以本文提供两种方法来调用上下文对象。
(一)使用存储过程或存储函数调用
1.编译存储过程
create or replace PROCEDURE set_value(attr VARCHAR2, value VARCHAR2)
AS
BEGIN
DBMS_SESSION.SET_CONTEXT('MY_CONTEXT',attr,value);
END;
/
create or replace PROCEDURE clear_context
AS
BEGIN
DBMS_SESSION.CLEAR_CONTEXT('MY_CONTEXT',null);
END;
/
2.创建CONTEXT(Local Application Contexts)
create or replace context MY_CONTEXT using set_value;
3.设置值(可以设置多个键值对,就不一一实验了)
begin
set_value('year','2018');
end;
4.查看值
select sys_context('MY_CONTEXT','year') from dual;
4.清除值前先创建同样的 context 引用不同的过程
create or replace context MY_CONTEXT using clear_context;
5.实现清除值(这里是清除所有,也可以按需配置)
begin
clear_context;
end;
通过上面的流程,我们发现可以实现对上下文对象设置值,但是流程过于麻烦,那么可不可以简化呢?其实我们可以使用PACKAGE;
(二)使用包调用
1.创建包
create or replace package my_context_util
AS
PROCEDURE set_value(attr VARCHAR2, value VARCHAR2);
PROCEDURE clear_context;
END;
/
create or replace package body my_context_util
AS
PROCEDURE set_value(attr VARCHAR2, value VARCHAR2)
AS
BEGIN
DBMS_SESSION.SET_CONTEXT('MY_CONTEXT',attr,value);
END;
PROCEDURE clear_context
AS
BEGIN
DBMS_SESSION.CLEAR_CONTEXT('MY_CONTEXT',null);
END;
END;
/
2.创建上下文(只需一次,之后无需创建)(用户名scott可不加)
create or replace context MY_CONTEXT using scott.my_context_util;
3.设置值、查询值、清除值
begin
scott.my_context_util.set_value('year','2018');
end;
/
select sys_context('MY_CONTEXT','year') from dual;
/
begin
scott.my_context_util.clear_context;
end;
/
我们发现这里只需要指定一次包,以后不需要再去指定,直接就可以设定。相当于只需初始化一次context对象即可。
实践中,上下文经常会被其他包调用,所以这也是我们在做迁移数据库的时候必须要注意的地方,有可能漏掉这些初始化对象而导致程序不可用。
查询context对象:
select * from dba_objects where object_type='CONTEXT';
必要的权限:(如果在创建上下文时候出现权限不足,请用高级用户赋权)
grant UNLIMITED tablespace to scott;
grant CREATE any context to scott;
grant drop any context to scott;
原错误:
ORA-01031: 权限不足
ORA-06512: 在 "SYS.DBMS_SESSION", line 115
ORA-06512: 在 "SCOTT.CLEAR_CONTEXT", line 4
ORA-06512: 在 line 2
01031. 00000 - "insufficient privileges"
*Cause: An attempt was made to change the current username or password
without the appropriate privilege. This error also occurs if
attempting to install a database without the necessary operating
system privileges.
When Trusted Oracle is configure in DBMS MAC, this error may occur
if the user was granted the necessary privilege at a higher label
than the current login.
*Action: Ask the database administrator to perform the operation or grant
the required privileges.
For Trusted Oracle users getting this error although granted the
the appropriate privilege at a higher label, ask the database
administrator to regrant the privilege at the appropriate label.