Мы можем сделать это, используя КОНТЕКСТ .Это пространство имен в памяти сеанса, которое мы можем использовать для хранения значений.Oracle поставляется с пространством имен по умолчанию «USERENV», но мы можем определить свое собственное.Контекст должен быть создан пользователем с привилегией CREATE ANY CONTEXT;обычно это DBA.Оператор ссылается на PACKAGE, который устанавливает и получает значения в пространстве имен, но этот пакет не должен существовать, чтобы оператор выполнялся успешно:
SQL> create context user_ctx using apc.ctx_pkg
2 /
Context created.
SQL>
Теперь давайте создадим пакет:
SQL> create or replace package ctx_pkg
2 as
3 procedure set_user_id(p_userid in varchar2);
4 function get_user_id return varchar2;
5 procedure clear_user_id;
6 end ctx_pkg;
7 /
Package created.
SQL>
Существует три метода для установки, получения и сброса значения в пространстве имен.Обратите внимание, что мы можем использовать одно пространство имен для хранения разных значений.Я просто использую этот пакет для установки одной переменной (USER_ID) в пространстве имен USER_CTX.
SQL> create or replace package body ctx_pkg
2 as
3 procedure set_user_id(p_userid in varchar2)
4 is
5 begin
6 DBMS_SESSION.SET_CONTEXT(
7 namespace => 'USER_CTX',
8 attribute => 'USER_ID',
9 value => p_userid);
10 end set_user_id;
11
12 function get_user_id return varchar2
13 is
14 begin
15 return sys_context('USER_CTX', 'USER_ID');
16 end get_user_id;
17
18 procedure clear_user_id
19 is
20 begin
21 DBMS_SESSION.CLEAR_CONTEXT(
22 namespace => 'USER_CTX',
23 attribute => 'USER_ID');
24 end clear_user_id;
25
26 end ctx_pkg;
27 /
Package body created.
SQL>
Так, как это решает что-нибудь?Вот таблица для временного хранения данных.Я собираюсь добавить столбец, который будет содержать токен для идентификации пользователя.Когда мы заполним таблицу, значение для этого столбца будет представлено CTX_PKG.GET_USER_ID()
:
SQL> create table temp_23 as select * from big_table
2 where 1=0
3 /
Table created.
SQL> alter table temp_23 add (user_id varchar2(30))
2 /
Table altered.
SQL> create unique index t23_pk on temp_23(user_id, id)
2 /
Index created.
SQL>
... и над этой таблицей я создаю представление: ...
create or replace view v_23 as
select
id
, col1
, col2
, col3
, col4
from temp_23
where user_id = ctx_pkg.get_user_id
/
Теперь, когда я хочу сохранить некоторые данные в таблице, мне нужно установить контекст со значением, однозначно идентифицирующим моего пользователя.
SQL> exec ctx_pkg.set_user_id('APC')
PL/SQL procedure successfully completed.
SQL>
Этот оператор заполняет временную таблицу двадцатью случайными строками:
SQL> insert into temp_23
2 select * from
3 ( select b.*, ctx_pkg.get_user_id
4 from big_table b
5 order by dbms_random.random )
6 where rownum <= 20
7 /
20 rows created.
SQL>
Я могу получить эти строки, запросив представление.Но когда я изменяю свой USER_ID и запускаю тот же запрос, я больше не вижу их:
SQL> select * from v_23
2 /
ID COL1 COL2 COL3 COL4
---------- ---------- ------------------------------ --------- ----------
277834 1880 GV_$MAP_EXT_ELEMENT 15-OCT-07 4081
304540 36227 /375c3e3_TCPChannelReaper 15-OCT-07 36
1111897 17944 /8334094a_CGCast 15-OCT-07 17
1364675 42323 java/security/PublicKey 15-OCT-07 42
1555115 3379 ALL_TYPE_VERSIONS 15-OCT-07 3
2073178 3355 ALL_TYPE_METHODS 15-OCT-07 3
2286361 68816 NV 15-OCT-07 68
2513770 59414 /5c3965c8_DicomUidDoc 15-OCT-07 59
2560277 66973 MGMT_MNTR_CA 15-OCT-07 66
2700309 45890 /6cc68a64_TrustManagerSSLSocke 15-OCT-07 45
2749978 1852 V_$SQLSTATS 15-OCT-07 6395
2829080 24832 /6bcb6225_TypesTypePair 15-OCT-07 24
3205157 55063 SYS_NTsxSe84BlRX2HiXujasKy/w== 15-OCT-07 55
3236186 23830 /de0b4d45_BaseExecutableMember 15-OCT-07 23
3276764 31296 /a729f2c6_SunJCE_n 15-OCT-07 31
3447961 60129 HHGROUP 15-OCT-07 60
3517106 38204 java/awt/im/spi/InputMethod 15-OCT-07 38
3723931 30332 /32a30e8e_EventRequestManagerI 15-OCT-07 30
3877332 53700 EXF$XPVARCLST 15-OCT-07 53
4630976 21193 oracle/net/nl/NetStrings 15-OCT-07 21
20 rows selected.
SQL> exec ctx_pkg.set_user_id('FOX_IN_SOCKS')
PL/SQL procedure successfully completed.
SQL> select * from v_23
2 /
no rows selected
SQL>
Итак, проблемы:
- , чтобы установить токен, которыйвы можете использовать автоматически для уникальной идентификации пользователя
- , чтобы найти хук в вашем соединительном коде, который может устанавливать контекст каждый раз, когда пользователь получает сеанс
- , что не менее важно, чтобы найти хук вВаш код отключения, который может сбрасывать контекст каждый раз, когда пользователь покидает сеанс
Кроме того, не забудьте очистить таблицу, как только пользователь закончит с ней.