Вернуться

Листинг 2. Механизм разбиения страниц

Этот пример использует механизм разбиения страниц, чтобы
обеспечить отображение большого числа записей, выбираемых по запросу.

create or replace procedure display_employees
    (display_start in number default 1,
     display_quantity in number default 15) is

--- Входной параметр 'display_start' задает начальную позицию
--- на странице непрерывной последовательности упорядоченных отображаемых
--- записей.
--- Входной параметр 'display_quantity' задает число записей, отображаемых
--- на странице.

  cursor employee_cursor is
    select   employee_number empno,
             last_name,
             first_name,
             ssn,
             title,
             birthdate
    from     employee
    order by last_name,
             first_name;

  cursor employee_count_cursor is
    select   count(*)
    from     employee;

  record_count            number := 0;
  counter                 number := 0;
  first_record_displayed  boolean := false;
  last_record_displayed   boolean := false;

  begin

--  Определение и сохранение общего числа записей в таблице 

    open employee_count_cursor;
    fetch employee_count_cursor into record_count;
    close employee_count_cursor;

    htp.htmlOpen;
    htp.headOpen;
    htp.title ('Corporate Employee List');
    htp.headClose;
    htp.bodyOpen('/Back/Texback.gif');
    htp.header (3, 'Employees');

--  Проверка правильности задания значений параметров 'display_start' 
--  и 'display_quantity'.

 if (display_start < 1) or
   (display_start > record_count) or
   (display_quantity < 1) then
   htp.print ('The specified display parameter values ' ||
                 'cause no records to be displayed.');
    else
      htp.tableOpen ('border=1 bgcolor=#ffffa0');
      htp.tableCaption ('Employee List');
      htp.tableHeader (' ');
      htp.tableHeader ('Last Name');
      htp.tableHeader ('First Name');
      htp.tableHeader ('SSN');
      htp.tableHeader ('Title');
      htp.tableHeader ('Birthdate');

      for each_emp in employee_cursor loop
        counter := counter + 1;

--  Если достигнут конец диапазона отображения, то нет необходимости  
--  продолжать цикл для получения дополнительных записей;
--  цикл (loop) уже завершен.

   if counter >= (display_start + display_quantity) then exit;

--  Иначе, если запись попадает внутрь интервала, то она должна быть
--- отображена,  ее заносят в таблицу.

   elsif (counter >= display_start) and
         (counter < (display_start + display_quantity)) then
          htp.tableRowOpen;

--  Следующее предложение отображает номер записи только в целях ссылки.

   htp.tableData (counter);
   htp.tableData (htf.anchor('zoom_in_emp?in_empno='|| 
       each_emp.empno,each_emp.last_name));
   htp.tableData (each_emp.first_name);
   htp.tableData (each_emp.ssn);
   htp.tableData (each_emp.title);
   htp.tableData (each_emp.birthdate);
   htp.tableRowClose;

--  Если первая или последняя запись уже отображены,
--  надо сохранить ее след для последующей ссылки.

    if counter = 1 then
      first_record_displayed := true;
     end if;
    if counter = record_count then
      last_record_displayed := true;
        end if;
      end if;
      end loop;
      htp.tableClose;

      htp.nl;
      htp.nl;

--- Отображение соответствующего подмножества по якорным (anchor) отметкам
--- 'Previous', 'Next', 'Top' или 'Bottom' в зависимости от того, входят ли
---  первая и/или последняя запись  в текущий диапазон отображения

   if first_record_displayed and last_record_displayed then
     htp.print ('All records displayed.');

   elsif first_record_displayed then
     htp.anchor (owa_util.get_owa_service_path ||
        'display_employees?display_start=' ||
        least ((display_start + display_quantity), 
               record_count) ||
        '&' || 'display_quantity=' || display_quantity,
        'Next');
     htp.anchor (owa_util.get_owa_service_path ||
           'display_employees?display_start=' ||
           (record_count-display_quantity + 1) ||
           '&' || 'display_quantity=' || display_quantity,
           'Bottom');
        htp.nl;
        htp.nl;
        htp.print ('Top of records displayed.');

      elsif last_record_displayed then
        htp.anchor (owa_util.get_owa_service_path ||
           'display_employees?display_start=' ||
           greatest ((display_start-display_quantity), 1) ||
           '&' || 'display_quantity=' || display_quantity,

           'Previous');
    htp.anchor (owa_util.get_owa_service_path ||
        'display_employees?display_start=1' ||
        '&' || 'display_quantity=' || display_quantity,
            'Top');
    htp.nl;
    htp.nl;
   htp.print ('Bottom of records displayed.');

      else

--  Диапазон отображаемых записей не включает,
--  ни первой, ни последней записи.

   htp.anchor (owa_util.get_owa_service_path ||
      'display_employees?display_start=' ||
      greatest ((display_start-display_quantity), 1) ||
      '&' || 'display_quantity=' || display_quantity,
      'Previous');
   htp.anchor (owa_util.get_owa_service_path ||
      'display_employees?display_start=' ||
      least ((display_start + display_quantity), 
      record_count) || '&' || 'display_quantity=' || 
            display_quantity, 
      'Next');
   htp.anchor (owa_util.get_owa_service_path ||
      'display_employees?display_start=1' ||
      '&' || 'display_quantity=' || display_quantity,
      'Top');
   htp.anchor (owa_util.get_owa_service_path ||
      'display_employees?display_start=' ||
      (record_count-display_quantity + 1) ||
      '&' || 'display_quantity=' || display_quantity,
       'Bottom');
      end if;
    end if;

    htp.bodyClose;
    htp.htmlClose;
  end;



Вернуться