Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базы данных.doc
Скачиваний:
114
Добавлен:
16.03.2016
Размер:
5.67 Mб
Скачать

23.1.3. Цели лекции

Следует заметить, что в этой, безусловно, перегруженной материалом лекции мы преследуем две основные цели. Первая цель состоит в том, чтобы показать читателям, что в средствах определения структурных типов SQL используются, по сути, все базовые возможности определения объектов базы данных и выборки данных, которые обсуждались в предыдущих лекциях. Более того, определенные пользователями типы в SQL являются объектами первого класса; UDT можно использовать в любой конструкции языка, в которой допускается применение предопределенного или конструируемого типа данных. Очень важно отдавать себе отчет в том, что наличие возможности определять пользовательские типы не делает язык SQL менее реляционным или более объектным. Эта возможность «всего лишь» фантастически повышает выразительную мощность языка.

Второй целью является демонстрация того, как на основе базовых механизмов языка удалось ввести дополнительные конструкции, которые действительно вплотную приближают SQL к объектному миру. Здесь, конечно, основную роль играет связка UDT и механизма типизированных таблиц, которые играют в SQL своеобразную совмещенную роль классов и коллекций объектов.

Может оказаться, что материал этой лекции покажется сложным, поскольку для его усвоения не помешало бы иметь предварительную подготовку в области полнотиповых языков программирования, объектно-ориентированных языков и систем баз данных и т. д. Хочется надеяться, что возникновение трудностей при изучении лекции не отпугнет читателей от этой темы, а напротив, послужит стимулом к изучению дополнительной литературы.

Возможна и другая опасная ситуация. Краткость и некоторая формальность изложения может создать ложное впечатление тривиальности объектных расширений SQL. В этом случае могу посоветовать перечитать предыдущие лекции курса, относящиеся к SQL, считая, что везде, где используются предопределенные или конструируемые типы, применяются некоторые UDT, а в тех случаях, где имеются таблицы, связываемые естественным соединением, используются типизированные таблицы. Думаю, это позволит оценить мощь новых возможностей SQL.

Введя этот необходимый контекст, перейдем к описанию соответствующих механизмов SQL:1999.

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

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

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

Напомним, что индивидуальным типом называется 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.194)Далее, поскольку индивидуальный тип является частным типом структурного типа, для индивидуального типа можно определять методы.

В своих книгах [4.2-4.3]главный редактор стандартов SQL Джим Мелтон постоянно подчеркивает семантическое сходство понятий индивидуального типа данных и домена в смысле SQL (лекция 15). Более того, утверждается, что в следующих версиях стандарта SQL использование доменов будет сначала объявлено нежелательным, а потом и вовсе будет запрещено. Но я полагаю, что сделать это совсем непросто.

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

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

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

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

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

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

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

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