Как задать и использовать константу в виде коллекции на Pl/SQL.

Иногда в реальных задачах необходимо в константах хранить какую-либо коллекцию. На языке pl/sql просто создать коллекцию и перечислить через запятую данные, которые она будет содержать, нельзя. Такое возможно только с массивами, у которых строго задан размер и тип элементов. Если же возникла необходимость сделать предопределенную коллекцию-константу, то в этом случае её не получится проинициализировать простым перечислением данных. Чтобы проинициализировать коллекцию–константу, необходимо задать функцию, которая вернет заполненную коллекцию для присвоения её в указанную переменную. Выглядеть это будет примерно так, как показано ниже.

Например, мы хотим создать коллекцию действий пользователя, индекс элемента которой будет представлять собой символьный код операции, а значение — название операции, которое увидит пользователь. Зададим возможные действия константами, так как в дальнейшем в программе они обрабатываются.

subtype typeActionName is varchar2(50);                      -- Тип: Код действия
type typeActionCol is table of typeActionName                -- Тип: Список действий
index by varchar2(200);

cOperSetDefault       constant typeOperName:= 'SetDefault’;
cOperUndoDefault      constant typeOperName:= 'UndoSetDefault';
cOperChangeParam      constant typeOperName:= 'ChangeParam';
cOperClose            constant typeOperName:= 'CLOSE';
cOperOpen             constant typeOperName:= 'UNCLOSE';
cOperDelete           constant typeOperName:= 'Delete';
cOperAddItem          constant typeOperName:= 'AddItem';

function setActionCollection  return typeOperCol;            --функция задания массива кода операции и имени операции

ActionCollection constant typeOperCol:= setActionCollection;  --список действий пользователя

function setActionCollection return typeActionCol
is
pOperCol  typeActionCol;
begin
pOperCol(cActionSetDefault)    := 'Установить параметры по умолчанию';
pOperCol(cActionUndoDefault)   := 'Вернуть параметры, которые были до сброса';
pOperCol(cActionCloseAgree)    := 'Закрыть соглашение';
pOperCol(cActionOpenAgree)     := 'Открыть соглашение';
pOperCol(cActionChangeParam)   := 'Изменить значение параметров;
pOperCol(cActionDelete)        := 'Удалить элемент';
pOperCol(cActionAddItem)       := 'Добавить элемент';
return  pOperCol;
end;

Таким образом можно задать коллекцию, содержащую данные любого составного типа. В зависимости от типа будет меняться только функция его заполнения (либо усложнятmся, либо упрощаться). После того, как мы объявили свою константу, возникает вопрос: как выполнить какие-либо операции при помощи данных, которые мы проинициализировали? Если рассматривать коллекцию, которую я привела выше, то для обхода её потребуется массив индексов.

type typeColkeys is varray(7) of typeOperName;

--массив для индексации действий
Collectionkeys typeColkeys  := typeColkeys (cActionSetDefault, cActionUndoDefault, cActionCloseAgree, cActionOpenAgree, cActionChangeParam, cActionDelete, cActionAddItem);

А после этого можно будет пройти по коллекции циклом и выполнить необходимые вам операции.

FOR i IN 1..ActionCollection.count loop
--выполняем необходимые операции
--Collectionkeys(i) – это будет код действия пользователя
--ActionCollection(Collectionkeys(i)) –это будет заголовок действия
end loop;

Вещи, конечно, несложные, но приводят к ошибкам и вопросам. Один раз использовав такую конструкцию, вы обязательно запомните, как лучше с ней работать. В функции инициализации можно заполнить коллекцию и из базы, если вам необходимо подгружать информацию, а не хранить её напрямую в пакете. В этом случае придется также и подумать над тем, что использовать в качестве массива индексов, так как при создании у массива задается определенное количество элементов, что при загрузке из базы просто не приемлемо.