Новые объектно-реляционные возможности Oracle расширяют систему типов данных, предоставляемых сервером, инкапсулируя в последних бизнес-правила и логику серверного приложения. Сложная логика реляционной модели может быть представлена объектным представлением – уникальной технологией Oracle, и таким образом соединить реляционные модели с объектной технологией Oracle 8.
Создать схему, представляющую движение материалов по складам предприятия. Для каждого склада назначать ответственное лицо из штатного списка предприятия (таблица BASE). На складе размещается материал, для которого необходимо учитывать всю хронологию поступления от внутренних и внешних заказчиков - покупателей. Внешний заказчик имеет статус 0 и должен выбираться из справочника агентов, при наличии статуса 0 у поставщика - покупателя материала, он должен выбираться из справочника складов - внутренняя преброска. Постановка задачи далека от реальной жизни, она придумана в учебных целях.
Итак приступим:
Пример создания атрибутов и методов класса с помощью Oracle Schema Manager. Соответственно генерируется SQL текст следующего вида:
Добавляем в класс новые методы c помощью Oracle Schema Manager:
Реализация методов должна учитывать прагму RESTRICT_REFERENCES аналогично пакетным процедурам и функциям. В результате получаем полный скрипт создания объектного типа:
Реализация методов класса осуществляется в теле класса, таким образом можно скрыть от пользователя класса отдельные методы и свойства. Ниже приводится скрипт для реализации методов класса:
При описании метода класса можно воспользоваться одним из модификаторов – MAP или ORDER. При использовании модификатора ORDER метод должен возвращать число и использоваться для сортировки объектов в предложении ORDER BY. Модификатор MAP используется для сравнения собственно объекта с собой подобным, который передается ему в качестве параметра. Метод должен возвращать –1, 0, 1, соответственно, если передаваемый объект меньше, равен или больше собственного объекта.
Доступ к данным и записям осуществляется через алиасы. Ниже приводятся команды DML для доступа к атрибутам и методам поля таблицы, представленным как объект класса, от которого он унаследован.
--Создается новый класс на основе которого будет создана таблица
--Тип BANKTYPE будет использован для объектной таблицы
--Создаем таблицу с одним объектным типом
Накладываем ограничение на поле класса, на который ссылается объект
--Заполняем таблицу данными с помощью конструктора класса BANKTYPE, за источник данных взята реляционная таблица.
В конструкторе класса неиспользуемый аттрибут (KOD Primary Key) инициализируется значением NULL. При выполнении оператора INSERT производится преобразование данных к типу соответствующего класса. Следующие операторы манипулируют данными объектного типа. Оператор VALUE Извлекает запись (Объект) из таблицы, используя при этом алиас.
Ссылки на объекты имеют тип REF, переменная объявляется как ссылка на тип объекта определенного класса. Важное замечание: в Oracle можно хранить ссылки только на объекты, хранимые в таблицах объектов, а точнее на строки, в которых хранятся объекты определенного класса. На самом деле ссылка на строку таблицы, которая содержит объект класса, представляет собой уникальный идентификатор таблицы, в которой содержится объект плюс уникальный идентификатор класса, от которого унаследован объект и, наконец, уникальный идентификатор строки таблицы (ROWID), на который ссылается объект. Ниже приводится значение ссылки на объект:
'ВЕСТ Адрес: ЭЛЕКТРОСТАЛЬ, УЛ.СОВЕТСКАЯ,Д.5 т.(8257)43260,44284%';
В результате получаем ссылку следующего вида:
REF(B)
---------------------------------------------------------------------------------------
000028020958E89574822D11D29781008048E2703DE33AAB34821511D29781008048E2703D00C00AE70002
6. Создание таблицы, с колонкой типа ссылка на объект, хранящийся в объектной таблице
--Таблица агентов содержит ссылку на банк (Type BANKTYPE)
Как видно из объявления таблицы, поле BANK ссылается на тип BANKTYPE, который совершенно не обязательно должен находиться в определенной таблице. Другими словами, разные записи одного поля таблицы могут ссылаться на объекты, физически расположенные в разных таблицах. Однако можно ограничить область размещения объектов, на которые ссылаются записи из поля таблицы. Ниже приведен другой пример создания таблицы:
Здесь кроме типа ссылки вводится ограничение и на таблицу, на которую будет указывать ссылка. Ссылочный тип отличается от реляционного FOREIGN KEY ограничения тем, что он обеспечивает выборку данных по значению, на которое указывает ссылка. Кроме того, в отличии от внешнего ключа, поле – ссылка может указывать на несуществующий объект, другими словами возникает понятие зависшей (не существующей ссылки). Этот факт можно выявить с помощью оператора DANGLING:
NAME
-------------------------------------------------
Электростальский Котельностроительный комбинат
Из двух записей выбрана одна , так как вторая имеет зависшую ссылку в поле BANK.
Следующий пример демонстрирует получение доступа к свойству объекта, через ссылку, размещенную в поле таблицы:
Вложенная таблица (Nested Table) связывается со столбцом исходной таблицы, чтобы служить хранилищем всех строк для каждой записи главной таблицы.
--Создаем тип, определяющий структуру вложенной таблицы
--Определяем табличный тип как ссылку на выше созданную структуру
--После создания табличного типа можно создать вложенную таблицу. В нашем примере эта таблица будет отображать историю движения материала на складе (приход, расход):
Следует обратить внимание, что таблица – хранилище недоступна в обычных операторах DML. Oracle расширил SQL и предоставил пользователю несколько способов доступа к Nested Table.
При добавлении записи в основную таблицу, поле вложенной таблицы должно инициализироваться конструктором последней:
Только после подобной инициализации, вложенная таблица способна принимать строки. С помощью оператора THE можно локализовать вложенную таблицу как атомарное значение для последующего добавления в него новых записей:
Важно, чтобы запрос в предложении THE возвращал одну запись с полем вложенной таблицы, в противном случае будет сгенерирована ошибка Oracle сервером. Следующий пример производит обновление записи во вложенной таблице:
Удаление записей во вложенных таблицах производится аналогичным образом:
8. Объектные представления (Views)
Эти объекты базы данных позволяют использовать реляционные данные из существующих таблиц и новые объектные данные:
--создаем представление
Объектное представление – это обычное представление с одной колонкой (очень похожи на таблицы объектов), в качестве строк выступают объекты со своими идентификаторами, которые определяет пользователь, на стадии создания представления, предложение WITH OBJECT OID (kod). Созданное приложение для редактирования такого представления например в Delphi 4 будет выглядеть следующим образом:
Поле KOD и NAME могут редактироваться из клиентского приложения, однако поле с атрибутами заведующего складом не может быть изменено в виду его виртуальных свойств, а именно, значение этого поля возвращает метод класса OTVETSTV.ATRIBUT. В этом случае для представления необходимо создать INSTEAND OF триггер, который будет отрабатывать в случае попытки модификации объектного представления.
Триггер срабатывает в момент вставки новой записи и обновляет связанные с представлением таблицы. Используя выражение CAST можно создать представление с вложенной таблицей:
--Этот тип абсолютно точно описывает поля вложенной таблицы (порядок следования, имя, размер)
/
--Объектная таблица, в представлении будет вложенной таблицей
from material mat;
В этом случае будет возвращен запрос с вложенными таблицами.
Вот примерно так он будет выглядеть в Delphi 4:
Все приводимее в этой сатье скрипты SQL тестировались
на Oracle server 8.04 Enterprise Edition. Клиентские приложения создавались
в среде Delphi 4 Patch 2.