Чтобы не искать по коду и не выдумывать повторно, решил сохранить тут алгоритм постраничной обработки массива данных.
Массив данных задается переменной l_data с определенной заранее длиной, а итератор страниц задается номером страницы l_page_no, начиная с 1, длиной страницы l_page_data_length, а также стартовым и финишным индексами страницы в массиве.
Для оптимизации работы с памятью копирование страницы в отдельный массив не предусмотрено, но может быть выполнено при модификации алгоритма.
declare -- данные для обработки
type t_data is table of number;
l_data t_data := t_data();
-- обеспечение постраничной обработки
l_page_no number := 1; -- индекс страницы
l_data t_data := t_data();
-- обеспечение постраничной обработки
l_page_no number := 1; -- индекс страницы
l_page_data_length number := 10; -- длина страницы
l_idx_from number; -- стартовый индекс
l_idx_to number; -- финишный индекс
l_idx_to number; -- финишный индекс
begin
l_data.extend(127);
dbms_output.put_line('DATA_LEN='||l_data.count||' FIRST='||l_data.first||' LAST='||l_data.last||' PAGE_LEN='||l_page_data_length);
loop
-- вычисляем стартовый и финишный индексы текущей страницы
l_idx_from := 1 + ((l_page_no - 1) * l_page_data_length);
l_idx_to := least(l_data.last, l_idx_from + l_page_data_length - 1);
exit when l_idx_from > l_data.last;
dbms_output.put_line('PAGE ('||l_page_no||'): FROM='||l_idx_from||' TO='||l_idx_to||' PAGE_LEN='||to_char(1+(l_idx_to-l_idx_from)));
l_page_no := l_page_no + 1;
end loop;
end;
l_idx_from := 1 + ((l_page_no - 1) * l_page_data_length);
l_idx_to := least(l_data.last, l_idx_from + l_page_data_length - 1);
exit when l_idx_from > l_data.last;
dbms_output.put_line('PAGE ('||l_page_no||'): FROM='||l_idx_from||' TO='||l_idx_to||' PAGE_LEN='||to_char(1+(l_idx_to-l_idx_from)));
l_page_no := l_page_no + 1;
end loop;
end;