Контекст сеансу в Oracle. Частина 2: створення власних контекстів

Частина 1


Анотація


У кожному сеансі роботи з СУБД можна використовувати так звані контексти, формально представляють собою іменований набір пар "параметр / значення". Контексти сеансів володіють рядом цікавих властивостей, істотно підвищують "внутрішні" можливості 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 створюваний контекст теж можна забезпечити початковими значеннями необхідних атрибутів з програми, відкриває сеанс. Це можна зробити:


Можливість таких початкових присвоєнь забезпечується відповідними вказівками при створенні контексту:

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, зможуть побачити в базі кожен власні дані.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*