Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базы данных.doc
Скачиваний:
138
Добавлен:
16.03.2016
Размер:
5.67 Mб
Скачать

Поддержка согласованности ссылок

Никакое ссылочное значение никогда не идентифицирует какую-либо строку, кроме той, с которой оно было ассоциировано с самого начала. Если эта строка удаляется, то значение ничего не идентифицирует и никогда не может быть связано с другой строкой. Из этого следует, что система должна каким-либо образом узнавать о том, идентифицирует ли данное ссылочное значение какую-то хранимую строку или ничего не идентифицирует (является висящей ссылкой). Но как система может это узнать, не потратив множество ресурсов? Отчасти здесь может помочь раздел SCOPE. В этом разделе указывается одна таблица, в которой строки должны существовать для всех значений данного местоположения, типом данных которого является некоторыйREF-тип. (В будущих версиях стандарта SQL, по всей видимости, будет разрешено указывать в разделеSCOPEсписок имен типизированных таблиц или даже использовать некоторую конструкцию, означающую «все таблицы, ассоциированные с данным структурным типом».)

Итак, если определяется столбец таблицы, поле строчного типа или атрибут структурного типа, и типом этого местоположения является REF-тип, то можно специфицировать разделSCOPE. Однако если такой раздел действительно указывается, то требуется также указать, нужна ли проверка ссылочных значений. Для этого служит конструкцияreference_scope_check, определяемая следующим синтаксическим правилом:

reference_scope_check ::= REFERENCES ARE [ NOT ] CHECKED

[ ON DELETE referential_action ]

Если указывается REFERENCES ARE NOT CHECKEDили если разделSCOPEне задается, то в определяемом местоположении можно хранить любое ссылочное значение, независимо от того, является ли оно значением самоссылающегося столбца какой-либо таблицы, на строку которой предположительно указывает ссылка. В этом случае система не гарантирует, что ссылочное значение действительно указывает на строку (но, конечно, это значение должно быть значением правильного типа –REF-типа указанного структурного типа).

Если же указывается REFERENCES ARE CHECKED, то каждый раз при сохранении значения в определяемом столбце, поле или атрибуте система обращается к указанной в разделеSCOPEтаблице, чтобы убедиться в том, что в ней имеется строка, значение самоссылающегося столбца которой совпадает с сохраняемым ссылочным значением. Кроме того, если указываетсяREFERENCES ARE CHECKED, то можно также указать ссылочное действие, которое должно выполняться при удалении строки, идентифицируемой ссылочным значением. Как обычно (см. лекцию 16), возможными ссылочными действиями являютсяRESTRICT,CASCADE,SET NULLиNO ACTION. Если ссылочное действие явно не указывается, по умолчанию принимаетсяNO ACTION. (Для поля строчного типа (ROW TYPE) и атрибута структурного типа допускается толькоNO ACTION.)

Заметим, что если раздел SCOPEвключается в определение атрибута структурного типа, то в конструкцииcolumn_optionsстолбца типизированной таблицы, соответствующего данному атрибуту, разделSCOPEприсутствовать не может – это считается синтаксической ошибкой.

23.3.3. Выборка данных из типизированных таблиц

Приведем несколько примеров операций выборки данных из типизированных таблиц, а также кратко обсудим операции обновления таких таблиц. Для этого сначала определим структурные типы EMP_T,PROGRAMMER_TиDEPT_T, а также соответствующие типизированные таблицы (упрощенный вариант).

CREATE TYPE EMP_T AS (

EMP_NAME VARCHAR(20),

EMP_BDATE DATE,

EMP_SAL SALARY,

DEPT REF (DEPT))

INSTANTIABLE

NOT FINAL

REF IS SYSTEM GENERATED

INSTANCE METHOD age ()

RETURNS DECIMAL (3,1);

CREATE TYPE PROGRAMMER_T UNDER EMP_T AS (

PROG_LANG VARCHAR (10))

INSTANTIABLE

NOT FINAL;

CREATE TYPE DEPT_T AS (

DEPT_NO INTEGER,

DEPT_NAME VARCHAR(200),

DEPT_MNG REF (EMP))

INSTANTIABLE

REF IS SYSTEM GENERATED

NOT FINAL;

CREATE TABLE EMP OF EMP_T

(REF IS DEPT_ID SYSTEM GENERATED,

DEPT WITH OPTIONS SCOPE DEPT);

CREATE TABLE PROGRAMMER OF PROGRAMMER_T UNDER EMP;

CREATE TABLE DEPT OF DEPT_T

(REF IS EMP_ID SYSTEM GENERATED,

DEPT_MNG WITH OPTIONS SCOPE EMP);

Следует отметить, что с типизированными таблицами можно работать, как с обычными таблицами203). Поэтому, в частности, возможен следующий запрос.

Пример 23.1. Найти имена всех служащих, размер заработной платы которых меньше 20000.00.

SELECT EMP_NAME

FROM EMP

WHERE EMP_SAL < 20000.00;

В соответствии с семантикой SQL:1999, при выполнении запроса из примера 23.1сначала будет произведена выборка имен служащих, удовлетворяющих условию, из таблицыEMP, затем – из таблицыPROGRAMMER, и эти промежуточные результаты будут скомбинированы в окончательный результат путем применения операции объединения (UNION). Но предположим, что нас интересуют только те служащие, получающие зарплату, не превышающую 20000 руб., которые не являются программистами (пример 23.2). Тогда можно применить формулировку запроса, в которой присутствует спецификацияONLY:

Пример 23.2. Найти имена всех служащих, которые не являются программистами, размер заработной платы которых меньше 20000.00.

SELECT EMP_NAME

FROM ONLY (EMP)

WHERE EMP_SAL < 20000.00;

Естественно, в запросах к типизированным таблицам можно использовать ссылки.

203 По крайней мере, в той же синтаксической форме.

Пример 23.3. Найти имена и названия отделов, где работают служащие, размер заработной платы которых меньше 20000.00.

SELECT EMP_NAME, DEPT -> DEPT_NAME

FROM EMP

WHERE EMP_SAL < 20000.00;

В SQL:1999 операция «->» называется операциейразыменования (dereferencing), но в обиходе ее можно считать операцией перехода по ссылке (в нашем примереDEPTссылается наDEPT_NAME). Можно неформально трактовать ссылочные значения как указатели на строки типизированных таблиц.

Может показаться неожиданным, что запрос из примера 23.3выбирает значения из таблицыDEPT, хотя в разделеFROMэтого запроса она даже не упоминается. Дело в том, что выполнение операции разыменования фактически приводит к выполнению соединения таблицEMPиDEPT, делая в запросе столбецDEPT_NAME«видимым».

Конечно, в запросе допускаются многократные переходы по ссылкам, так что можно сформулировать следующий запрос:

Пример 23.4. Найти имена служащих и имена руководителей их отделов для служащих, получающих зарплату, не превышающую 20000.00.

SELECT EMP_NAME, DEPT -> DEPT_MNG -> EMP_NAME

FROM EMP

WHERE EMP_SAL < 20000.00;

Как показывает следующий пример, в запросах можно использовать вызовы методов над строками, к которым производится переход по ссылке.

Пример 23.5. Найти имя и возраст руководителя отдела 605.

SELECT DEPT_MNG -> EMP_NAME, DEPT_MNG -> age ()

FROM DEPT

WHERE DEPT_NO = 605;

Наконец, имеется возможность полностью выбрать экземпляр структурного типа, идентифицируемый ссылочным значением (в SQL:1999 это называется разрешением ссылки – reference resolution).

Пример 23.6. Получить полные данные о руководителе отдела 605.

SELECT DEREF (DEPT_MNG)

FROM DEPT

WHERE DEPT_NO = 605;

В этом случае результатом запроса будет являться таблица, включающая один столбец структурного типа EMP_T. Единственным значением этого столбца будет экземпляр (значение) этого структурного типа, соответствующий служащему-руководителю отдела 605.

Операции обновления типизированных таблиц выполняются очевидным образом. Операция INSERTвставляет указанные строки в указанную таблицу. ОперацииDELETEиUPDATEудаляют или модифицируют строки в иерархии таблиц, корнем которой является указанная таблица, если в операции не содержитсяONLY. Если же специфицированоONLY, то удаляются или модифицируются только строки указанной таблицы.