Листинг 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;