Московский государственный университет имени М.В.Ломоносова
Опубликован: 10.10.2005 | Доступ: свободный | Студентов: 8464 / 634 | Оценка: 3.85 / 3.50 | Длительность: 22:03:00
Лекция 9:

Объектные расширения

< Лекция 8 || Лекция 9: 123456789

Ссылочные значения и REF-типы

Понятия ссылочных значений и ссылочных (REF) типов являются, по существу, неразделимыми. В SQL:1999 ссылочный тип может использоваться в качестве типа данных столбцов обычных таблиц, атрибутов структурных типов, SQL-переменных и параметров – словом, везде, где можно использовать другие типы данных SQL. Значения местоположения ссылочного типа всегда являются ссылочными значениями строк типизированных таблиц (т. е. значениями самоссылающихся столбцов этих строк).

Для удобства повторим синтаксис спецификации ссылочного типа:

reference_type_specification ::= system_generated_representation
    | user_defined_representation
    | derived_representation
system_generated_representation :== REF IS SYSTEM GENERATED
user_defined_representation :== REF USING predefined_type
derived_representation ::= REF USING (commalist_of_attributes)
Механизмы генерации ссылочных значений

В SQL:1999 и SQL:2003 обеспечиваются три механизма назначения уникальных идентификаторов экземплярам структурных типов, ассоциированных с типизированными таблицами. Во всех типизированных таблицах, ассоциированных с данным структурным типом, должен использоваться один и тот же механизм. Предоставляются следующие альтернативы выбора ссылочных значений, которые могут являться:

  • значениями некоторого встроенного типа SQL ( user_defined_representation ), которые должны генерироваться приложением каждый раз при сохранении экземпляра структурного типа как строки типизированной таблицы ;
  • значениями, порождаемыми из одного или нескольких атрибутов структурного типа ;
  • значениями, автоматически генерируемыми системой.

Как отмечалось в разделе "Определяемые пользователями типы", при определении любого максимального структурного супертипа явно или неявно задается спецификация ссылочного типа. Спецификация ссылочного типа наследуется всеми подтипами этого супертипа. При определении типизированных таблиц необходимо указать соответствующую спецификацию самоссылающегося столбца (конечно, эта спецификация логически избыточна, и, по всей вероятности, в следующих версиях стандарта SQL это требование будет ослаблено). Хотя соотношение между альтернативами спецификации ссылочного типа и спецификации самоссылающегося столбца очевидно, приведем его явно (табл. 19.1).

Таблица 19.1. Спецификации ссылочного типа и самоссылающегося столбца
reference_type_specification self-referencing_column
REF USING predefined_type USER GENERATED
REF FROM commalist_of_attributes DERIVED
REF IS SYSTEM GENERATED SYSTEM GENERATED

Если для некоторого структурного типа выбран вариант пользовательской генерации ссылочных значений, то ответственность за поддержание уникальности таких значений лежит на пользователе. Конечно, ограничения PRIMARY KEY или UNIQUE, определенные на уровне максимальной супертаблицы семейства типизированных таблиц, могут гарантировать отсутствие в любой таблице этого семейства дублирующих ссылочных значений, но в SQL:1999 отсутствуют какие-либо средства, предотвращающие повторное использование ссылочных значений из удаленных строк в самоссылающихся столбцах новых строк.

Преобразование задаваемых пользователем ссылочных значений к ссылочному типу

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

ref_cast_option ::= cast_to_ref
    | cast_to_type
cast_to_ref ::= CAST ( SOURCE AS REF ) WITH identifier
cast_to_type ::= CAST ( REF AS SOURCE ) WITH identifier

Чтобы пояснить эту конструкцию, предположим, что в определении структурного типа указано REF USING INTEGER. Тогда соответствующие приложения отвечают за то, чтобы обеспечить глобально уникальные целые значения самоссылающегося столбца во всех строках всех типизированных таблиц, ассоциированных с этим структурным типом. Но приложения обеспечивают значения целого типа, а типом данных самоссылающегося столбца является некоторый ссылочный тип.

Для решения именно этой проблемы и предназначена конструкция ref_сast_option. В этой конструкции вводятся имена двух SQL-функций, первая из которых служит для преобразования ссылочных значений, обеспечиваемых приложением, к соответствующему REF -типу при вставке или обновлении строк типизированной таблицы ( SOURCE AS REF ). Вторая функция преобразует значения REF -типа к соответствующему встроенному типу данных при выборке строк из типизированной таблицы ( REF AS SOURCE ). Система автоматически генерирует обе подпрограммы, и конструкция ref_сast_option позволяет лишь назначить подпрограммам имена. Если конструкция ref_сast_option явно не включается в определение структурного типа с REF USING predefined_type, то имена подпрограммам назначаются системой. Единственным преимуществом явного назначения имен является возможность явного вызова этих функций при написании SQL-операторов, содержащих выражения REF -типа, которые нужно привести к соответствующему встроенному типу. Заметим, что такие функции невозможно написать вручную, поскольку правила отображения зависят от реализации SQL.

Если для структурного типа выбирается альтернатива порождения ссылочных значений, то система использует для порождения ссылочных значений значения неявно указанных столбцов (соответствующих явно указанным атрибутам ассоциированного структурного типа ). При этом остаются все упомянутые выше проблемы, хотя в таком случае явно требуется объявление ограничений PRIMARY KEY или UNIQUE для соответствующего набора столбцов.

Наконец, при выборе последней альтернативы (системно-генерируемые ссылочные значения ) каждой строке, вставляемой в типизированную таблицу, ассоциированную с соответствующим структурным типом, присваивается уникальный идентификатор. Это значение сохраняется в самоссылающемся столбце и может быть использовано любым приложением для уникальной идентификации данной строки на всем протяжении жизни таблицы.

Спецификация ссылочного типа при объявлении столбцов и атрибутов

Самоссылающиеся столбцы всегда имеют REF -тип. Конкретный REF -тип зависит от двух факторов:

  • структурного типа, ассоциированного с типизированной таблицей: REF -тип всегда связан с некоторым структурным типом ;
  • выбранного способа генерации ссылочных значений ; эта информация задается в определении структурного типа и не присутствует в спецификации ссылочного типа.

Для объявления местоположения ссылочного типа используется следующий синтаксис:

reference_type ::= REF (referenced_type) [ SCOPE table_name ]
referenced_type ::= UDT_name

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

В необязательном разделе SCOPE задается имя типизированной таблицы. Ассоциированным структурным типом этой таблицы должен быть referenced_type REF -типа, в спецификации которого содержится данный раздел SCOPE. Хотя можно было бы ожидать, что значение REF -типа можно использовать для ссылки на строки типизированных таблиц, ассоциированный структурный тип которых является собственным подтипом указанного referenced_type, в SQL такая разновидность ссылок не допускается. Ассоциированный структурный тип таблицы, на строки которой указывают значения REF -типа, должен быть в точности тем же, что и referenced_type этого REF -типа. Но, конечно, можно объявить REF -тип, у которого referenced_type является ассоциированным структурным типом подтаблицы, хотя самоссылающийся столбец этой подтаблицы необходимо наследуется от максимальной супертаблицы семейства таблиц.

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

Никакое ссылочное значение никогда не идентифицирует какую-либо строку, кроме той, с которой оно было ассоциировано с самого начала. Если эта строка удаляется, то значение ничего не идентифицирует и никогда не может быть связано с другой строкой. Из этого следует, что система должна каким-либо образом узнавать о том, идентифицирует ли данное ссылочное значение какую-то хранимую строку или ничего не идентифицирует (является висящей ссылкой). Но как система может это узнать, не потратив множество ресурсов? Отчасти здесь может помочь раздел 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, то можно также указать ссылочное действие, которое должно выполняться при удалении строки, идентифицируемой ссылочным значением. Как обычно (см. лекцию 12), возможными ссылочными действиями являются RESTRICT, CASCADE, SET NULL и NO ACTION. Если ссылочное действие явно не указывается, по умолчанию принимается NO ACTION. (Для поля строчного типа ( ROW TYPE ) и атрибута структурного типа допускается только NO ACTION.)

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

< Лекция 8 || Лекция 9: 123456789
Алексей Ковтун
Алексей Ковтун

При попытке исполнения запроса:

CREATE DOMAIN EMP_NO AS INTEGER

    CHECK (VALUE BETWEEN 1 AND 10000);

Выдается ошибка: Неизвестный тип объекта "DOMAIN" в интсрукции CREATE, DROP или ALTER. 

Используется SQL Server MS SQL 2008R2

Александра Каева
Александра Каева