Индивидуальные типы

Определяемые пользователями типы

Один из основных упреков по адресу языка SQL, звучавший, в частности, в Первом манифесте, заключался в отсутствии каких бы то ни было возможностей хранить в базе данных данные, тип которых являлся бы не предопределенным, а определяемым пользователями. Отрицательные последствия отсутствия этой возможности признавались и во Втором манифесте. В SQL:1999 этот дефект был устранен. Как мы отмечали в Лекции 11, в стандарте поддерживается возможность определения пользователями двух разновидностей UDT – структурных типов (structured type) и индивидуальных типов (distinct types).

 

 

Напомним, что индивидуальным типом называется UDT, основанный на единственном встроенном типе (например, INTEGER). Значения такого типа нельзя прямо использовать в операциях соответствующего базового типа, однако допускается явное приведение значений индивидуального типа к базовому типу. Поясним это на примерах.

 

Пусть заданы следующие определения индивидуальных типов:

 

CREATE TYPE EMP_NO AS INTEGER FINAL;

CREATE TYPE DEPT_NO AS INTEGER FINAL;

CREATE TYPE PRO_NO AS INTEGER FINAL;

 

Таблицу EMP можно определить следующим образом (приведем упрощенный вариант):

 

CREATE TABLE EMP (

EMP_ID EMP_NO,
EMP_NAME VARCHAR(20),
DEPT_ID DEPT_NO,
PRO_ID PRO_NO);

 

Такое определение таблицы приведет к тому, что хотя все три индивидуальных типа определены на одном и том же базовом типе INTEGER, попытка выполнить запрос

 

SELECT EMP_NAME
FROM EMP
WHERE EMP_ID > DEPT_ID;

 

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

 

SELECT EMP_NAME
FROM EMP
WHERE CAST (EMP_ID TO INTEGER) > CAST (DEPT_ID TO INTEGER);

 

Аналогичным образом, будет отвергнут запрос

 

SELECT EMP_NAME, EMP_ID + 5
FROM EMP
WHERE DEPT_ID > 630;

 

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

 

SELECT EMP_NAME, CAST (EMP_ID TO INTEGER) + 5
FROM EMP
WHERE CAST (DEPT_ID TO INTEGER) > 630;

 

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

· почему, в отличие от обыкновения, мы не привели формальные синтаксические правила операции определения индивидуального типа?

· что означает ключевое слово FINAL в приведенных примерах определения индивидуальных типов?

 

На оба эти вопроса достаточно дать один (возможно, неожиданный) ответ. С формальной точки зрения индивидуальный тип данных является частным случаем структурного типа данных. Обе разновидности UDT определяются единым синтаксисом, который мы обсудим в следующих подразделах. В частности, ключевое слово FINAL играет важную роль в определении структурного типа, указывая на тот факт, что этот тип может быть использован только для создания объектов, а не для порождения новых типов на основе механизма наследования. При определении индивидуальных типов механизм наследования не используется, и поэтому в определении любого индивидуального типа должно присутствовать ключевое слово FINAL.* Далее, поскольку индивидуальный тип является частным типом структурного типа, для индивидуального типа можно определять методы.

 

В своих книгах главный редактор стандартов SQL Джим Мелтон неоднократно подчеркивает семантическое сходство понятий индивидуального типа данных и домена в смысле SQL (см. Лекцию 11). Более того, утверждается, что в следующих версиях стандарта SQL использование доменов будет сначала объявлено нежелательным, а потом и вовсе будет запрещено. По мнению автора этого курса, сделать это совсем непросто.

 

Напомним, что в случае использования SQL-домена:

(a) в определении домена указывается базовый встроенный тип данных и, возможно, ограничение допустимых значений, которое распространяется на любой столбец, определенный на данном домене;

(b) для значений столбца, определенного на домене, допускаются все операции, допустимые для базового типа.

 

Естественно, эти возможности могут использоваться текущими пользователями стандарта SQL. В то же время, в случае использования индивидуального типа данных:

(a) в определении индивидуального типа указывается только базовый тип данных; если столбец определяется на индивидуальном типе данных, то для него обязательно придется специфицировать собственное ограничение целостности;

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

 

Здесь явно имеются противоречия, для сглаживания которых требуется модифицировать понятие индивидуального типа данных.