Объектно-ориентированные системы.

§  Объектно-ориентированные идеи проникают в мир отношений.

    Отношение сохраняется в качестве фундаментальной абстракции

§  Объектно-ориентированные СУБД использует класс как фундаментальную абстракцию и рассматривает отношение как один из многих типов

Мотивировка.

§  Позволить СУБД работать со специальными типами данных: картами, сигналами, картинками и т. п., которые бы могли использовать для своей обработки собственные специальные методы

§  Поддержка специальных методов даже для обычных реляционных данных.

§  Поддержка более сложных структур, чем «плоские файлы».

План.

1.  Рассмотреть основные идеи, сформулированные в SQL стандарте.

2.  Использовать Oracle 8i/9i обозначения в тех случаях, когда они похожи.

3.  Ввести некоторые новые концепции из Oracle.

    Подробнее в документе, помещенном на страничке курса (раздел Объектно-ориентированные возможности Oracle).

Типы определенные пользователем (ТОП).

SQL разрешает ТОП, играющие двоякую роль:

1.  Они могут быть типами отношений, т. е. типами кортежей отношений.

§  Иногда называют строчным типом.

2.  Они также могут быть типом атрибута в отношении.

Определение ТОП. Пример и синтаксис Oracle.

CREATE TYPE BarType AS OBJECT (

name CHAR(20) UNIQUE,

addr CHAR(20)

);

/

CREATE TYPE BeerType AS OBJECT (

name CHAR(20) UNIQUE,

manf CHAR(20)

);

/

CREATE TYPE MenuType AS OBJECT (

bar REF BarType,

beer REF BeerType,

price FLOAT

);

/

Замечания.

§  В Oracle определения типов должны заканчиваться слэшем, вызывающим компиляцию типа.

§  Стандарт SQL похож на Oracle, но OBJECT не используется после AS.

Создание таблиц.

Определения типов сами не создают таблиц.

§  Они используются вместо списка элементов в операторе CREATE TABLE.

Пример.

CREATE TABLE Bars OF BarType;

CREATE TABLE Beers OF BeerType;

CREATE TABLE Sells OF MenuType;

Значения ТОП - подход Oracle.

§  Каждый ТОП имеет конструктор типа с тем же именем.

§  Значением(ями) этого типа являются значения атрибутов (полей), включенных в конструктор.

Пример.

SELECT * FROM Bars

производит значение BarType('Joe''s Bar', 'Maple St.')

Доступ к атрибутам объектов - подход Oracle.

§  Оператор. (точка) работает как обычно.

§  Так если мы хотим получить название бара и адрес без конструктора, можно использовать:

SELECT bb. name, bb. addr FROM Bars bb;

§  Технически, использование алиасной переменной bb не является необходимым, но как мы увидим позже, в некоторых случаях без этого не обойтись. Использование алиаса должно быть хорошей привычкой.

§  Стандарт SQL: похожая идея, но атрибут рассматривается как метод-генератор и отмечается круглыми скобками bb. name().

Добавление (вставка) данных - подход Oracle.

Мы можем использовать стандартный INSERT в Oracle, но мы должны заключить («завернуть») вставляемый объект в его тип-конструктор.

Пример.

INSERT INTO Bars VALUES(

BarType('Joe''s Bar', 'Maple St.')

);

Стандарт SQL использует для доступа к атрибутам методы 2х типов, автоматически создаваемых вместе с ТОП: метод-чтение(generator) и метод-обновление(mutator). Оба имеет то же имя, что и атрибут, однако первый не имеет параметров, а второй получает в качестве параметра значение, которое замещает текущее значение атрибута. В нашем случае, для вставки кортежа необходима следующая PSM процедура

CREATE PROCEDURE InsertBar (

IN n CHAR(20),

IN a CHAR(20)

)

DECLARE newBar BarType;

BEGIN

SET newBar = BarType();

newBar. name(n);

newBar. addr(a);

INSERT INTO Bars

VALUES(newBar);

END;

Теперь, чтобы добавить тот же бар, что в предыдущем примере, необходимо вызвать процедуру

InsertBar('Joe''s Bar', 'Maple St.');

Другой способ – написать метод, ассоциированный с типом, который будет принимать в качестве параметров значения атрибутов, и возвращать в качестве значения объект, который можно вставить при помощи INSERT. Например,

INSERT INTO Bars VALUES(NewBar('Joe''s Bar', 'Maple St.'));

где NewBar() – такой метод. Подробнее см. книгу.

Типы для столбцов.

ТОП может быть также типом столбца (атрибута) отношения.

Пример(Oracle). Создадим тип адреса для использования в отношениях.

CREATE TYPE AddrType AS OBJECT (

street CHAR(30),

city CHAR(20),

zip INT

);

Теперь мы можем создать отношение Drinkers, включающее имя, адрес и любимое пиво. Пиво включается как объект, это денормализует отношение, но считается вполне допустимым.

CREATE TABLE Drinkers (

name CHAR(30),

addr AddrType,

favBeer BeerType

);

Необходимость использования алиасов.

Если необходим доступ к атрибуту с ТОП, необходимо использовать алиас для отношения, т. е.

SELECT favBeer. name FROM Drinker;

Не будет работать в Oracle. Также не будет работать:

SELECT Drinker. favBeer. name FROM Drinker;

Правильно: SELECT dd. favBeer. name FROM Drinker dd;

Ссылки.

§  ТОП может содержать ссылку. Если Т является ТОП, то

REF( T ) будет ссылочным типом на объект типа Т.

§  В отличие от ОО систем ссылки имеют значения, которые могут просматриваться в запросах.

НЕ нашли? Не то? Что вы ищете?

Разыменование в SQL.

A -> B = атрибут B объекта, на который указывает ссылочная переменная А.

Пример. Найти сорта пива, предлагаемые в Joe’s Bar.

SELECT beer -> name

FROM Sells

WHERE bar -> name = 'Joe''s Bar';

Разыменование в Oracle.

Разыменование автоматическое с использованием .(точки).

Тот же пример в синтаксисе Oracle.

SELECT ss. beer. name

FROM Sells ss

WHERE ss. bar. name = 'Joe''s Bar';

Оператор Oracle DEREF.

Если мы хотим получить полностью весь объект BeerType, следующий запрос не будет работать т. к. ss. beer является ссылкой, и мы получим «мусор»

SELECT ss. beer

FROM Sells ss

WHERE ss. bar. name = 'Joe''s Bar';

Правильным будет запрос

SELECT DEREF(ss. beer)

FROM Sells ss

WHERE ss. bar. name = 'Joe''s Bar';

Методы.

Это реальная причина того, что объектно-реляционный подход не означает просто наличие вложенных структур в отношениях.

§  Будем следовать синтаксису Oracle.

§  Объявляется в операторе CREATE TYPE statement, определяется в операторе CREATE TYPE BODY.

§  Методы являются функциями или процедурами, в Oracle они определяются подобно другим PL/SQL процедурам или функциям.

§  Имеется специальная переменная-кортеж SELF, ссылающаяся на объект, к которому применяется метод.

Пример.

Добавим метод priceInYen к типу MenuType, и, следовательно, к отношению Sells.

CREATE TYPE MenuType AS OBJECT (

bar REF BarType,

beer REF BeerType,

price FLOAT,

MEMBER FUNCTION priceInYen(

rate IN FLOAT) RETURN FLOAT,

PRAGMA RESTRICT REFERENCES

(priceInYen, WNDS)

);

/

CREATE TYPE BODY MenuType AS

MEMBER FUNCTION

priceInYen(rate FLOAT)

RETURN FLOAT IS

BEGIN

RETURN rate * SELF. price;

END;

END;

/

CREATE TABLE Sells OF MenuType;

На заметку.

§  Прагма необходима для того, чтобы можно было использовать метод priceInYen в запросах.

§  В объявлении аргументы процедуры/функции должны иметь режим IN, OUT, или IN OUT, также как PL/SQL процедуры.

    Однако режим не указывается в определении метода.

§  Многие методы не имеют аргументы, используя встроенную переменную-кортеж SELF.

    В этом случае скобки после имени функции опускаются.

§  Тело метода может иметь любое количество объявлений процедур/функций, разделенных запятыми.

Пример использования метода.

Имя метода указывается после точки, следующей за именем (или выражением) объекта, к которому применяется метод, за именем метода в скобках указываются параметры.

SELECT ss. beer. name, ss. priceInYen(120.0)

FROM Sells ss

WHERE ss. bar. name = 'Joe''s Bar';

Встроенные функции сравнения (SQL).

Для каждого ТОП мы можем определить 2 функции EQUAL и

LESSTHAN. Это позволит значениям этого ТОП участвовать в сравнениях WHERE использующих =, <=, и т. п., а также в сортировке при помощи ORDER-BY.

Методы упорядочения в Oracle.

Мы можем объявить один метод для типа в качестве метода упорядочения.

§  Определение этого метода должно возвращать значение <0, 0, >0, если SELF соответственно «меньше», «равен» или «больше» объекта, передаваемого как аргумент метода.

§  Будет использоваться в сравнениях WHERE и для ORDER BY.

Пример. Упорядочивать объекты BarType по имени name.

CREATE TYPE BarType AS OBJECT (

name CHAR(20) UNIQUE,

addr CHAR(20),

ORDER MEMBER FUNCTION before(

bar2 IN BarType) RETURN INT,

PRAGMA RESTRICT REFERENCES

(before, WNDS, RNDS, WNPS, RNPS)

);

/

CREATE TYPE BODY BarType AS

ORDER MEMBER FUNCTION

before(bar2 BarType)

RETURN INT IS

BEGIN

IF SELF. name < bar2.name

THEN RETURN -1;

ELSIF SELF. name = bar2.name

THEN RETURN 0;

ELSE RETURN 1;

END IF;

END;

END;

/

Дополнительные коды в прагме гарантируют, что при выполнении метода не будет читаться или изменяться состояние базы данных или «пакета».