Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Объекты в ORACLE.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
143.87 Кб
Скачать

4. Реализация полиморфизма в субд oracle

Под полиморфизмом в ORACLE понимается возможность использования свойства подстановочности (substitutability) и динамической диспетчеризации методов (Dynamic Method Dispatch), или иными словами, виртуальных методов.

4.1. Полиморфизм типов

Подстановочность – это основная характеристика полиморфизма типов (type polymorphism), которая позволяет использовать значение некоторого подтипа там, где ожидается значение супертипа.

Для понимания уровня реализации полиморфизма типов в объектной модели СУБД ORACLE рассмотрим следующий пример.

DROP TABLE Deps;

DROP TABLE Employees;

DROP SEQUENCE Employees_seq;

-- создадим таблицу для хранения информации об отделах и наполним ее данными:

CREATE TABLE Deps OF department_typ;

INSERT INTO Deps VALUES(1, ‘Отдел продаж’);

INSERT INTO Deps VALUES(2, ‘Отдел закупок’);

INSERT INTO Deps VALUES(3, ‘Отдел кадров’);

Нам также понадобится таблица для хранения информации о сотрудниках и последовательность для генерации значений первичных ключей таблицы:

CREATE TABLE Employees(

emp_id NUMBER,

employee employee_typ

);

CREATE SEQUENCE Employees_seq;

Рассмотрим, каким образом можно хранить данные о разных сотрудниках в одной таблице:

-- добавление босса:

INSERT INTO Employees VALUES(Employees_seq.NEXTVAL, boss_typ(‘Петр Иванович Сидоров’, to_date(’12.03.2004’,’dd.mm.yyyy’)));

-- добавление менеджера по продаже:

INSERT INTO Employees VALUES(Employees_seq.NEXTVAL, sales_manager_typ( ‘Вася’, to_date(’12.03.2004’,’dd.mm.yyyy’), department_typ(1,’Отдел продаж’)));

-- выборка перечня сотрудников предприятия:

SELECT * FROM Employees;

Здесь нужно обратить внимание на полезность объявления типа employee_typ как абстрактного. В противном случае была бы разрешена следующая не вполне логичная команда:

INSERT INTO Employees VALUES(Employees_seq.NEXTVAL, employee_typ(‘Дядя Петя’,sysdate));

В ответ на попытку выполнить эту команду СУБД вполне резонно заметит, что нельзя создавать экземпляры объектов абстрактных типов. С точки зрения поддержания целостности базы данных это является правильным (если существует бизнес-правило, что все сотрудники должны относиться к какому-то отделу или являться начальниками).

4.2. Расширение и сужение объектных типов

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

Расширение – это присвоение, в котором объявленный тип источника является более конкретным, чем объявленный тип места назначения (например, присвоение переменной типа sales_manager_typ значения типа employee_typ).

Сужение – это присвоение, в котором объявленный тип источника является более общим, чем объявленный тип места назначения (например, присвоение переменной типа employee_typ значения переменной sales_manager_typ).

Примеры неявного расширения были рассмотрены ранее (присвоение столбцу типа employee_typ значений типов boss_typ и sales_manager_typ). Рассмотрим, как выполняется более сложный шаг – сужение.

ORACLE предоставляет специальную функцию TREAT, которая позволяет выполнять операцию сужения. Функция TREAT явно изменяет объявленный тип источника в присваивании на более специализированный тип (подтип) в иерархии места назначения. Без использования этой функции нельзя сослаться на специфичные для подтипа атрибуты и методы.

-- общий синтаксис функции:

TREAT (<object_instance> AS <object_type>)

где <object_instance> – это значение столбца или строки коллекции данного конкретного супертипа в объектной иерархии, а <object_type> – это подтип в этой иерархии.

-- например, можно выполнить запрос:

SELECT e.employee.Name FROM Employees e;

-- не удастся выполнить следующий запрос, поскольку свойство Dep есть только

-- у типа sales_manager_typ и его подтипов:

SELECT e.employee.Dep.Caption FROM Employees;

-- для выполнения предыдущей задачи необходимо выполнить запрос:

SELECT TREAT(employee as sales_manager_typ).Dep.Caption FROM Employees;

Для объектов отличных от sales_manager_typ функция TREAT вернет значение NULL.