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’ ,