Выбрать главу

supertypes ( ) манипулирует объектами t_business_person nt_person:

□ CREATE PROCEDURE subtypes_and_supertypes AS

— создаём объекты

v_business_person t_business_person :=

t_business_person(1, 'John', 'Brown',

'01-FEB-1955', '800-555-1211',

t_address('2 State Street', 'Beantown', 'MA', '12345'),

'Manager', 'XYZ Corp'

);

v_person t_person :=

t_person(1, 'John', 'Brown', '01-FEB-1955', '800-555-1211',

t_address('2 State Street', 'Beantown', ’MA’ , '12345'));

v_business_person2 t_business_person;

v_person2 t_person;

BEGIN

-- присваиваем v_business_person для v_person2

v_person2 := v_business_person;

DBMS_0UTPUT.PUT_LINE(' v_person2.id = ' || v_person2.id);

DBMSJJUTPUT.PUT_LINE(' v_person2.first_name = ' ||

v_person2 .first_name);

DBMS_0UTPUT.PUT_LINE('v_person2.last_name = ' ||

v_person2 .last_name);

— следующие строки не будут компилироваться, потому что v_person2

-- имеет тип t_person, a t_person не знает о дополнительных

-- атрибутах t i t l e и company

— DBMS_0UTPUT.PUT_LINE('v_person2.title = ' ||

-- v_person2 . t i t l e ) ;

424 Глава 12

— DBMS_OUTPUT.PUT_LINE('v_person2.company = ' I I

— v_person2.company);

— следующие строки не будут компилироваться, потому что вы не можете

— напрямую присваивать объект t_person объекту t_business_person

- - v_business_person2 := v_person;

END subtypes_and_supertypes;

/

В следующем примере показан результат вызова subtypes_and_

supertypes ():

□ SET SERVEROUTPUT ON

CALL subtypes_and_supertypes();

v_person2.id = 1

v_person2.first_name = John

v_person2.last_name = Brown

Объекты типа NOT SUBSTITUTABLE

Если вы хотите предотвратить использование объекта подтипа вместо

объекта супертипа, вы можете пометить объектную таблицу или объектный

столбец как «незамещаемые». Например, следующее выражение создаёт

таблицу по имени object_customers2 :

П CREATE TABLE object_customers_not_subs OF t_person

NOT SUBSTITUTABLE AT ALL LEVELS;

Выражение NOT SUBSTITUTABLE AT ALL LEVELS показывает, что никакие

объекты других типов, кроме t_pe rson, не могут быть добавлены в таблицу.

Если делается попытка добавить в эту таблицу объект типа t_business_

person, генерируется ошибка:

□ SQL> INSERT INTO object_customers_not_subs VALUES (

2 t_business_person(1, ‘ Steve’ , ‘ Edwards’ , ‘ 03-MAR-1955', '800-555-

1212’ ,

3 t_ a d d re s s ( ‘ 1 Market S t r e e t ’ , ‘ Anytown’ , ‘ VA’ , ‘ 12345’ ),

4 ' Manager’ , ‘ XYZ Corp’

5 )

6 );

t_business_person(1, ‘ Steve’ , ‘ Edwards’ , ' 03-MAR-1955’ , ‘ 800-555-1212 ,

*

ERROR at l in e 2:

0RA-00932: in c o n s is te n t datatypes: expected 0BJECT_USER2.T_PERS0N got

0BJECT_USER2.T_BUSINESS_PERSON

(ORA-00932: несоответствующие типы данных: ожидается OBJECT_USER2.T_

PERSON получен

0BJECT_USER2.T_BUSINESS_PERSON)

Вы также можете пометить объектный столбец как незамещаемый. Например,

следующее выражение создаёт таблицу с объектным столбцом по

имени product, который может хранить только объекты типа t_product:

П CREATE TABLE products (

product t_product,

Объекты базы данных 425

quantity_in_stock INTEGER

) COLUMN product NOT SUBSTITUTABLE AT ALL LEVELS;

Любые попытки добавить объект не типа t_product в столбец product

будут генерировать ошибку.

Другие полезные объектные функции

В предыдущих разделах этой главы вы видели использование функций

REF(), DEREFO, и VALUEQ. В этом разделе вы увидите следующие дополнительные

функции, которые можно использовать с объектами:

■ IS 0F() проверяет, принадлежит ли объект к определённому типу

или подтипу;

■ TREAT( ) выполняет run-time проверку, может ли тип объекта рассматриваться

как супертип;

■ SYS_TYPEID() возвращает идентификатор типа объекта.

IS 0F()

Функция IS 0F() используется для проверки того, принадлежит ли объект

к некоторому типу или подтипу. Например, следующий запрос использует

IS 0F() для проверки того, являются ли объекты в таблице obj ect_business_

customers объектами типа t_business_person, и поскольку они являются

ими, запрос возвращает строку:

□ SELECT VALUE(o)

FROM object_business_customers о

WHERE VALUE(o) IS OF (t_business_person);

VALUE(0)(ID, FIRST_NAME, LAST_NAME, DOB, PHONE,

ADDRESS(STREET, CITY, STATE, ZIP

T_BUSINESS_PERS0N(1, ‘ John’ , ‘ Brown’ , ‘ 01-FEB-55’ , ‘ 800-555-1211’ ,

T_ADDRESS(‘ 2 State Street’ , ‘ Beantown’ , ‘ MA’ , ‘ 12345’ ),

‘ Manager’ , ' XYZ Corp’ )

Вы также можете использовать IS 0F() для проверки того, что объекты

имеют подтип указанного типа. Например, объекты в таблице object_

business_customers имеют тип t_ business_person, который является подтипом

t_pe rson. Поэтому следующий запрос выдаст такой же результат, как

в предыдущем примере:

□ SELECT VALUE(o)

FROM object_business_customers о

WHERE VALUE(o) IS OF (t.person);

VALUE(0)(ID, FIRST_NAME, LAST_NAME, DOB, PHONE,

ADDRESS(STREET, CITY, STATE, ZIP

T_BUSINESS_PERS0N(1, ‘ John’ , ‘ Brown’ , ‘ 01-FEB-55’ , ‘ 800-555-1211’ ,

426 Глава 12

T_ADDRESS(‘ 2 State Street’ , ‘ Beantown’ , ' MA', ‘ 12345’ ),

‘ Manager’ , ‘ XYZ Corp’ )

Вы можете указать более одного типа в IS 0F(); например:

□ SELECT VALUE(o)

FROM object_business_customers о

WHERE VALUE(o) IS OF (t_business_person, t_person);

VALUE(O)(ID, FIRST_NAME, LAST_NAME, DOB, PHONE,

ADDRESS(STREET, CITY, STATE, ZIP

T_BUSINESS_PERS0N(1, ‘ John’ , ‘ Brown’ , ‘ 01-FEB-55’ , ‘ 800-555-1211’ ,