В каждом сеансе работы с СУБД можно использовать так называемые контексты, формально представляющие собой именованный набор пар "параметр/значение". Контексты сеансов обладают рядом интересных свойств, существенно повышающих "внутренние" возможности Oracle по созданию приложений. В статье рассматриваются два предопределенных контекста Oracle: USERENV и CLIENTCONTEXT.
Введение
В каждом сеансе работы с СУБД можно использовать так называемые контексты. Каждый контекст – это именованный набор пар "параметр/значение". Oracle называет каждый конкретный подобный набор пространством имен (namespace), а элементы пространства имен атрибутами, способными принимать значения.
Создаются контексты SQL-предложением CREATE CONTEXT. Из-за этого далее вместо "пространства имен" предпочтение отдается термину "контекст". Параметры контекста ("атрибуты") устанавливаются процедурой DBMS_SESSION.SET_CONTEXT, а вот вычитываются в программу стандартной функцией SYS_CONTEXT. Пакет DBMS_SESSION содержит ряд других подпрограмм для работы с контекстами.
Здесь рассматривается лишь формальная сторона контекста сеанса, а способ его применения разработчик может определить сам или почерпнуть из описаний избирательного доступа к данным (FGAC или Label Security) и сервера приложений Oracle.
Готовый справочный контекст сеанса USERENV
Один контекст, с названием USERENV, создавать явным образом не требуется. Он доступен любому сеансу связи с СУБД Oracle в виде готового набора значений, разрешающего только прочтение, но не правку. Он позволяет узнать всевозможные сведения о сеансе, полезные для прикладного программирования. Ранее в Oracle существовала одноименная функция, но сейчас она поддерживается ради старых программ.
Пример информации, которую можно получить из контекста USERENV в программу:
COLUMN authent FORMAT A10 COLUMN curr_schema FORMAT A10 COLUMN curr_user FORMAT A10 COLUMN db_name FORMAT A10 COLUMN db_domain FORMAT A10 COLUMN host FORMAT A15 COLUMN ip_address FORMAT A15 COLUMN os_user FORMAT A15 SELECT SYS_CONTEXT ( 'userenv', 'AUTHENTICATION_TYPE' ) authent , SYS_CONTEXT ( 'userenv', 'CURRENT_SCHEMA' ) curr_schema , SYS_CONTEXT ( 'userenv', 'CURRENT_USER' ) curr_user , SYS_CONTEXT ( 'userenv', 'DB_NAME' ) db_name , SYS_CONTEXT ( 'userenv', 'DB_DOMAIN' ) db_domain , SYS_CONTEXT ( 'userenv', 'HOST' ) host , SYS_CONTEXT ( 'userenv', 'IP_ADDRESS' ) ip_address , SYS_CONTEXT ( 'userenv', 'OS_USER' ) os_user FROM dual ;Официальная документация: 10g Release 2 (10.2).
Вот, пример, как сведения из этого контекста помогают различить разные условия употребления конкретной программы:
CONNECT scott/tiger CREATE PROCEDURE whoowns AS BEGIN DBMS_OUTPUT.PUT_LINE ( SYS_CONTEXT ( 'userenv', 'CURRENT_SCHEMA' ) ); DBMS_OUTPUT.PUT_LINE ( SYS_CONTEXT ( 'userenv', 'CURRENT_USER' ) ); DBMS_OUTPUT.PUT_LINE ( user ); END; /
Проверка:
SQL> SET SERVEROUTPUT ON SQL> EXECUTE whoowns SCOTT SCOTT SCOTT PL/SQL procedure successfully completed. SQL> ALTER SESSION SET CURRENT_SCHEMA = system; Session altered. SQL> EXECUTE scott.whoowns SCOTT SCOTT SCOTT PL/SQL procedure successfully completed. SQL> CONNECT / as sysdba Connected. SQL> SET SERVEROUTPUT ON SQL> EXECUTE scott.whoowns SCOTT SCOTT SYS PL/SQL procedure successfully completed.
Перетранслируем процедуру для работы с правами запускающего:
CONNECT scott/tiger CREATE OR REPLACE PROCEDURE whoowns AUTHID CURRENT_USER AS BEGIN DBMS_OUTPUT.PUT_LINE ( SYS_CONTEXT ( 'userenv', 'CURRENT_SCHEMA' ) ); DBMS_OUTPUT.PUT_LINE ( SYS_CONTEXT ( 'userenv', 'CURRENT_USER' ) ); DBMS_OUTPUT.PUT_LINE ( user ); END; /
Снова проверка:
SQL> SET SERVEROUTPUT ON SQL> EXECUTE whoowns SCOTT SCOTT SCOTT PL/SQL procedure successfully completed. SQL> ALTER SESSION SET CURRENT_SCHEMA = system; Session altered. SQL> EXECUTE scott.whoowns SYSTEM SCOTT SCOTT PL/SQL procedure successfully completed. SQL> CONNECT / as sysdba Connected. SQL> SET SERVEROUTPUT ON SQL> EXECUTE scott.whoowns SYS SYS SYS PL/SQL procedure successfully completed. SQL> ALTER SESSION SET CURRENT_SCHEMA = system; Session altered. SQL> EXECUTE scott.whoowns SYSTEM SYS SYSПримеры поясняют отличие атрибутов CURRENT_SCHEMA и CURRENT_USER контекста USERENV друг от друга и от системной переменной USER.
Готовый изменяемый контекст сеанса CLIENTCONTEXT
Еще один предопределенный контекст, с именем CLIENTCONTEXT, также не требует специального создания, однако в отличие от USERENV он позволяет сеансу создавать собственные атрибуты и задавать им значения. Особенность этого контекста в том, что он, в дополнение к обычному способу (изнутри сеанса), позволяет устанавливать значения атрибутам заранее, при открытии соединения с СУБД клиентской программой, и передавать их для обработки в сеанс. Делается это
- либо через библиотеку OCI с помощью специального вызова OCIAppCtxSet
- либо из программы на Java с помощью методов класса oracle.jdbc.internal.OracleConnection.
Значения переданных в сеанс атрибутов контекста CLIENTCONTEXT можно читать как обычно функцией SYS_CONTEXT, и изменять, но можно заводить и новые атрибуты:
SQL> CONNECT scott/tiger Connected. SQL> EXECUTE DBMS_SESSION.SET_CONTEXT ( 'CLIENTCONTEXT', 'a', 'b' ) PL/SQL procedure successfully completed. SQL> SELECT SYS_CONTEXT ('CLIENTCONTEXT', 'a' ) FROM dual; SYS_CONTEXT('CLIENTCONTEXT','A') -------------------------------------------------------------------- bЕсли бы атрибут A был установлен клиентской программой на C или на Java перед установлением соединения, значение B мы бы увидели сразу.
Второе отличительное свойство контекста CLIENTCONTEXT в том, что Oracle разрешает именно для него обращаться к DBMS_SESSION.SET_CONTEXT напрямую (см. выше). Это исключение: контексты, которые разработчик пожелает создавать сам, позволят обращаться к DBMS_SESSION.SET_CONTEXT только из текста своей доверительной программной единицы.
Комментариев нет:
Отправить комментарий