This presentations gives an overview of the concept of Application Context in the Oracle Database. It is one of the items in the AMIS Knowledge Center session PL/SQL Potpourri (January 20th, 2009). The presentation shows the various types of Application Context (session scope, global, cross-session) and introduced a number of use cases for using the Application Context facility. It has a number of code samples.
2. Overview
Application Context provides part of the environment
in which a session is executing statements
Part is system defined – context USERENV
Part is developer controlled – CLIENTCONTEXT and user
defined contexts
The Application Context is the link for context meta-
data between applications and the database
Applications should set the proper context values before
executing SQL and PL/SQL statements
Application Context is sometimes a more elegant and
better performing alternative to global package variables
And an essential part of VPD – Virtual Private Database
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
3. Introducing Application Context
An Application Context is
Named area
With key-value pairs WebClient_Ctx
• Key and Value are both Currency_Ctx Name Value
string values
OrgId 14
(Usually) part of the Locale fr_ca
session scope Timezone +2.00
View_Ctx
• Just like global package
variables
Values can only be added through a PL/SQL package
Values can be read in SQL queries and PL/SQL code
Through the SYS_CONTEXT operator
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
4. Application Context
Enables application developers to define, set, and access
application attributes by serving as a data cache
This removes the repeated overhead of querying the
database each time access to application
Namespace
attributes is needed
Two Application
Contexts are always Attribute Value
around:
Attribute Value
CLIENTCONTEXT
USERENV
Attribute Value
Pairs
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
5. Application Context
Values can be read from an Application Context using
SYS_CONTEXT, both in SQL as well as PL/SQL
select sys_context('USERENV', 'SESSION_USER')
from dual
l_user:= sys_context('USERENV', 'SESSION_USER')
Pass in the name of the Application Context and the name of the Attribute
you are looking for
If you ask for an Application Context that does not
exist, NULL is returned
If you ask for an attribute that does not exist, ORA-
2003 – invalid <app context> parameter is raised
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
7. Storing values in standard context
CLIENTCONTEXT
Values can be set in the Application Context CLIENTCONTEXT
begin
dbms_session.set_context
( 'CLIENTCONTEXT' -- Namespace
, 'dollar_to_euro_ratio' -- Attribute
, '0.67' -- Value
);
end;
CLIENTCONTEXT needs not be set up, it is always there
It is session bound – not accessible in other sessions, stored in UGA
The value can be read – in the same session – using:
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
8. Creating an application specific context
Application Context is a named container with a set of key-value
pairs.
A per session instance is stored in UGA
create context Hrm_Ctx using HrmPkg
An Application Context is associated with a package
Only through the package can values be set in the context
Setting values is not tied to the transaction (no commit dependency)
Values in the context can be used in where conditions
These are treated as bind-parameters!
deptno = sys_context('Hrm_Ctx', 'dept')
deptno = :b1
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
9. Distinction with global package variables
Values from Application Context are treated as bind
variables
There value is established before the query is executed
While functionally similar, the execution for these two
queries is quite different:
select *
from big_table
where country_column = package.get_current_country
and
select *
from big_table
where country_column =
sys_context('App_Ctx', 'current_country')
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
10. Create the HRM_CTX Context
create or replace context hrm_ctx using hrm_pkg
create or replace package body hrm_pkg
is
procedure set_language (p_language in varchar2)
is
begin
dbms_session.set_context
('HRM_CTX' , 'LANGUAGE' ,p_language);
end set_language;
procedure clear_context is
begin
dbms_session.clear_context('HRM_CTX');
end;
... select *
from session_context
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
11. Create the HRM_CTX Context
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
12. Use cases for Application Context
Programmable/Configurable View
Meta Data Interface between Application and Database
Client User Identity – and other environment settings
• Get rid of hard coded references to USER!
Instrumentation
Setting default values
Cache for ‘expensive’ and/or ‘shared’ values
Foundation for VPD
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
13. Configurable View
Generic challenge: create a view that has run-time
parameters governing its behavior
For example:
View EMP_REPORT_VW
Returns the Average Salary and Number of Employees
• Per Job and Department and Year of hiring
• or: Over all Employees
• or: Per Job
• or: Per Department and Year of Hiring
• or: any other combination
It depends on the caller which should be the case!
• The caller should provide ‘input parameters’ to get the desired
behavior from this view
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
15. Approach this challenge
Clearly this view uses data from meta data environment
That indicates which column(s) to group by
The view accesses this data from an Application
Context using SYS_CONTEXT
Setting the data is done through a simple call to a
package, preceding the query against the view
Note: for client technologies that have a problem calling
PL/SQL packages, we could create a View called
EMP_REPORT_VW_PARAMETERS with an INSTEAD OF
trigger that will convert an update of a parameter to a call to
the package that controls the Application Context.
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
17. Implementing Configurable View (2)
If group by department, then show deptno
If group by department, then group by deptno
else group by null (which has no effect)
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
18. Calling the configurable view
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
19. The client is always right
What time is it
or at least what is the client’s timezone
What locale is it
which language/regional settings apply
Where is it located
what is the geographical location
Who is it
web user’s identity <> any database user
Note: The database can only serve!
Following the client’s lead
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
20. USER <> CLIENT_IDENTIFIER
Client
Many – and ever more –
applications make use of
light-weight users
LDAP
That do not correspond J(2)EE Application Server
to database users
Web
These applications will Application
inform the database
through setting the Client
Identifier about the user
Referring to USER is (ever APPLICATION_
more) meaningless! SCHEMA
USERENV
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
21. Set Client Identifier with Light Weight User
In Java using Oracle JDBC Driver
conn.setClientIdentifier(quot;john.doequot;)
In PL/SQL
DBMS_SESSION.SET_IDENTIFIER( 'john.doe');
Or use a logon trigger to derive the client identifier
CREATE OR REPLACE TRIGGER logon_trigger
AFTER LOGON ON DATABASE
DECLARE
uid VARCHAR2(64);
BEGIN
SELECT ora_login_user ||':'
||SYS_CONTEXT('USERENV', 'OS_USER')
INTO uid
FROM dual;
dbms_session.set_identifier(uid);
END logon_trigger;
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
22. Set Client Identifier with Light Weight User
In the database – SQL or PL/SQL – the current client
identifier can be read like this:
SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER')
The Client Identifier is also available in V$SESSION
SELECT sid, client_identifier, service_name
FROM v_$session;
as well as V$SQLAREA
DBMS_MONITOR.CLIENT_ID_TRACE_ENABLE
allows for tracing all activity of a CLIENT_IDENTIIER
aka light-weight user
Note: Oracle standard auditing does not use
CLIENT_IDENTIFIER
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
23. A properly instrumented application...
Should tell the database
Who is the actual user for whom it is running
Which Module requests database actions & for what purpose
(optionally) Additional information about the client
begin
dbms_application_info.set_module
( module_name => 'MODULE_NAME'
, action_name => 'What is the module doing'
); -- sets columns Module&Action in V$SESSION view
dbms_application_info.set_client_info
( client_info => 'extra info e.g. Task Context'
); -- no longer than 64 chars, sets column Client
-- Info in the V$SESSION view
dbms_session.set_identifier('id for real user');
-- sets v$session view column CLIENT_IDENTIFIER
end;
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
24. Guideline: provide application with
Instrumentation API
Define an API (PL/SQL procedure) that applications can
call to provide all instrumentation information
This API will take care of
setting the proper values
J(2)EE Application Server
in Application Context
and through Web
Application
dbms_application_info
Requires but a single call
INSTRUMENTATION_API
dbms_
dbms_
application_
session
info
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
25. Retrieving the ‘instrumented values’
select sys_context('USERENV','sid') sid
, sys_context('USERENV','module') module
, sys_context('USERENV','action') action
, sys_context('USERENV','client_identifier')
client_identifier
, sys_context('USERENV','client_info') client_info
from dual
/
select sid
, module
, client_identifier
, client_info
, action
from v$session
/
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
26. Default values for audit columns
The default value of a column can be specified using a
reference to an application context:
CREATE TABLE IMPORTANT_RECORDS
( ...
, USER_CREATED VARCHAR2(100) DEFAULT
SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER')
That can be a reference to a user defined context too:
CREATE TABLE IMPORTANT_RECORDS
( ...
, PRICE VARCHAR2(100) DEFAULT
SYS_CONTEXT('ORDER_APP','CURRENT_PRICE')
Note: you can refer to default in UPDATE statement
UPDATE IMPORTANT_RECORDS
SET PRICE = DEFAULT
WHERE ...
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
27. Create Context as Globally Accessible
Accessible throughout the entire instance:
Every session can retrieve values
Stored in SGA (instead of UGA)
• A big difference compared to package variables!!
For global settings, cross application parameters
• For example once-per-day calculated or retrieved (from web
services?) values that remain available throughout the day
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
29. Globally Accessible: Accessing Values
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
30. Application Context values associated
with Client Identifier
Application Context can be private (tied to a session) or
globally accessible (across all sessions)
Third option: attributes associated with Client Identifier:
only sessions with the same Client Identifier can access an
those attributes of such a context
dbms_session.set_context
( namespace=> 'HRM_CTX'
, attribute => 'my_org_id'
, value=> '67'
, client_id =>
sys_context('USERENV','CLIENT_IDENTIFIER')
);
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
31. Application Context associated with
Client Identifier
Retrieving session specific values is handled by the
database automatically, using the CLIENT_IDENTIFIER
SYS_CONTEXT('HRM_CTX', 'my_ord_id')
If HRM_CTX has a value associated with the client identifier,
it is returned; otherwise the non associated value is returned
To remove all values tied to a specific client_identifier
from an application context:
... –- still package hrm_pkg managing HRM_CTX
procedure clear_context is
begin
dbms_session.clear_context('HRM_CTX'
, sys_context('USERENV','CLIENT_IDENTIFIER') );
end;
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009
32. Summary
An Application Context is a named in-memory set of
key-value pairs
Application Context value references in SQL queries
are processed like bind parameters
A Context is by default associated with a single session
Alternatively a context can be global (cross session) or
associated with a Client Identifier
Application Context is used for
Exposing System and Session attributes (USERENV)
Configurable Views
Application to Database meta data interface
Global cross-session shared in memory cache
Virtual Private Database
Application Context
Lucas Jellema, KC Server Development – PL/SQL Potpourri, 20th Januariy2009