Oracle DB, Oracle APEX, Linux etc.

среда, 20 июля 2011 г.

Oracle APEX: Процедуры в URL - F

В APEX переход по страницам приложения - это обращение к процедурам. И одной из самых используемых процедур является F. Чтобы увидеть её, можно просто почаще смотреть в строку адреса во время работы с APEX. Там обнаружится что-то вроде такого:

http://work:8080/apex/f?p=4000:1500:434361572702804:::::

С помощью этой процедуры можно создавать ссылки к различным страницам приложений APEX. Я не буду здесь повторять раздел документации Oracle® Application Express Application Builder User's Guide: 2 Application Builder Concepts - Understanding URL Syntax. По крайней мере, ту его часть, которая описывает структуру значений параметра P. Давайте лучше поговорим о том, что упоминается не так часто.

Итак, F - это своеобразная обёртка для WWV_FLOW.SHOW (aka APEX_APPLICATION.FLOW). В этой процедуре устанавливаются различные глобальные переменные, использующиеся для отображения страницы, параметр P разбирается на составляющие, которые передаются в APEX_APPLICATION.FLOW.

Кроме параметра P у процедуры F есть ещё параметры. Часть из них описана в документации, часть можно увидеть в URL при работе с приложениями. Вот неполный список:

  • p_sep - разделитель, который используется, чтобы разбить значение параметра P в PL/SQL-коллекцию.
  • p_trace - если равен "YES", apex_application.show будет создавать трассировочный файл. Подробнее в документации: Enabling SQL Tracing and Using TKPROF.
  • c - workspace_id или название (workspace) рабочего пространства из apex_workspaces. По значению этого параметра выбирается и устанавливается группа безопасности (aka security group ID). Это понадобится, к примеру, при вызове страниц приложения с тем же псевдонимом в другом рабочем пространстве. Упоминается в документации: Calling a Page Using an Application and Page Alias.
  • cs - контрольная сумма, которой проверяются значения параметров. Первый символ - тип кинтрольной суммы, остальная строка - собственно контрольная сумма.
  • success_msg - текст для отображения сообщения об успешном выполнении.
  • notification_msg - текст для отображения уведомления.
  • tz, p_lang, p_territory - NLS-параметры: временная зона, язык и территория. Значением p_lang можно менять язык сессии, который используется при переводе приложения с настройкой Application Language Derived From = Session.

Сообщения по теме:
Oracle APEX: Процедуры в URL - P
Oracle APEX: Процедуры в URL - Z

Читать далее

пятница, 8 июля 2011 г.

Oracle APEX: Убить Билла

Как удалить вручную сессию APEX, если известен её ID? Всё довольно просто.

Для начала подумаем, где должна использоваться возможность удаления сессии. Правильно, там где пользователь завершает сеанс в приложении - смотрим на ссылку LOGOUT_URL:

http://localhost:8888/apex/wwv_flow_custom_auth_std.logout?p_this_flow=4000&p_next_flow_page_sess=4550:8:8297564516445573

Нужное нам находится в wwv_flow_custom_auth_std.logout. Давайте глянем ещё на процесс, который выполняется при принудительном удалении сессий администратором экземпляра APEX. Заходим в Administration->Application Express Internal Administration, переходим на Manage Instance->Session State->Purge Session, by age. Это страница 66 приложения 4050. Посмотрим, что за процессы выполняются при обработке этой страницы:

set long 5000
select process_source 
  from apex_application_page_proc 
 where application_id = 4050 and page_id = 66;

PROCESS_SOURCE
--------------------------------------------------------------------------------
wwv_flow_cache.purge_oldest_sessions (
p_num_sessions_to_purge     => :P66_MAX_SESSIONS,
p_purge_sess_older_then_hrs => :P66_AGE * 24);

Ещё одна наводка - пакет wwv_flow_cache с множеством процедур purge_%.

Произведя ритуал Unwrap над этими пакетами, можно увидеть, что удаляется сессия APEX с идентификатором :p_id довольно просто:

delete apex_040000.wwv_flow_sessions$ where id = :p_id;

Всё, остальные изыски из этих процедур вроде подсчёта удалённых сессий, переноса их в wwv_flow_purged_sessions$ и изменения значения в печеньке на -1 нам не нужны.

Убить Билла сессию APEX - проще простого. Была бы лицензия на убийство в виде соответствующей привилегии на таблицу apex_040000.wwv_flow_sessions$...
Читать далее

суббота, 18 июня 2011 г.

PL/SQL Challenge: Now with APEX flavor!

Сегодня на PL/SQL Challenge появилась первая викторина по APEX. Надеюсь, многие захотят поучаствовать: для проверки знаний, из интереса, ради призов и чтобы узнать что-то новое.

Удачи!
Читать далее

суббота, 28 мая 2011 г.

Oracle APEX 4.0: Небольшой пример плохой реализации

Сегодня я хотел бы упомянуть о том, как не надо разрабатывать. И в качестве примера у нас будет... APEX 4.0 Application Builder. Думаю, все разработчики приложений, использующие эту среду, видели страницу атрибутов элемента, динамического действия или региона. Например, выбираем у элемента Display As=Select List - и появляется регион List of Values с соответствующими настройками. В общем, ту страницу, на которой в зависимости от типа объекта атрибуты и регионы прячутся и показываются в зависимости от выбранных значений.

Отличная цель: оживить и разгрузить страницу, убирая неподходящие поля с глаз долой.

Плохая реализация: при загрузке страницы показываются все элементы страницы, а уже потом Dynamic Actions прячут ненужное, запускаясь после полной загрузки страницы. Это здорово, что у динамических действий есть возможность запуска при загрузке страницы (флажок Fire On Page Load). Но когда пользователь видит мельтешащие поля, которые только что были, а потом куда-то пропали - это ужасно. И с эстетической точки зрения, и с точки зрения здравого смысла. Зачем показывать, а потом тут же (а иногда - и не тут, если страница загружается медленно) скрывать часть интерфейса? Лучше не показывать её вообще.

Как стоило сделать: воспользоваться возможностью указать соответствующий CSS-стиль в свойствах региона, элемента и в их шаблонах. Скрыть всё то, что показывается динамически в зависимости от каких-либо условий.
display: none;
Не отмечать Fire On Page Load у действий, которые что-либо скрывают. (Потому что они сохраняют старое значение свойства display и потом используют его при показе элемента.) Отмечать Fire On Page Load у действий, которые что-либо показывают. Как итог, на странице появятся вначале все обязательные настройки, а потом отобразится все доступные для изменения настройки.

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

PS: Вышеописанный подход, в принципе, касается не только приложений APEX. Чем меньше пользователь видит ненужного, чем меньше зряшной работы выполняет приложение, тем лучше.

Читать далее

понедельник, 14 февраля 2011 г.

Oracle APEX: Collections Debug 2

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

create or replace procedure copy_apex_session_env 
  ( p_session_id apex_workspace_sessions.apex_session_id%type
  , p_app_id apex_applications.application_id%type )
as
  l_session apex_workspace_sessions%rowtype;
  l_app_id apex_applications.application_id%type;
begin
  begin
    select * into l_session
      from apex_workspace_sessions s 
     where apex_session_id = p_session_id;
  exception
    when no_data_found then
      raise_application_error(-20001, 'Invalid Session ID!');
  end;
  
  begin
    select application_id into l_app_id
      from apex_applications
     where application_id = p_app_id
       and workspace_id = l_session.workspace_id;
  exception
    when no_data_found then
      raise_application_error(-20002, 'Invalid Application ID!');
  end;  
  
  apex_custom_auth.set_session_id(p_session_id => l_session.apex_session_id);
  apex_custom_auth.set_user(l_session.user_name);
  wwv_flow_api.set_security_group_id(l_session.workspace_id);
  apex_application.g_flow_id := l_app_id;
end copy_apex_session_env;
/

Она должна создаваться в схеме разбора приложения (без этого не сработает wwv_flow_api.set_security_group_id). Теперь, чтобы увидеть данные соответствующей коллекции, достаточно вызвать процедуру и выполнить запрос:

exec copy_apex_session_env(p_session_id => &session_id, p_app_id => &app_id);

select * from apex_collections where collection_name = 'YOUR_COLLECTION_NAME';

Читать далее

понедельник, 7 февраля 2011 г.

Oracle APEX: Collections Debug

Самый простой, хоть и не очень честный способ отладки при работе с коллекциями APEX - смотреть в таблицы wwv_flow_collections$ и wwv_flow_collection_members$ схемы, в которую установлен APEX. Если, конечно, есть соответствующие права, и известны приложение (FLOW_ID) и сессия (SESSION_ID), работающие с коллекцией.
Читать далее

понедельник, 27 декабря 2010 г.

Пара фраз о JSON

Вначале - о проблеме. Сколько раз сталкиваюсь, что JSON-парсер в Firefox вдруг по какой-то причине спотыкается на казалось бы правильной JSON-строке. Решение довольно простое - завернуть эту строку в обычные скобки:

  var result = JSON.parse("("+json_string+")");

Теперь - о довольно удобном средстве работы с JSON из PL/SQL. Вам хочется организовать эту работу так?

declare
  l_json json := json();
begin
  l_json.put('name', 'Taras');
  l_json.put('sons', json_list('["Mykola", "Vasyl"]'));
  htp.p(l_result.to_char);
end;
/

Тогда обратите своё внимание на проект PL/JSON. Думаю, он облегчит Вам жизнь - особенно, если Вы не поленитесь просмотреть короткие уроки.
Читать далее