Программирование >>  Oracle 

1 ... 322 323 324 [ 325 ] 326 327 328 ... 469


Использование объектно-реляционных средств 1393

14 end if;

15 end;

16 end;

17 /

Type body created.

tkyte@TKrE816> select name, p.home address.toString()

2 from people P

NAME

P.HOME ADDRESS.TOSTRING()

Tom Kyte

123 Main Street

Reston, VA 45678

Вот и первый пример метода объекта. Каждый метод вызывается с неявным параметром SELF. Можно добавить этот префикс к атрибутам STREET ADDR1, STREET ADDR2 и т.д.:

SELF.street addrl chr(10) SELF.street addr2 ...

но он и так добавляется неявно. Тут вы вполне резонно можете заметить: Ведь все это можно сделать с помощью реляционной таблицы и PL/SQL-пакета . Это действительно так. Однако использование объектного типа с методами, как показано выше, дает определенные преимущества.

Обеспечивается более совершенн1й механизм инкапсуляции. Тип ADDRESS TYPE

инкапсулирует и поддерживает адрес, со всеми его атрибутами и функциональными возможностями.

Методе! более тесно привязываются к специфическим данным. Это очень важный момент. Если используются скалярные столбцы и PL/SQL-функция, форматирующая их для вывода адреса на печать, эту функцию можно вызвать с любыми данными. Можно передать значение столбца EMPLOYEE NUMBER в качестве почтового индекса, фамилию - вместо названия улицы и т.д. Привязывая метод к атрибутам, мы гарантируем, что метод TOSTRING может работать только с данными адреса. Пользователи, вызывающие этот метод, не должны задумываться о передаче соответствующих данных - они уже здесь .

Однако объектный тип имеет один недостаток: в Oracle 8i он мало поддается изменениям. С помощью оператора ALTER можно добавлять новые методы, но нельзя ни удалить существующие, ни добавить дополнительные атрибуты после создания таблицы, использующей этот тип (да и удалить добавленные методы невозможно). Единственное, что можно делать, - это добавлять методы или изменять их (тело типа). Другими словами, развитие схемы при использовании объектных типов затруднено. Если со временем окажется, что для объекта ADDRESS TYPE необходим еще один атрибут, придется пересоздавать объекты, в которые этот тип встроен. Это не относится к объектным типам, которые не используются для столбцов таблиц базы данных или в операторах



1394

Глава 20

CREATE TABLE OF TYPE. Другими словами, если объектные типы используются исключительно в объектных представлениях или для расширения возможностей PL/SQL (как описано в следующих разделах), этой проблемой можно пренебречь.

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

tkyte@TKYTE816>select * from people order by home address; select * from people order by home address *

ERROR at line 1:

ORA-22 9 50 : cannot ORDER objects without MAP or ORDER method

tkyte@TKYTE816> select * from people where home address > work address; select * from people where home address > work address

ERROR at line 1:

ORA-22950: cannot ORDER objects without MAP or ORDER method

tkyte@TKYTE816> select * from people where home address = work address; no rows selected

Упорядочивать данные объектного типа, использовать их при поиске больших меньших значений будет невозможно. Значения можно будет сравнивать только на равенство. При этом сервер Oracle выполняет сравнение по всем атрибутам, чтобы узнать, не совпадают ли они. Чтобы можно б1ло выполнять все остальные операции, необходимо добавить метод MAP или метод ORDER (объектный тип может иметь либо метод MAP, либо метод ORDER, но не оба одновременно).

Метод MAP - это функция, работающая с одним экземпляром объекта и возвращающая значение одного из скалярных типов, которое сервер Oracle будет использовать для сравнения с другими однотипными объектами. Например, если объектный тип представляет точку на плоскости с координатами X и Y, функция MAP может возвращать квадратный корень из (X*X+Y*Y) - расстояние от начала координат. Метод ORDER принимает два экземпляра объекта - SELF и объект для сравнения с SELF. Метод ORDER возвращает 1, если SELF больше этого объекта, -1, если SELF меньше другого объекта или 0, если объекты равны. Метод MAP предпочтительнее, поскольку работает намного быстрее и даже может вызываться в параллельных запросах (метод ORDER нельзя использовать при распараллеливании). Метод MAP достаточно вызвать для экземпляра объекта один раз, и после этого сервер Oracle может использовать это значение при сортировке. Метод ORDER при сортировке большого множества, возможно, придется вызывать сотни или тысячи раз с одними и теми же данными. Для созданного ранее типа ADDRESS TYPE я продемонстрирую оба метода. Сначала - метод ORDER

tkyte@TKYTE816> alter type Address Type

2 REPLACE

3 as object

4 (street addrl varchar2(25) ,

5 street addr2 varchar2(25) ,



Использование объектно-реляционных средств

1395

6 city varchar2(30) ,

7 state varchar2(2),

8 zip code number,

9 member function toString return varchar2,

10 order member function order function(compare2 in Address type)

11 return number

12 )

13 /

Type altered. tkyte@TKYTE816>

create or replace type body Address Type

6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21

29 30 31

33 34

38 39 40 41 42

member function toString return varchar2 is

begin

if (street addr2 is not NULL)

then

return street addrl chr(10) street addr2 chr(10)

city , state

else

return street addrl chr(10) city , state

end if;

end;

order member function order function(compare2 in Address type)

return number

begin

if (nvl(self.zip code,-99999) <> nvl(compare2.zip code,-99999)) then

return sign(nvl(self.zip code,-99999)

- nvl(compare2.zip code,-99999));

end if;

if (nvl(self.city,chr(0)) > nvl(compare2.city,chr(0)))

then

return 1;

elsif (nvl(self.city,chr(0)) <nvl(compare2.city,chr(0)) )

then

return -1; end if;

if (nvl(self.street addrl,chr(0)) >

nvl(compare2.street addr1,chr(0)))

then

return 1;

elsif (nvl(self.street addrl,chr(O)) <

nvl(compare2.street addr1,chr(0)))

then

return -1; end if;

if (nvl(self.street addr2,chr(0)) >



1 ... 322 323 324 [ 325 ] 326 327 328 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика