Индивидуальные типы
Напомним, что индивидуальным типом называется 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.1) Далее, поскольку индивидуальный тип является частным типом структурного типа, для индивидуального типа можно определять методы.
В своих книгах главный редактор стандартов SQL Джим Мелтон постоянно подчеркивает семантическое сходство понятий индивидуального типа данных и домена в смысле SQL ( лекция 11). Более того, утверждается, что в следующих версиях стандарта SQL использование доменов будет сначала объявлено нежелательным, а потом и вовсе будет запрещено. Но я полагаю, что сделать это совсем непросто.
Напомним, что в случае использования SQL-домена:
- в определении домена указывается базовый встроенный тип данных и, возможно, ограничение допустимых значений, которое распространяется на любой столбец, определенный на данном домене;
- для значений столбца, определенного на домене, допускаются все операции, разрешенные для базового типа.
Естественно, эти возможности могут использоваться текущими пользователями стандарта SQL. В то же время в случае использования индивидуального типа данных:
- в определении индивидуального типа указывается только базовый тип данных; если столбец определяется на индивидуальном типе данных, то для него обязательно придется специфицировать собственное ограничение целостности;
- для значений столбца, определенного на индивидуальном типе данных, не допускаются операции соответствующего базового типа (если не использовать операцию явного приведения типов).
Здесь явно имеются противоречия, для сглаживания которых требуется модифицировать понятие индивидуального типа данных.