Совершенствование приложений Oracle Forms

Блоки на основе FROM CLAUSE

Показывать лекцию целиком

Ранее мы рассматривали создание блоков на основе таблиц, представлений, синонимов. В принципе это достаточный набор объектов, так как для реализации иерархических запросов JOIN (cross, natural, inner, outer и т.д.) или запросов с группировкой вам достаточно будет создать блок на основе представления. А что делать, если у разработчика нет привилегии на создание представления? Или необходимо сделать блок на основе функции? Ответом на эти вопросы как раз и является свойство блока Query Data Source Type — FROM CLAUSE.

Свойства для работы с FROM CLAUSE

Для начала определимся, что такое FROM CLAUSE.

FROM CLAUSE используется в качестве источника данных ( Data Source ) для блока, позволяющего использовать вложенные операторы SELECT в конструкции FROM. Значение, возвращаемое FROM CLAUSE, – это подмножество записей первоначального (original query) запроса. В основном FROM CLAUSE используется для реализации соединения (joins), связывания (lookups), вычисления и агрегации без создания представления на сервере, поэтому FROM CLAUSE может также применяться как прототип представления и повысить производительность вашего приложения.

Примечание: блоки, основанные на FROM CLAUSE , – это блоки типа Query Only, то есть блоки, позволяющие выполнять только запросы.

Перейдем к практической части, в которой мы выполним два несложных упражнения:

  • создание блока на основе запроса с группировкой;
  • создание блока на основе Pipelined Function.
  • Блок на основе запроса с группировкой

    Для начала рассмотрим пример с созданием блока на основе запроса с группировкой.

  • Создайте таблицу NUMB:
    create table numb(A number);
  • Заполните таблицу значениями:
    begin
     for i in 1..10 loop
      insert into NUMB values(i); 
     end loop; 
    end;
  • Измените таблицу так, чтобы появились дубли:
    update NUMB set A=4 where A=7; 
    update NUMB set A=5 where A=6;
  • Проверьте содержимое таблицы:
    select * from NUMB;
    A --------
    1
    2
    3
    4
    5
    5
    4
    8
    9 10
    10 rows selected.
  • Выполните запрос с группировкой, который будет источником для блока:
    select A from numb group by a;
    A --------
    1
    2
    3
    4
    5
    8
    9 10
    8 rows selected.
  • Теперь, когда все готово для выполнения примера, создадим новую форму FORM_1. Создайте блок данных вручную. Выберите блок в объектном навигаторе и вызовите палитру свойств. Установите свойства блока следующим образом:

  • Query Data Source Type – определяет тип источника данных для блока. Установите этот параметр на FROM CLAUSE.
  • Query Data Source Name – текст вложенного запроса (nested query). В этом свойстве введите текст запроса:
    select A from numb group by a
  • Свойство Database item установите равным " Yes ".
  • Name – значение этого свойства установите равным " Num ".
  • Создайте одну кнопку и один текстовый элемент с параметрами:

  • Свойство Database item установите равным " Yes " (иначе получите ошибку unable to perform query).
  • Column name – это свойство установите равным A (имя должно совпадать с именем столбца в запросе, иначе также получите ошибку unable to perform query).
  • Создайте триггер WHEN-BUTTON-PRESSED:

    go_block ('NUMB'); 
    execute_query;

    Мы рассмотрели очень простой, но показательный пример, который поможет вам понять назначение FROM CLAUSE и способы его использования в реальных и более сложных задачах.

    Создание блока на основе Pipelined Function

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

  • написание функции;
  • создание формы.
  • Приступим к первой части.

    Создадим простую Pipelined -функцию, возвращающую набор данных в виде последовательности чисел:

    create type "virtual_table_type" as table of number;
    create or replace function "pipe_table" (p_num_rows in number, l_order varchar2)
    return "virtual_table_type" pipelined
    is type t_data is ref cursor; 
    c_data t_data; 
    cursor c1 is select * from numb; 
    c2 c1%rowtype; 
    begin
     open c_data for 'select * from numb 
      order by'||l_order; 
     for i in 1 .. p_num_rows loop
      fetch c_data into c2; pipe row(c2.a); 
     end loop; 
     return; 
    end "pipe_table";
    select * from table("pipe_table"(5,' a desc'));
    COLUMN_VALUE
    ---------
    10
    9
    8
    5
    5

    Функция готова, теперь можно перейти к следующему шагу. Но прежде чем начать, давайте рассмотрим еще один небольшой пример, чтобы не ограничиваться отображением данных из Pipelined -функции и показать, как можно другому блоку назначить новый источник данных.

  • К существующей форме добавьте еще один базовый блок на таблицу Numb с одним текстовым полем А. В блоке NUM измените свойство Query Data Source Name на select * from table(vt(5,' a desc')).
  • Добавьте в триггер WHEN-BUTTON-PRESSED следующие строки:
    go_block('NUM');
    execute_query;
    go_block('NUMB');
    set_block_property('NUMB', query_data_source_type,
    get_block_property( 'NUM', query_data_source_type));
    set_block_property('NUMB', query_data_source_name,
    get_block_property( 'NUM', query_data_source_name));
    execute_query;
  • Запустите форму на выполнение. В результате у вас в обоих элементах должны отобразиться одинаковые данные. Этот простой пример должен помочь вам закрепить ранее выполненное упражнение, и вы сможете применить данную функциональность в своих приложениях. Приведем простой пример, когда, имея форму с одним блоком данных, вы хотите просматривать набор не только отсортированных данных или ограниченных условием WHERE Clause, но и сгруппированных. Вам не придется создавать много представлений на сервере – достаточно создать несколько блоков с различными источниками данных и назначать их основному при нажатии кнопки.

    Вернуться к учебному плану