Oracle DB, Oracle APEX, Linux etc.

суббота, 31 декабря 2011 г.

НГ-2012

Желаю в наступающем Новом году счастья, здоровья, достаточно воображения для задумок и достаточно сил для их воплощения!
Читать далее

среда, 12 октября 2011 г.

Oracle: ORA-00600 [16305] + ORA-03113 при открытии БД

Обновил в очередной раз Debian на своей домашней машине, запускаю экземпляр Oracle - и что я вижу? ORA-03113 в консоли + ORA-00600 [16305] в alert.log. Порыскав немного по OTN Forums и MOS и попутно заглядывая в трассу PMON, наткнулся на Doc ID 466056.1. Проверяя кэйс, выполнил ifconfig - а в выводе нет работающего loopback-интерфейса. В общем, для решения проблемы было достаточно его поднять:
sudo ifup lo
И можно смело запускать экземпляр.
Читать далее

Oracle: V$SESSION_LONGOPS и несколько одновременных длинных операций

Для того, чтобы отразить в V$SESSION_LONGOPS состояние нескольких одновременных длительных операций - например, общее выполнение процесса и конкретный большой шаг - нужно сохранять значение параметра slno процедуры DBMS_APPLICATION_INFO.set_session_longops. Используя затем пару значений (rindex,slno), можно менять необходимую строку в V$SESSION_LONGOPS. Вот пример работы с двумя длительными операциями:
declare
  first_row pls_integer := dbms_application_info.set_session_longops_nohint;
  second_row pls_integer := dbms_application_info.set_session_longops_nohint;
  slno1 pls_integer;
  slno2 pls_integer;
begin
  dbms_application_info.set_session_longops(rindex => first_row
                                            ,slno => slno1
                                            ,op_name => '1_op'
                                            ,sofar => 1
                                            ,totalwork => 2
                                            ,units => 'step'
                                           );
  dbms_application_info.set_session_longops(rindex => second_row
                                            ,slno => slno2
                                            ,op_name => '2_op'
                                            ,sofar => 1
                                            ,totalwork => 1
                                            ,units => 'step'
                                           );
  dbms_application_info.set_session_longops(rindex => first_row
                                            ,slno => slno1
                                            ,op_name => '1_op'
                                            ,sofar => 2
                                            ,totalwork => 2
                                            ,units => 'step'
                                           );
 
end;
/

select MESSAGE from v$session_longops where (sid,serial#) =
(select sid,serial# from v$session where audsid = USERENV('SESSIONID'));
Тема на SQL.RU: set_session_longops Можно ли вернуться к предидущей строке?
Читать далее

пятница, 5 августа 2011 г.

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

Последняя из "маленьких" встроенных процедур APEX, которые можно использовать в URL: Z.

Эта процедура используется для подсчёта кликов по ссылкам. Обёрткой вокруг неё является APEX_UTIL.COUNT_CLICK, поэтому можно смело ориентироваться на документацию, меняя в примерах APEX_UTIL.COUNT_CLICK на Z. У Z есть следующие параметры:

  • p_url — URL, к которому необходимо перейти.
  • p_cat — категория, к которой Z причисляет клик.
  • p_id — вторичный числовой идентификатор клика. ID приложения, номер страницы — всё то, что поможет Вам в дальнейшем выделить именно эти клики из остальных.
  • p_user — пользователь, который сделал клик.
  • p_company, p_workspace — ID рабочего пространства. Если p_company пустое, то используется p_workspace. Если оба эти параметра пустые, то Z не сохраняет информацию о клике, а просто перенаправляет на p_url.

Пример URL с этой процедурой:

z?p_url=w3.org&p_cat=w3c&p_company=&WORKSPACE_ID.

Информацию, собранную Z, можно просмотреть в представлении APEX_WORKSPACE_CLICKS.


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

Читать далее

четверг, 4 августа 2011 г.

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

Ещё одна используемая при создании URL процедура: P.

Она не завраплена, так что её код можно легко увидеть:

create or replace
procedure p (
    n       in varchar2 default null,
    p_mime_type in varchar2 default null,
    p_inline    in varchar2 default 'NO')

-- Copyright (c) Oracle Corporation 2001. All Rights Reserved.
--
--    DESCRIPTION
--      View a page given a page ID
--
--    SECURITY
--      Public shortcut
--
--    NOTES
--
--    EXAMPLES:
--

is
begin
     if n is null then
         htp.p(wwv_flow_lang.system_message('p.valid_page_err'));
         return;
     end if;
     --
     wwv_flow_file_mgr.get_file (
        p_id => n,
        p_mime_type => p_mime_type,
        p_inline => p_inline);
end p;

P используется, чтобы скачать загруженные файлы, которые можно найти в представлении APEX_APPLICATION_FILES (aka WWV_FLOW_FILES, построено на таблице FLOW_FILES.WWV_FLOW_FILE_OBJECTS$). У этой процедуры не так много параметров:
  • n — ID файла, который необходимо скачать.
  • p_mime_type — устаревший параметр для указания MIME-типа файла. Сейчас информация берётся из соответствующих столбцов записи в APEX_APPLICATION_FILES.
  • p_inlineNO, чтобы предложить пользователю скачать файл; YES, чтобы браузер отобразил его.
Пример относительного URL для скачивания файла с ID=1234567891011:
p?n=123456789101112&p_inline=NO


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

Читать далее

среда, 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), работающие с коллекцией.
Читать далее