学无止境
分类: Oracle
2013-09-18 11:22:31
上下文命名空间CONTEXTS。
经常用于动态获取一些变量值。主要语法有以下4种,context可以只用于当前会话,也可以用于全局。
create context context-namespace using package-name;
create context context-namespace using package-name initialized externally;
create context context-namespace using package-name initialized globally;
create context context-namespace using package-name accessed globally;
获取上下文可以通过sys_context('context-namespace', 'attribute-name')来获取
设置上下文,可以通过dbms_session.set_context('context-namespace', 'attribute-value', value)来设置,ORACLE出于安全的考虑,该过程只能在创建context使用的包里执行,该包是自定义的。
一个普通context的例子,需要注意的是只有create any context的系统权限,没有create context权限。
grant create session,create procedure,create any context to test;
conn test/test
create context some_context using some_package;
create package some_package as
procedure set_value_in_context(some_value in varchar2);
end some_package;
/
create package body some_package as
procedure set_value_in_context(some_value in varchar2) is
begin
dbms_session.set_context('some_context', 'some_attribute', some_value);
end set_value_in_context;
end some_package;
/
exec some_package.set_value_in_context('liaody');
select sys_context('some_context', 'some_attribute') from dual;
SYS_CONTEXT('SOME_CONTEXT','SOME_ATTRIBUTE')
-----------------------------------------------
liaody
其他会话无法查询到这个context值,不能跨会话查询。
下面是一个全局context的例子:
create context global_context using global_package accessed globally;
create package global_package as
procedure set_value_in_context(global_value in varchar2);
end global_package;
/
create package body global_package as
procedure set_value_in_context(global_value in varchar2) is
begin
dbms_session.set_context('global_context', 'global_attribute', global_value);
end set_value_in_context;
end global_package;
/
exec global_package.set_value_in_context('valid accross sessions');
conn ldy/ldy
select sys_context('global_context', 'global_attribute') from dual;
SYS_CONTEXT('GLOBAL_CONTEXT','GLOBAL_ATTRIBUTE')
--------------------------------------------------
valid accross sessions
使用其他用户在其他会话也可以查询到这个context的内容。
系统的USERENV命名空间带了一些常用的用户上下文内容,以下是常用的一些参数返回:
SQL> select sys_context('userenv','host') from dual;
SYS_CONTEXT('USERENV','HOST')
---------------------------------
MSHOME\LIAODY
SQL> select sys_context('userenv','sessionid') from dual;
SYS_CONTEXT('USERENV','SESSIONID')
--------------------------------------
209
SQL> select sys_context('userenv','session_user') from dual;
SYS_CONTEXT('USERENV','SESSION_USER')
----------------------------------------
LDY
SQL> select sys_context('userenv','db_name') from dual;
SYS_CONTEXT('USERENV','DB_NAME')
-----------------------------------
oracle9i
SQL> select sys_context('userenv','instance') from dual;
SYS_CONTEXT('USERENV','INSTANCE')
------------------------------------
1
SQL> select sys_context('userenv','language') from dual;
SYS_CONTEXT('USERENV','LANGUAGE')
------------------------------------
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
SQL> select sys_context('userenv','os_user') from dual;
SYS_CONTEXT('USERENV','OS_USER')
-----------------------------------
LIAODY\Eagle
IP_ADDRESS必须通过走监听连接,才能获取到IP地址
SQL> select sys_context('userenv','ip_address') from dual;
SYS_CONTEXT('USERENV','IP_ADDRESS')
-------------------------------------
127.0.0.1
一个简单例子:
grant create procedure,create any context to test;
create context test_context using contxt_pkg1;
create or replace package contxt_pkg1
as
procedure set_contxt1;
end;
/
create or replace package body contxt_pkg1
as
procedure set_contxt1
is
begin
dbms_session.set_context('test_context','ip',sys_context('userenv','ip_address'));
end;
end;
/
exec contxt_pkg1.set_contxt1;
select sys_context('test_context','ip') from dual;