вторник, 8 ноября 2011 г.

Массивы в PL/SQL

PL/SQL, являясь процедурным расширением языка структурированных запросов SQL, имеет все необходимые составляющие для полнофункционального программирования логики. Ветвления, циклы, массивы и т.д. - все как у людей:) Работа с массивами в PL/SQL, однако, отличается от стандартного для многих распространенных языков программирования подхода.

С массивами, как известно, можно делать три вещи: объявлять массив, добавлять/изменять/читать данные по индексу и обходить массив в цикле. Эти действия мы и рассмотрим.



Определение массива PL/SQL

Для определения массива необходимо описать тип данных в массиве и затем объявить переменную созданного типа:

declare

 TYPE arr_type IS TABLE OF VARCHAR2(128)
 INDEX BY BINARY_INTEGER;

 arr arr_type;

begin
 null;
end;

Таким образом мы определили тип arr_type, являющийся описанием массива. Каждый массив этого типа, как видно из описания, хранит данные типа VARCHAR2(128), то есть строки длиной до 128 символов, используя в качестве ключа массива тип BINARY_INTEGER, то есть целые числа.

Определив тип, мы можем создать массивы этого типа, как показано в примере выше. Переменная arr является массивом типа arr_type.

Работа с элементами массива


Добавляются элементы массива в PL/SQL практически так же, как и в других языках программирования, вместо традиционных квадратных скобок используются круглые:

-- включим вывод данных
SET SERVEROUTPUT ON
DECLARE
 TYPE arr_type IS TABLE OF VARCHAR2(128)
 INDEX BY BINARY_INTEGER;
 arr arr_type;
 str VARCHAR2(500);
begin

-- добавляем элементы в массив
arr(1)  := 'Креслице';
arr(2)  := 'Табуреточка';
arr(-4) := 'Стульчик';
arr(7)  := 'Диванище';

-- присваиваем строковой переменной str значение элемента массива
str := arr(2);

-- выводим значение элемента
DBMS_OUTPUT.put_line('arr(-4) = ' || arr(-4));

end;

В скобках указывается индекс элемента массива. Конечно, индекс должен принадлежать типу индекса для массива - BINARY_INTEGER в нашем случае.

Обход массива в цикле


Массивы тем собственно и хороши, что их можно в цикле обходить:) Вариантов обхода может быть много, некоторые показаны ниже.


SET SERVEROUTPUT ON
DECLARE
 TYPE arr_type IS TABLE OF VARCHAR2(128)
 INDEX BY BINARY_INTEGER;
 arr arr_type;
 cnt BINARY_INTEGER;
begin

arr(1)  := 'Креслице';
arr(2)  := 'Табуреточка';
arr(-4) := 'Стульчик';
arr(7)  := 'Диванище';

-- ОБХОДИМ МАССИВ В ПОРЯДКЕ ПЕРВЫЙ ЭЛЕМЕНТ-ПОСЛЕДНИЙ ЭЛЕМЕНТ

-- начальное значение счетчика цикла - индекс
-- первого элемента массива
cnt := arr.FIRST;

LOOP
 -- выводим текущий элемент
 DBMS_OUTPUT.put_line('Element is: ' || arr(cnt));
 -- условие выхода - равенство счетчика индексу последнего элемента
 EXIT WHEN cnt = arr.LAST;
 -- счетчик устанавливаем на индекс следующего элемента
 cnt := arr.NEXT(cnt);
END LOOP;

-- ОБХОДИМ МАССИВ В ПОРЯДКЕ ПОСЛЕДНИЙ ЭЛЕМЕНТ-ПЕРВЫЙ ЭЛЕМЕНТ

-- начальное значение счетчика цикла - индекс
-- последнего элемента массива
cnt := arr.LAST;

LOOP
 -- выводим текущий элемент
 DBMS_OUTPUT.put_line('Element is: ' || arr(cnt));
 -- условие выхода - равенство счетчика индексу первого элемента
 EXIT WHEN cnt = arr.FIRST;
 -- счетчик устанавливаем на индекс предыдущего элемента
 cnt := arr.PRIOR(cnt);
END LOOP;

end;

Здесь мы использовали несколько методов массивов PL/SQL, приведем их и некоторые другие (первоисточник):

АтрибутВозвращаемый типОписание
COUNTNUMBERВозвращает число строк таблицы.
DELETE-Удаляет строки таблицы.
EXISTSBOOLEANВозвращает TRUE если указанный элемент находится в таблице иначе FALSE.
FIRSTBINARY_INTEGERВозвращает индекс первой строки таблицы.
LASTBINARY_INTEGERВозвращает индекс последней строки таблицы.
NEXTBINARY_INTEGERВозвращает индекс строки таблицы, которая следует за указанной строкой.
PRIORBINARY_INTEGERВозвращает индекс строки таблицы, которая предшествует указанной строке.

Таким образом, обход в цикле реализуется следующим образом в зависимости от порядка обхода элементов:

  1. счетчику цикла присваивается начальное значение, равное индексу первого (или последнего) элемента массива;
  2. в цикле выполняются необходимые действия и происходит проверка, не равен ли счетчик цикла индексу последнего (первого) элемента массива;
  3. в случае равенства цикл останавливается;
  4. в противном случае вычисляет новое значение индекса массива (для следующего или предыдущего элемента) и цикл повторяется.
Вот и вся мат часть работы с PL/SQL массивами. Удачи!

6 комментариев:

  1. Спасибо, Леша) Помог юным программистам)

    ОтветитьУдалить
  2. Спасибо. А есть возможность создавать многомерные массивы?

    ОтветитьУдалить
    Ответы
    1. Можно представлять многомерные массивы в стиле Fortran.

      Удалить
  3. Коротко и делу. Полезная статья для начинающих.

    ОтветитьУдалить
  4. Код автором либо совсем не проверялся, либо правился без проверки.
    В коде вместо a. для исполнения требуется arr.

    ОтветитьУдалить
    Ответы
    1. Спасибо Вам, что написали о найденном! Исправил.

      Удалить