FoxBase!
msgbartop
Блог Oracle разработчика
msgbarbottom
foxbase

27.04.2010 Сортировка индексных массивов Oracle PL/SQL

Применение индексных массивов в Oracle PL/SQL нами уже обсуждалось в статьях Индексные массивы в Oracle PL/SQL и PL/SQL и Java. Кто быстрее? 
В этой статье поговорим о различных методах сортировки индексных массивов. 

Сортировка по индексному ключу

Индексные массивы изначально ранжированы по ключу. Мы легко можем получить элементы массива в порядке возрастания или убывания значения ключа. Для этого используются стандартные программные конструкции получения элементов индексного массива.  
Допустим, у нас объявлен тип простого числового индексного массива:

TYPE n_arr IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
В PL/SQL коде для получения элементов массива в порядке возрастания значения числового индексного ключа используется следующая конструкция:

DECLARE
  arr n_arr;
  n PLS_INTEGER;
BEGIN
  ... -- Заполнение элементов индексного массива arr
  n:=arr.FIRST;
  WHILE n IS NOT NULL
  LOOP
    -- Выполняем требуемые действия
    n:=arr.next(n);
  END LOOP;
END;
Для получения элементов в порядке убывания индексного ключа код необходимо изменить следующим образом:

n:=arr.LAST;
WHILE n IS NOT NULL
LOOP
  -- Выполняем требуемые действия
  n:=arr.PRIOR(n);
END LOOP;

Произвольная сортировка

Каким образом отсортировать индексный массив по другим значениям, отличным от ключа? Стандартными средствами PL/SQL этого сделать нельзя. В конце концов сама природа индексных массивов такова, что они изначально отсортированы по значению индекса-ключа. Но применив некоторые алгоритмические ухищрения мы можем это сделать. Для этих целей используем вспомогательный двумерный индексный массив для выполнения сортировки:

TYPE n_sort IS TABLE OF n_arr INDEX BY PLS_INTEGER;
Код, выполняющий сортировку по значению элементов массива, будет выглядеть следующим образом:

DECLARE
  arr n_arr;
  arr1 n_arr;
  sort n_sort;
  n PLS_INTEGER;
  k PLS_INTEGER;
  val NUMBER;
BEGIN
  ... -- Заполнение элементов индексного массива arr
  -- Сортировка
  n:=arr.FIRST;
  WHILE n IS NOT NULL
  LOOP
    sort(arr(n))(n):=NULL;
    n:=arr.next(n);
  END LOOP;
  -- Формирование отсортированного по возрастанию массива arr1, содержащего в качестве значения ключи из массива arr
  n:=sort.FIRST; -- n:=sort.last; для выполнения сортировки по убыванию
  WHILE n IS NOT NULL
  LOOP
    k:=sort(n).FIRST;
    WHILE k IS NOT NULL
    LOOP
      arr1(arr1.COUNT+1):=k;
      k:=sort(n).next(k);
    END LOOP;
    n:=sort.next(n); -- n:=sort.prior(n); для выполнения сортировки по убыванию
  END LOOP;  
END;
После выполнения приведенного выше кода мы имеем массив arr1, содержащий в качестве значений ключи массива arr, отсортированный по возрастанию (убыванию) значений массива arr. Цикл по массиву arr по возрастанию (убыванию) его значений будет выглядеть следующим образом:

FOR n IN arr1.FIRST..arr1.LAST
LOOP
  val:=arr(arr1(n));
END LOOP;
Приведенные решение выглядит довольно простым. Ключевым элементом этого метода можно считать двумерный массив sort. Конструкция sort(arr(n))(n):=null; заполняет этот массив сначала значениями массива arr, но, так как они могут повторяться, то значения ключа запоминаются во втором измерении массива sort.   
Используя приведенную выше методику можно реализовать сколь угодно сложные методы сортировки, фактически создавая вспомогательный индексный массив с требуемыми условиями сортировки. 

www.foxbase.ru 




Смотрите также:



Оставьте свой комментарий

Вы должны быть авторизированны, чтобы оставить комментарий.