Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

2006 г.

Контекст сеанса в Oracle

Часть 2: создание своими руками

Часть 1: предопределенные контексты
Владимир Пржиялковский,
Преподаватель технологий Oracle,
www.ccas.ru/prz/

Сама садик я садила,
Сама буду поливать,
Сама милого любила,
Сама буду забывать.

Русская народная песня

Аннотация

В каждом сеансе работы с СУБД можно использовать так называемые контексты, формально представляющие собой именованный набор пар «параметр/значение». Контексты сеансов обладают рядом интересных свойств, существенно повышающих «внутренние» возможности Oracle по созданию приложений. В статье рассматриваются возможности проектирования локальных и глобальных контекстов сеанса и некоторые их свойства.

Как построить контекст сеанса своими руками

Для самостоятельного создания контекста служит специальная команда CREATE CONTEXT. Выдать ее (то есть создать контекст) может сеанс, имеющий полномочие CREATE ANY CONTEXT. Слово ANY в названии полномочия (привилегии) свидетельствует о том, что контекст - внесхемный объект в БД Oracle, такой, например, как роль, и отличный, например, от таблицы.

Для каждого контекста требуется указать специальную «доверительную» программную единицу: процедуру, функцию или пакет. Именно из тела этой программной единицы Oracle разрешит обращаться к процедуре DBMS_SESSION.SET_CONTEXT. Принято такое неочевидное решение во имя безопасности, так как доступ к хранимым программным единицам регулируется уже готовым механизмом привилегий.

Пример создания контекста

Положим, доверительной программной единицей должна быть процедура SET_MYCONTEXT_VALUE:

CONNECT / as sysdba 

CREATE OR REPLACE CONTEXT mycontext USING set_mycontext_value;

Обратите внимание, что процедура не обязана существовать в момент создания контекста. Но в конце концов ее-таки потребуется создать:

CREATE OR REPLACE PROCEDURE set_mycontext_value (
  par IN VARCHAR2
, val IN VARCHAR2 
) 
AS
BEGIN DBMS_SESSION.SET_CONTEXT ( 'mycontext', par, val );
END;
/

GRANT EXECUTE ON set_mycontext_value TO scott;

Проверка:

SQL> CONNECT scott/tiger
Connected.
SQL> SELECT SYS_CONTEXT ( 'mycontext', 'sesame' ) FROM dual;

SYS_CONTEXT('MYCONTEXT','SESAME')
------------------------------------------------------------
 
SQL> EXECUTE sys.set_mycontext_value ( 'sesame', '123' ) PL/SQL procedure successfully completed. SQL> SELECT SYS_CONTEXT ( 'mycontext', 'sesame' ) FROM dual; SYS_CONTEXT('MYCONTEXT','SESAME') ------------------------------------------------------------ 123

Выше серым фоном выделена пустая строка.

С помощью контекста MYCONTEXT и доступной ему процедуры пользователь SCOTT завел значение, которое сможет читать и переустанавливать в собственном сеансе вплоть до завершения. Другой сеанс пользователя SCOTT создаст и будет использовать с помощью этого же контекста свои значения, то есть значения контекста являются собственностью сеанса.

Значения атрибутов контекста живут не долее пределов сеанса и защищены от доступа из других сеансов. В течение сеанса значения переменных пакета могут пропасть («сброс» пакета, хотя пользователи и нечасто прибегают к нему), и значения атрибутов контекста тоже (с помощью пакета DBMS_SESSION). Этим атрибуты схожи с переменными пакета. Но есть и отличия:

  • в пакете набор переменных фиксирован, а набор атрибутов контекста произволен
  • переменные пакета могут быть разнообразны по структуре, а значения атрибутов контекста - всего лишь строки текста
  • атрибутам контекста можно устанавливать до сеанса и делать доступными в другом сеансе.

Вот еще пример использования нашего контекста:

SQL> EXECUTE set_mycontext_value -
> ( 'start work', TO_CHAR ( SYSDATE, 'hh24:mi:ss' ) )

PL/SQL procedure successfully completed.

SQL> REMARK выполняем работу, после чего смотрим когда начинали ...
SQL> SELECT SYS_CONTEXT ( 'mycontext', 'start work' ) FROM dual;

SYS_CONTEXT('MYCONTEXT','STARTWORK')
--------------------------------------------------------------------
13:58:06
Вариация в технологии: использование доверительного пакета
Если запросить структуру справочной таблицы доступных контекстов, то видно, что поле для доверительной программной единицы названо PACKAGE:
SQL> SELECT * FROM all_context;

NAMESPACE              SCHEMA                 PACKAGE
---------------------- ---------------------- ----------------------
MYCONTEXT              SYS                    SET_CONTEXT_VALUE

Это не случайно: на практике часто более технологично установку контекста выполнять с помощью доверительного пакета, а не самостоятельной процедуры или функции. Ведь в состав пакета можно включить и прочие программные элементы, моделирующие логику предметной области.

Пример:

CONNECT / as sysdba 

CREATE OR REPLACE CONTEXT mycontext USING mycontext_pckg;

CREATE OR REPLACE PACKAGE mycontext_pckg IS
   PROCEDURE set_value ( par VARCHAR2, val VARCHAR2 );
   FUNCTION get_value ( par VARCHAR2 ) RETURN VARCHAR2;
END;
/

CREATE OR REPLACE PACKAGE BODY mycontext_pckg IS
   PROCEDURE set_value ( par VARCHAR2, val VARCHAR2 )
   IS
   BEGIN
      DBMS_SESSION.SET_CONTEXT ( 'mycontext', par, val );
   END;

   FUNCTION get_value ( par VARCHAR2 ) RETURN VARCHAR2
   IS
   BEGIN
      RETURN SYS_CONTEXT ( 'mycontext', par );
   END;
END;
/

GRANT EXECUTE ON mycontext_pckg TO scott;

Проверка:

SQL> CONNECT scott/tiger
Connected.
SQL> SELECT sys.mycontext_pckg.get_value ( 'sesame' ) FROM dual;

SYS.MYCONTEXT_PCKG.GET_VALUE('SESAME')
---------------------------------------------------------------------
 
SQL> EXECUTE sys.mycontext_pckg.set_value ( 'sesame', '123' ) PL/SQL procedure successfully completed. SQL> SELECT sys.mycontext_pckg.get_value ( 'sesame' ) FROM dual; SYS.MYCONTEXT_PCKG.GET_VALUE('SESAME') --------------------------------------------------------------------- 123

Пакет можно спроектировать и иначе, закрыв, например, для пользователя имя атрибута или даже контекста. Можно запрограммировать все, что требует логика предметной области.

Начальные значения атрибутов контекста
Выше было показано, как атрибуты контекстов выставляются в процессе сеанса связи с СУБД. Однако по подобию с CLIENTCONTEXT создаваемый контекст тоже можно обеспечить начальными значениями требуемых атрибутов из программы, открывающий сеанс. Это можно сделать
  • средствами OCI (вызовы OCIAttrSet и OCISessionBegin) и
  • через сервер имен (каталог) LDAP.

Возможность таких начальных присвоений обеспечивается соответствующими указаниями при создании контекста:

CREATE CONTEXT ... INITIALIZED EXTERNALLY и

CREATE CONTEXT ... INITIALIZED EXTERNALLY

Начальные значения атрибутов контекста для сеансов - очень сильное средство, позволяющее наложить на относительно примитивный механизм внутренних пользователей БД инфраструктуру внешних пользователей, часто более проработанную и универсальную. Например, сервер приложений может поддерживать очень много пользователей web-страниц, обладающих собственными свойствами. Моделировать их отдельными локальными для Oracle пользователями может оказаться крайне неэффективно, и в этом случае возможность предварительного установления атрибутов перед обращением к БД будет давать единственный ключ к построению решения.

Глобальный контекст сеанса («контекст приложения»)

«Обычный» контекст сеанса имеет своею областью действия отдельный сеанс. Иногда этого разработчику приложения вполне достаточно, а иногда хочется большего. Можно ли, например, запретить сеансу самостоятельно выставлять значение атрибута и предоставить ему только чтение, а значение задавать из другого сеанса? Такую возможность обеспечивает глобальный контекст сеанса, называемый еще иногда контекстом приложения. Пример его использования показан ниже:
CONNECT / AS SYSDBA

CREATE OR REPLACE CONTEXT globalcontext 
USING globalcontext_pckg
ACCESSED GLOBALLY
/

CREATE OR REPLACE PACKAGE globalcontext_pckg AS
   PROCEDURE set_value (
     par VARCHAR2
   , val VARCHAR2
   , usr VARCHAR2
   , usrid VARCHAR2
   );
END;
/

CREATE OR REPLACE PACKAGE BODY globalcontext_pckg AS
   PROCEDURE set_value (
     par VARCHAR2
   , val VARCHAR2
   , usr VARCHAR2
   , usrid VARCHAR2
   )
   AS
   BEGIN
    DBMS_SESSION.SET_CONTEXT (
     'globalcontext'
   , par
   , val
   , usr
   , usrid
   );
   END;
END;
/

EXECUTE globalcontext_pckg.set_value -
( 'sesame' , '123', 'SCOTT', 'XYZ32A6' )

Проверка:

SQL> CONNECT scott/tiger
Connected.
SQL> SELECT SYS_CONTEXT ( 'globalcontext', 'sesame' ) FROM dual;

SYS_CONTEXT('GLOBALCONTEXT','SESAME')
--------------------------------------------------------------------
 
SQL> EXECUTE DBMS_SESSION.SET_IDENTIFIER ( 'XYZ32A6' ); PL/SQL procedure successfully completed. SQL> SELECT SYS_CONTEXT ( 'globalcontext', 'sesame' ) FROM dual; SYS_CONTEXT('GLOBALCONTEXT','SESAME') -------------------------------------------------------------------- 123 SQL> EXECUTE DBMS_SESSION.SET_IDENTIFIER ( 'XYZ32A6ZZZ' ); PL/SQL procedure successfully completed. SQL> SELECT SYS_CONTEXT ( 'globalcontext', 'sesame' ) FROM dual; SYS_CONTEXT('GLOBALCONTEXT','SESAME') ----------------------------------------------------------------------
 

Тут есть сразу несколько интересных новшеств.

  1. То, что контекст глобальный, было указано словами ACCESSED GLOBALLY при его создании.
  2. В процедуре DBMS_SESSION.SET_CONTEXT именно для глобального контекста существуют два дополнительных параметра. Первый сообщает, сеансам чьего пользователя будет доступен этот контекст (для каждого такого пользователя нужно будет выполнить отдельный вызов SET_CONTEXT), а второй - условное значение, которое необходимо будет сообщить для возможности прочитать установленное другим сеансом значения атрибута, своего рода пароль.
  3. Сообщение этого условного значения выполняется специальной процедурой DBMS_SESSION.SET_IDENTIFIER.

Таким образом, мало войти в СУБД под «правильным» пользователем; для того, чтобы получить в сеансе значение желаемого атрибута (глобального контекста), нужно будет еще сообщить условную строку. Излишне напоминать, что очевидным кандидатом на такую строку является cookie сеанса общения с web. И только благодаря этому, а также механизму избирательного доступа к частям таблицы в Oracle («виртуальные частные базы данных», VPD/FGAC) и возможности сервера приложений автоматически выдавать SET_IDENTIFIER при обращении к БД, многочисленные пользователи web, формально подключаемые к СУБД под одними и теми же именами пользователей Oracle, смогут увидеть в базе каждый собственные данные.

Часть 1: предопределенные контексты

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...