Опубликован: 10.10.2005 | Уровень: специалист | Доступ: платный | ВУЗ: Московский государственный университет имени М.В.Ломоносова
Лекция 9:

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

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

Определение структурных типов

Общий синтаксис оператора определения UDT ( индивидуального или структурного ) определяется следующими правилами:

UDT_definition ::= CREATE TYPE UDT_name
[ subtype_clause ]
[ AS representation ]
[ instantiable_clause ]
finality
[ reference_type_specification ]
[ ref_cast_option ]
[ cast_option ]
[ method_specification_commalist ]

Имя определяемого пользователем типа данных имеет, в общем случае, традиционную для SQL трехзвенную структуру – имя_каталога.имя_схемы.имя_типа. Раздел подтипизации задается в следующем синтаксисе:

subtype_clause ::= UNDER UDT_name

Если этот раздел присутствует в определении UDT, то в нем указывается имя ранее определенного UDT, атрибуты и методы которого будут наследоваться определяемым структурным типом. Структурные типы, определяемые без использования наследования, называются максимальными супертипами (поскольку у любого из таких типов супертип отсутствует)6Как уже отмечалось ранее, раздел подтипизации может присутствовать только при определении структурного UDT . . В определениях максимального структурного супертипа или индивидуального типа должен присутствовать раздел представления (AS):

representation ::= predefined_type
    | (attribute_definition_ commalist)

Если в разделе представления указывается имя предопределенного встроенного типа, то определяется индивидуальный тип. Указание списка определений атрибутов соответствует определению структурного типа. Заметим, что раздел представления может отсутствовать. В этом случае должен присутствовать раздел подтипизации, и представление заново определяемого структурного типа полностью наследуется из определения структурного UDT, имя которого указано после ключевого слова UNDER.

Определение атрибута структурного UDT

Определение атрибута имеет следующий синтаксис:

attribute_definition ::= attribute_name data_type
    [ reference_scope_check ]
    [ default_clause ]
    [ collate_clause ]

Имя определяемого атрибута должно отличаться от имен всех других атрибутов определяемого типа, включая имена атрибутов, наследуемых от супертипа, и имена атрибутов типа данных определяемого атрибута. Тип данных может быть любым допустимым в SQL типом данных (включая конструируемые типы ARRAY 7А в стандарте SQL:2003 и MULTISET. и ROW, а также UDT), кроме самого определяемого структурного типа и его супертипов8Последнее ограничение является непонятным. Его можно обойти, например, следующим образом. Пусть структурный тип T' определяется как подтип типа T, и мы хотим включить в представление типа T' атрибут a типа T. Тогда предварительно определим тип T'' как подтип типа T в точности с тем же представлением. Тогда ничто не помешает определить в представлении типа T' атрибут a типа T'' ..

Для атрибута можно объявить значение по умолчанию. Если типом данных атрибута является встроенный тип данных, то значение атрибута объявляется в том же синтаксисе, что и значение столбца по умолчанию в определении таблицы (см. лекцию 12). Если типом данных атрибута является UDT ( индивидуальный или структурный ), тип ROW или ссылочный тип (см. следующий пункт), то единственным допустимым значением по умолчанию является неопределенное значение ( NULL ). Если же типом данных атрибута является тип ARRAY, то значением по умолчанию может быть NULL или пустое значение-массив (указывается как ARRAY[] ).

Для каждого определения атрибута, в котором типом атрибута является структурный тип, система автоматически генерирует пару методов, имена которых совпадают с именем атрибута. Первый метод является наблюдателем (observer). Он вызывается без явных параметров и выдает значение указанного атрибута в значении того структурного типа, к которому применяется. Второй метод является мутатором (mutator). Он вызывается с одним явным параметром – значением типа атрибута, применяется к некоторому местоположению (столбцу, переменной или параметру), где находится значение определяемого структурного типа, и этот вызов приводит к тому, что значение заменяется новым значением того же типа с измененным соответствующим образом значением данного атрибута.

Присутствие в определении атрибута раздела reference_scope_check возможно (и требуется) в том и только в том случае, когда типом определяемого атрибута является ссылочный тип. Более подробно мы обсудим суть этой спецификации в следующем разделе. Пока лишь кратко заметим, что этот раздел указывает системе, должна ли она проверять, что каждое значение данного атрибута является ссылкой на существующий экземпляр указанного структурного типа, и должна ли система вызывать ссылочное действие при удалении экземпляра, на который ведет ссылка9Мы вынуждены следовать терминологии стандарта SQL, которая иногда бывает довольно нечеткой. В частности, по отношению к структурным типам используются термины значение (value) во вполне стандартном смысле; местоположение (site) как расширенное понятие переменной (нечто, содержащее значение структурного типа ); экземпляр (instance). Последний термин в объектной терминологии обычно используется в том же смысле, что объект класса. В случае SQL это строка типизированной таблицы (см. следующий раздел)..

Можно определить инстанциируемый (instantiable) или неинстанциируемый (not instantiable) структурный тип:

instantiable_clause ::= INSTANTIABLE
    | NOT INSTANTIABLE

Для неистанциируемого типа конструктор не определяется, и поэтому создать значение этого типа невозможно10Мы снова используем обороты, принятые в стандарте SQL. Заметим, что, хотя смысл неинстанциируемого типа должен быть интуитивно понятен, приведенное определение является очень нечетким. Классическое (не вполне строгое) понятие типа данных основывается на паре <множество_значений, набор_операций>. Поэтому нельзя создать значение типа, можно только выбрать его из соответствующего множества значений. Поэтому, строго говоря, в типе данных не может присутствовать " метод-конструктор ", а может иметься (или не иметься) операция выборки значения. У неинстациируемых типов такая операция отсутствует.. Такие типы применимы только для определения инстанциируемых подтипов. Назначение неинстанциируемых типов состоит в моделировании абстрактных концепций, на которых основываются более конкретные концепции. Неинстанциируемые типы могут быть типами атрибутов других структурных типов, типами столбцов, переменных и т. д. Однако в соответствующем местоположении всегда должно находиться либо значение инстанциируемого подтипа данного неинстанциируемого типа, либо неопределенное значение. При отсутствии явной спецификации по умолчанию тип считается инстанциируемым.

Обязательный раздел finality указывает на возможность или невозможность определения подтипов определяемого структурного типа:

finality ::= FINAL | NOT FINAL

При определении индивидуального типа всегда требуется указывать FINAL. При определении структурного типа в SQL:1999 необходимо указать NOT FINAL. Это требование не обосновано, и в следующих версиях стандарта SQL будет разрешено определять структурные типы, от которых невозможно наследование.

Раздел спецификации ссылочного типа

Хотя типизированные таблицы обсуждаются в следующем разделе, мы вынуждены немного забежать вперед, чтобы ввести синтаксис и пояснить смысл раздела reference_type_specification определения структурного типа. Строки типизированных таблиц обладают всеми характеристиками объектов в объектно-ориентированных системах, включая уникальные идентификаторы, которые могут использоваться для ссылок из других компонентов среды. В SQL:1999 поддерживаются три различных механизма присваивания уникальных идентификаторов экземплярам структурных типов, ассоциированных с такими таблицами (для всех строк таблицы, ассоциированной с данным структурным типом, используется один и тот же механизм). Уникальные идентификаторы экземпляров структурного типа могут представлять собой следующее:

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

Соответственно, синтаксис раздела reference_type_specification определяется следующими правилами:

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)

Раздел reference_type_specification может присутствовать только в определении максимального структурного супертипа, т. е. соответствующая спецификация наследуется всеми подтипами этого супертипа. При отсутствии в определении супертипа явного раздела reference_type_specification по умолчанию предполагается наличие раздела REF IS SYSTEM GENERATED.

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

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

CREATE DOMAIN EMP_NO AS INTEGER

    CHECK (VALUE BETWEEN 1 AND 10000);

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

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

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