Иногда в реальных задачах необходимо в константах хранить какую-либо коллекцию. На языке 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;
Вещи, конечно, несложные, но приводят к ошибкам и вопросам. Один раз использовав такую конструкцию, вы обязательно запомните, как лучше с ней работать. В функции инициализации можно заполнить коллекцию и из базы, если вам необходимо подгружать информацию, а не хранить её напрямую в пакете. В этом случае придется также и подумать над тем, что использовать в качестве массива индексов, так как при создании у массива задается определенное количество элементов, что при загрузке из базы просто не приемлемо.