Добавить в корзинуПозвонить
Найти в Дзене
Oracle APEX

Печеньки от Oracle APEX. Представление с контекстным параметром

Дальнейшая автоматизация персональных настроек и фильтрации. В предыдущей заметке мы обсуждали представление с функциональным параметром: в раздел where определения представления было включено сравнение значения столбца с результатом, возвращаемым функцией. Действительно, чтоб получить, например, представление, показывающее только сегодняшние события лога, можно записать create view ... as
select ... from ...
where ... >= trunc(sysdate)
; Никаких запретов на использование функций sysdate и trunc() в коде представления нет, все будет работать. Точно так же мы включили в код представления свою функцию, которая возвращает значение фильтрующего параметра, но перед использованием представления должны вызвать свою процедуру, которая установит необходимое значение пакетной переменной, которое вернет функция, включенная в код представления. Oracle APEX предлагает возможность дальнейшей автоматизации этого подхода. Предположим, у нас есть система на Oracle APEX, работающая с регионами РФ. Струк

Дальнейшая автоматизация персональных настроек и фильтрации.

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

create view ... as
select ... from ...
where ... >= trunc(sysdate)
;

Никаких запретов на использование функций sysdate и trunc() в коде представления нет, все будет работать. Точно так же мы включили в код представления свою функцию, которая возвращает значение фильтрующего параметра, но перед использованием представления должны вызвать свою процедуру, которая установит необходимое значение пакетной переменной, которое вернет функция, включенная в код представления.

Oracle APEX предлагает возможность дальнейшей автоматизации этого подхода.

Предположим, у нас есть система на Oracle APEX, работающая с регионами РФ. Структура регионов достаточно сложная и в иерархическом, и во временном аспектах - иногда пользователям удобно исключать какие-то регионы из всех своих дел в системе.

Исключение регионов с точки зрения пользовательского интерфейса
Исключение регионов с точки зрения пользовательского интерфейса

Причем хотелось бы сделать это так (две схемы, естественно):

  • Есть таблица регионов regions_tab в схеме-владельце и доверенное схеме-публикации экранирующее ее представление regions_vi;
  • Есть таблица исключенных пользователями регионов regions_excl_glb_tab в схеме-владельце и доверенное схеме-публикации экранирующее ее представление regions_excl_glb_vi;
  • Есть необходимые синонимы/представления в схеме-публикации;
  • Хотелось бы, чтоб представление regions_vi схемы-публикации сразу же и автоматически не включало в себя регионы, исключенные данным пользователем, как нет их вообще для всей системы во время сеанса данного пользователя.

Оказывается, при создании сессии Oracle APEX записывает в стандартный контекст сеанса userenv пару параметр/значение, значение которой содержит разделенные двоеточием имя текущего пользователя и идентификатор текущей сессии.

Значение может быть извлечено из контекста функцией sys_context() с указанием имен контекста и параметра:

sys_context('userenv', 'client_identifier')

Если предположить для простоты, что имена пользователей не имеют в своем составе цифр (это, конечно, весьма сильное допущение), то имя пользователя можно извлечь из контекста просто подавлением двоеточия и цифр:

regexp_replace(sys_context('userenv', 'client_identifier'), ':|[0-9]+', '')

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

select region_id
from regions_excl_glb_vi
where usr
= regexp_replace(sys_context('userenv', 'client_identifier'), ':|[0-9]+', '')
;

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

create view regions_vi as
select <список столбцов>
from <схема-владелец>.regions_vi
where id not in
(
select region_id
from regions_excl_glb_vi
where usr
= regexp_replace(sys_context('userenv', 'client_identifier'), ':|[0-9]+', '')
)
;

Точно так же просто может быть решена частая и насущная задача показа текущему пользователю только его активов.