Ссылочные значения и REF -типы
Понятия ссылочных значений и ссылочных (REF ) типов являются по существу неразделимыми. В SQL :1999 ссылочный тип может использоваться в качестве типа данных столбцов обычных таблиц, атрибутов структурных типов и т.д. – словом, везде, где можно использовать другие типы данных SQL . Значения местоположений ссылочного типа всегда являются ссылочными значениями строк типизированных таблиц (т.е. значениями самоссылающихся столбцов этих строк).
В SQL :1999 обеспечиваются три механизма назначения уникальных идентификаторов экземплярам структурных типов, ассоциированных с типизированными таблицами. Во всех типизированных таблицах, ассоциированных с данными структурным типом, должен использоваться один и тот же механизм. Предоставляются следующие альтернативы выбора ссылочных значений, которые могут являться
значениями некоторого встроенного типа SQL , которые должны генерироваться приложением каждый раз при сохранении экземпляра структурного типа как строки типизированной таблицы;
значениями, порождаемыми из одного или нескольких атрибутов структурного типа;
значениями, автоматически генерируемыми системой.
При определении структурного типа, который предназначается для определения одной или нескольких типизированных таблиц, необходимо задать спецификацию ссылочного типа. При определении типизированных таблиц, необходимо указать соответствующую спецификацию самоссылающегося столбца (конечно, эта спецификация логически избыточна).
Если для некоторого структурного типа выбран вариант пользовательской генерации ссылочных значений, то ответственность за поддержание уникальности таких значений лежит на пользователе. Конечно, ограничения PRIMARY KEY или UNIQUE , определенные на уровне максимальной супертаблицы семейства типизированных таблиц, могут гарантировать отсутствие в любой таблице этого семейства дублирующих ссылочных значений, но в SQL :1999 отсутствуют какие-либо средства, предотвращающие повторное использование ссылочных значений из удаленных строк в самоссылающихся столбцах новых строк.
В этом случае в определении структурного типа может присутствовать конструкция, специфицирующая функции преобразования значений встроенного типа в значения ссылочного типа и наоборот. В этой конструкции вводятся имена двух SQL -функций, первая из которых служит для преобразования ссылочных значений (в нашем примере, значений целого типа), обеспечиваемых приложением, к соответствующему REF -типу при вставке или обновлении строк типизированной таблицы. Вторая функция преобразует значения REF -типа к соответствующему встроенному типу данных при выборке строк из типизированной таблицы. Система автоматически генерирует обе подпрограммы, и упомянутая конструкция позволяет лишь назначить подпрограммам имена. Если эта конструкцияявно не включается в определение структурного типа со ссылочными значениями, генерируемыми пользователями, то имена подпрограммам назначаются системой.
Если для структурного типа выбирается альтернатива порождения ссылочных значений, то система использует для порождения ссылочных значений значения неявно указанных столбцов (соответствующих явно указанным атрибутам ассоциированного структурного типа). При этом остаются все упомянутые выше проблемы, хотя в этом случае явно требуется объявление ограничений PRIMARY KEY или UNIQUE для соответствующего набора столбцов.
Наконец, при выборе последней альтернативы (системно-генерируемые ссылочные значения) каждой строке, вставляемой в типизированную таблицу, ассоциированную с соответствующим структурным типом, присваивается уникальный идентификатор. Это значение сохраняется в самоссылающемся столбце и может быть использовано любым приложением для уникальной идентификации данной строки во все время жизни таблицы.
Самоссылающиеся столбцы всегда имеют REF -тип. Конкретный REF -тип зависит от двух факторов:
структурного типа, ассоциированного с типизированной таблицей: REF -тип всегда связан с некоторым структурным типом;
от выбранного способа генерации ссылочных значений; эта информация задается в определении структурного типа и не присутствует в спецификации ссылочного типа.
В спецификации ссылочного типа задается имя структурного типа, на экземпляры которого будут указывать значения ссылочного типа (referenced type ). REF -тип может использоваться в качестве типа атрибута структурного типа, и в этом случае referenced _ type может быть тем же самым, что и определяемый структурный тип. Во все остальных случаях referenced _ type должен являться некоторым существующим структурным типом.
В необязательном разделе указания области действия значений ссылочного типадолжно задаваться имя типизированной таблицы, ассоциированным структурным типом которой является referenced _type REF -типа, в спецификации которого содержится этот раздел. Ассоциированный структурный тип таблицы, на строки которой указывают значения REF -типа, должен быть в точности тем же, что и referenced _type этого REF -типа. Но можно объявить REF -тип, у которого referenced _type является ассоциированным структурным типом подтаблицы, хотя самоссылающийся столбец этой подтаблицы необходимо наследуется от максимальной супертаблицы семейства таблиц.
Если раздел указания области действия значений действительно присутствует, то требуется также указать, нужна ли проверка ссылочных значений.
Если проверка не требуется, то в определяемом столбце можно хранить любое ссылочное значение, независимо от того, является ли оно значением самоссылающегося столбца какой-либо таблицы на строку, которой предположительно указывает ссылка. В этом случае система не гарантирует, что ссылочное значение действительно указывает на строку (но, конечно, это значение должно быть значением правильного типа – REF -типа указанного структурного типа).
Если же указывается потребность в проверке, то каждый раз при сохранении значения в определяемом столбце система обращается к указанной таблице, чтобы убедиться в том, что в ней имеется строка, значение самоссылающегося столбца которой совпадает с сохраняемым ссылочным значением. Кроме того, в этом случае можно также указать ссылочное действие, которое должно выполняться при удалении строки, идентифицируемой ссылочным значением.
Возможными ссылочными действиями являются RESTRICT , CASCADE , SET NULL и NO ACTION . Если ссылочное действие явно не указывается, по умолчанию принимается NO ACTION .
Заметим, что если раздел указания области действия значенийвключается в определение атрибута структурного типа, то соответствующий раздел не может присутствовать среди опций столбца типизированной таблицы, соответствующего данному атрибуту.
Выборка данных из типизированных таблиц
Приведем несколько примеров операций выборки данных из типизированных таблиц, а также операций обновления таких таблиц. Для этого сначала определим структурные типы 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
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 )
Во-первых, заметим, что с типизированными таблицами можно работать как с обычными таблицами. Поэтому, частности, возможен следующий запрос.
Пример 3.1. Найти имена всех служащих, размер заработной платы которых меньше 20000.00.
SELECT EMP_NAME
FROM EMP
WHERE EMP_SAL < 20000.00
В соответствии с семантикой SQL :1999, при выполнении запроса из прим. 3.2 сначала будет произведена выборка имен служащих, удовлетворяющих условию, из таблицы EMP , затем – из таблицы PROGRAMMER , и эти промежуточные результаты будут скомбинированы в окончательный результат путем применения операции объединения ( UNION ).
Но предположим, что нас интересуют только те служащие, получающие зарплату, меньшую 20000.00, которые не являются программистами (пример 3.2). Тогда можно применить формулировку запроса, в которой присутствует спецификация ONLY :
SELECT EMP_NAME
FROM ONLY ( EMP )
WHERE EMP_SAL < 20000.00
Естественно, в запросах к типизированным таблицам можно использовать ссылки.
Пример 3.3. Найти имена и названия отделов всех служащих, размер заработной платы которых меньше 20000.00.
SELECT EMP_NAME, DEPT -> DEPT_NAME
FROM EMP
WHERE EMP_SAL < 20000.00
В SQL :1999 операция “ -> ” называется операцией разыменования , но в обиходе можно считать ее операцией перехода по ссылке (в нашем примере DEPT ссылается на DEPT _ NAME ). Можно неформально трактовать ссылочные значения как указатели на строки типизированных таблиц.
Может показаться неожиданным, что запрос из прим. 3.3 выбирает значения из таблицы DEPT , хотя она даже не упоминается в разделе FROM этого запроса. Дело в том, что выполнение операции разыменования фактически приводит к выполнению соединения таблиц EMP и DEPT , делая “видимым” в запросе столбец DEPT _ NAME .
Конечно, в запросе допускаются многократные переходы по ссылкам, так что можно сформулировать следующий запрос:
Пример 3.4. Найти имена служащих и имена руководителей их отделов для служащих, получающих зарплату, меньшую 20000.00.
SELECT EMP_NAME, DEPT -> DEPT_MNG -> EMP_NAME
FROM EMP
WHERE EMP_SAL < 20000.00
Как показывает следующий пример, в запросах можно использовать вызовы методов над строками, к которым производится переход по ссылке.
Пример 3.5. Найти имя и возраст руководителя отдела 605.
SELECT DEPT_MNG -> EMP_NAME, DEPT_MNG -> age ()
FROM DEPT
WHERE DEPT_NO = 605
Наконец, имеется возможность полностью выбрать экземпляр структурного типа, идентифицируемый ссылочным значением (в SQL :1999 это называется разрешением ссылки – reference resolution ).
Пример 3.6. Получить полные данные о руководителе отдела 605.
SELECT DEREF ( DEPT_MNG )
FROM DEPT
WHERE DEPT_NO = 605
В этом случае результатом запроса будет являться таблица, включающая один столбец структурного типа EMP _ T . Единственным значением этого столбца будет являться экземпляр (значение) этого структурного типа, соответствующий служащему-руководителю отдела 605.
Операции обновления типизированных таблиц выполняются очевидным образом. Операция INSERT вставляет указанные строки в указанную таблицу. Операции DELETE и UPDATE удаляют или модифицируют строки в иерархии таблиц, корнем которой является указанная таблица, если в операции не содержится ONLY . Если же специфицировано ONLY , то удаляются или модифицируются только строки указанной таблицы.