Рассмотрим схему БД, где хранятся данные о сотрудниках и отделах. Будем работать в схеме SCOTT, из которой на время нужно удалить таблицы EMP и DEPT (позже мы их восстановим).
Предположим, что и те, и другие имеют адреса: сотрудники - домашний, а отделы – юридический. Адрес имеет несколько полей (например, “индекс”, “район”, “населенный пункт”, “место”). В традиционной табличной реализации есть два способа промоделировать наличие адреса:
- включить одинаковые группы полей в таблицы сотрудников и отделов;
- создать отдельную таблицу адресов и включить в таблицы сотрудников и отделов ссылки на нее.
Первое решение неудобно тем, что адрес теряет свою идентичность: неудобно, например, сравнивать адреса, особенно в разных таблицах. Второе решение искусственно, если только не считать адреса самостоятельными объектами моделирования.
Объектные возможности последних версий Oracle дают возможность более приемлемой альтернативы. Для описания адреса создадим тип (здесь и далее предполагается использование в качестве рабочего инструмента SQL*Plus):
CREATE TYPE address_typ AS OBJECT (
zip CHAR(6),
location VARCHAR2(200))
/
Воспользуемся этим типом для описания сотрудников и отделов:
CREATE TABLE dept (
dname VARCHAR2(50),
deptno NUMBER CONSTRAINT pk_dept PRIMARY KEY,
addr address_typ);
CREATE TABLE emp (
ename VARCHAR2(50),
empno NUMBER CONSTRAINT pk_emp PRIMARY KEY,
deptno NUMBER CONSTRAINT fk_emp REFERENCES dept,
home address_typ);
Проверим описания созданных объектов:
DESCRIBE address_typ
DESCRIBE dept
DESCRIBE emp
Пример заведения сотрудников и отделов:
INSERT INTO dept VALUES (
'Sales',
10,
address_typ('123456', 'Boston 123... '));
INSERT INTO emp VALUES (
'Smith',
1001,
10,
address_typ('123333', 'Boston 567... '));
Здесь выражение ADDRESS_TYP('123333', 'Boston 567... ') означает обращение к конструктору объекта, то есть к функции, автоматически создаваемой СУБД при заведении нового типа для возможности создавать новые объекты этого типа с нужными значениями атрибутов. Понятие конструктора общепринято в объектном подходе. В приведенных предложениях INSERT простановку адреса можно оформить чуть иначе, добавив, в соответствии с духом объектного подхода, ключевое слово NEW перед обращением к конструктору:
INSERT INTO emp VALUES (
'Allen',
1002,
10,
NEW address_typ('123456', 'Boston 123... '));
Проверка:
COLUMN dname FORMAT A20
COLUMN ename FORMAT A20
COLUMN addr FORMAT A40
COLUMN home FORMAT A40
SELECT * FROM dept;
SELECT * FROM emp;
Другие примеры:
SELECT ename, home FROM emp;
SELECT e.ename, d.dname FROM emp e, dept d WHERE e.home = d.addr;
SELECT e.ename, e.home.zip FROM emp e;
UPDATE emp
SET home = address_typ('123457', 'Boston 777... ')
WHERE ename = 'Allen';
UPDATE emp e SET e.home.zip = '123458' WHERE ename = 'Allen';