浅谈oracle中的context(上下文)Oracle Application Context

context这个词见得还是挺多的,尤其是在计算机领域。大部人将它翻译为上下文,我也就跟随大众吧。比如操作系统中的上下文切换等等。那么上下文到底意味着什么呢?在我看来就是当前程序运行的一个环境信息。举个例子说吧,当一个用户登录oracle之后就会有一个session,这个session中包含了session_id,用户名等等信息,这就是上下文的一些信息。那么,在oracle中怎么查看这个上下文的一些信息呢?
(1)查看context中的属性信息。
oracle默认的为我们创建了一个context叫userenv(user environment),在这里你可以查看到很多session级别的信息。里面的单词都很简单,相信大家都知道每个属性表示什么意思。
SYS_CONTEXT('USERENV','TERMINAL') 
SYS_CONTEXT('USERENV','LANGUAGE')
SYS_CONTEXT('USERENV','SESSIONID') 
SYS_CONTEXT('USERENV','INSTANCE')
SYS_CONTEXT('USERENV','ENTRYID') 
SYS_CONTEXT('USERENV','ISDBA') 
SYS_CONTEXT('USERENV','NLS_TERRITORY') 
SYS_CONTEXT('USERENV','NLS_CURRENCY')
SYS_CONTEXT('USERENV','NLS_CALENDAR') 
SYS_CONTEXT('USERENV','NLS_DATE_FORMAT') 
SYS_CONTEXT('USERENV','NLS_DATE_LANGUAGE') 
SYS_CONTEXT('USERENV','NLS_SORT') 
SYS_CONTEXT('USERENV','CURRENT_USER')
SYS_CONTEXT('USERENV','CURRENT_USERID') 
SYS_CONTEXT('USERENV','SESSION_USER') 
SYS_CONTEXT('USERENV','SESSION_USERID') 
SYS_CONTEXT('USERENV','PROXY_USER') 
SYS_CONTEXT('USERENV','PROXY_USERID') 
SYS_CONTEXT('USERENV','DB_DOMAIN') 
SYS_CONTEXT('USERENV','DB_NAME') 
SYS_CONTEXT('USERENV','HOST') 
SYS_CONTEXT('USERENV','OS_USER') 
SYS_CONTEXT('USERENV','EXTERNAL_NAME') 
SYS_CONTEXT('USERENV','IP_ADDRESS') 
SYS_CONTEXT('USERENV','NETWORK_PROTOCOL') 
SYS_CONTEXT('USERENV','BG_JOB_ID') 
SYS_CONTEXT('USERENV','FG_JOB_ID') 
SYS_CONTEXT('USERENV','AUTHENTICATION_TYPE')
SYS_CONTEXT('USERENV','AUTHENTICATION_DATA')  
(2)我们自己创建一个context
语法:
DBMS_SESSION.SET_CONTEXT ( namespace VARCHAR2, attribute VARCHAR2, value VARCHAR2, username VARCHAR2, client_id VARCHAR2 );
三个参数是必须的,后两个非必须,如果不写的话就默认为null。后面两个参数是针对全局的context
使用的,这里不讨论了,请查阅相关资料。一个namespace下的attribute数理论上是没有限制的。
1)创建一个context
CREATE OR REPLACE CONTEXT context_name USING proc_name
2)建立与上下文先关的过程(也就是上面的proc_name)
CREATE OR REPLACE PROCEDURE proc_name
/**
context_name:上面的那个上下文名字
attribute_name:属性的名字,就相当用户userenv中的host,db_name一样
attribute_value:属性的值
**/
AS
  BEGIN
DBMS_SESSION.set_context('context_name', 'attribute_name',attribute_value);
END;
当我们创建好了之后,就可以可以使用了。
(3)context的作用
context的最主要的作用是对信息的一种管理上的方便,这有点类似于OO中的封装思想。我们得到这些信息只要通过SYS_CONTEXT('namespace','attribute')来获得,方便、简洁。
当然,关于context还有很多更深层次的知识,但是如果我们不是那些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的生命周期也结束了。另一篇博客Oracle VPD http://blog.csdn.net/chncaesar/article/details/18550029 给出了一个local application context的例子。


Global application context存储在SGA中,只要SGA不消亡,global application context就一直存在。global application context常常用于跨会话,与会话无关的场景。dbms_session.set_context有两个默认值为NULL的参数:

  • username
  • client_id

username = null , client_id=null。所有用户都能访问。

username = null, client_id=<client_id>。 只要session 的client_id =<client_id>,而不管username,都能访问。

username = <database username>, client_id=null。只要session使用指定的oracle schema登陆,不管client_id,都能访问。

username = <database username>, client_id=<client_id>. 常用于statless web session ,如http。

username = <non-database username>, client_id=<client_id> . 该username将用于数据库连接池的owner。

例子1: 所有用户都能访问的application context

[sql]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CREATE OR REPLACE CONTEXT global_hr_ctx USING hr_ctx_pkg ACCESSED GLOBALLY;  
  2. CREATE OR REPLACE PACKAGE hr_ctx_pkg   
  3.    AS    
  4.     PROCEDURE set_hr_ctx(sec_level IN VARCHAR2);   
  5.     PROCEDURE clear_hr_context;  
  6.    END;    
  7.   /  
  8.   CREATE OR REPLACE PACKAGE BODY hr_ctx_pkg   
  9.    AS                                              
  10.     PROCEDURE set_hr_ctx(sec_level IN VARCHAR2)        
  11.     AS     
  12.     BEGIN    
  13.      DBMS_SESSION.SET_CONTEXT(    
  14.      <strong> namespace  => 'global_hr_ctx',   
  15.       attribute  => 'job_role',   
  16.       value      => sec_level);</strong>  
  17.      END set_hr_ctx;  
  18.              
  19.   PROCEDURE clear_hr_context    
  20.     AS  
  21.     BEGIN    
  22.      DBMS_SESSION.CLEAR_CONTEXT('global_hr_ctx''job_role');   
  23.     END clear_context;    
  24.   END;   
  25.  /  
例子2: 跨session/application,但是使用同一个数据库schema的application context。

[sql]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CREATE OR REPLACE PACKAGE hr_ctx_pkg  
  2.   AS  
  3.     PROCEDURE set_hr_ctx(sec_level IN VARCHAR2, user_name IN VARCHAR2);  
  4.     PROCEDURE clear_hr_context;  
  5.    END;  
  6.   /  
  7.   CREATE OR REPLACE PACKAGE BODY hr_ctx_pkg  
  8.    AS  
  9.     PROCEDURE set_hr_ctx(sec_level IN VARCHAR2, user_name IN VARCHAR2)  
  10.     AS  
  11.      BEGIN  
  12.       DBMS_SESSION.SET_CONTEXT(  
  13.        namespace  => 'global_hr_ctx',  
  14.        attribute  => 'job_role',  
  15.        value      => sec_level,  
  16. <strong>       username   => user_name);</strong>  
  17.       END set_hr_ctx;  
  18.    
  19.    PROCEDURE clear_hr_context  
  20.     AS  
  21.      BEGIN  
  22.       DBMS_SESSION.CLEAR_CONTEXT('global_hr_ctx');  
  23.      END clear_context;  
  24.   END;  
  25.  /   
两个例子都提供了clear_hr_context 存储过程。这是因为global application context常驻SGA,需要用户使用完毕就清理,以免信息泄露。

USERENV

USERENV是Oracle预定义的命名空间。它包含了许多常用的application context。

  • CURRENT_USER
  • DB_NAME
  • HOST: 客户端机器名
  • CLIENT_INFO: 客户端程序用作计数,标识符等
其他application context请参考SQL Language Reference。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值