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

Общая характеристика оператора SELECT и организация списка ссылок на таблицы в разделе FROM

< Лекция 2 || Лекция 3: 12345 || Лекция 4 >

Конструкторы значения строки и таблицы

Чтобы завершить обсуждение выражений запросов (с учетом того, что конструкция соединенных таблиц ( joined_table ) отложена на следующие лекции), нам осталось рассмотреть конструкции table_value_constructor и TABLE table_name.

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

row_value_constructor ::= row_value_constructor_element
	| [ ROW ] (row_value_constructor_element_comma_list)
	| row_subquery
row_value_constructor_element ::= value_expression | NULL | DEFAULT

Заметим, что значение элемента по умолчанию можно использовать только в том случае, когда конструктор значения-строки применяется в операторе INSERT (тогда этим значением будет значение по умолчанию соответствующего столбца).

Конструктор значения-таблицы производит таблицу на основе заданного набора конструкторов значений-строк:

table_value_constructor ::= VALUES 
	row_value_constructor_comma_list

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

Наконец, конструкция TABLE table_name является сокращенной формой записи выражения SELECT * FROM table_name.

Ссылки на базовые, представляемые и порождаемые таблицы

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

table_reference ::= table_primary 
table_primary ::= table_or_query_name [ [ AS ] correlation_name
	  [ (derived_column_list) ] ]
	| derived_table [ AS ] correlation_name
	  [ (derived_column_list) ]
table_or_query_name ::= { table_name | query_name }
derived_table ::= (query_expression)

Итак, в самом простом случае в качестве ссылки на таблицу используется имя таблицы (базовой или представляемой) или имя запроса, присоединенного к данному запросу с помощью раздела WITH. В другом случае ( derived_table ) порождаемая таблица задается выражением запроса, заключенным в круглые скобки. Явное указание имен столбцов результата запроса из раздела WITH или порождаемой таблицы требуется в том случае, когда эти имена не выводятся явно из соответствующего выражения запроса. Обратите внимание, что в таких случаях в соответствующем элементе списка раздела FROM должен указываться псевдоним ( correlation_name ), потому что иначе таблица была бы вообще лишена имени. Можно считать, что выражение запроса вычисляется и сохраняется во временной таблице при обработке раздела FROM.

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

Представляемые таблицы, или представления (VIEW)

Еще одним примером рекурсивности спецификаций языка SQL является то, что в конце этой лекции мы вынуждены прервать обсуждение оператора выборки и ввести понятие представляемой таблицы, или представления, которую можно использовать в операторе выборки наряду с базовыми таблицами. Только после этого можно будет считать обсуждение ссылок на таблицы в разделе FROM условно завершенным. Итак, оператор создания представления в общем случае определяется следующими синтаксическими правилами:

create_view ::= CREATE [ RECURSIVE ] VIEW table_name
	  [ column_name_comma_list ]
	AS query_expression
	[ WITH [ CASCADED | LOCAL ] CHECK OPTION ]

Рекурсивные представления (такие, в определении которых присутствует ключевое слово RECURSIVE ) и необязательный раздел WITH CHECK OPTION мы обсудим в следующих лекциях (пока лишь заметим, что этот раздел связан с особенностями выполнения операций обновления базы данных через представления). Здесь мы кратко рассмотрим только простую форму представлений, определяемых по следующим правилам:

create_view ::= CREATE VIEW table_name
	  [ column_name_comma_list ]
	AS query_expression

Имя таблицы, задаваемое в определении представления, существует в том же пространстве имен, что и имена базовых таблиц, и, следовательно, должно отличаться от всех имен таблиц (базовых и представляемых), созданных тем же пользователем. Если имя представления встречается в разделе FROM какого-либо оператора выборки, то вычисляется выражение запроса, указанное в разделе AS, и оператор выборки работает с результирующей таблицей этого выражения запроса. 19По крайней мере, так это следует понимать в соответствии с семантикой представлений в языке SQL. При реальной обработке запросов над представлениями такая явная "материализация" представления выполняется кране редко. Вместо этого используется техника подстановки тела представления в тело запроса с гарантией того, что результат модифицированного запроса будет в точности таким же, что и результат исходного запроса над материализованным представлением. Но это уже относится к тематике оптимизации SQL-запросов, выходящей за пределы этого курса. Явное указание имен столбцов представляемой таблицы требуется в том случае, когда эти имена не выводятся из соответствующего выражения запроса.

Как и для всех других вариантов оператора CREATE, для CREATE VIEW имеется обратный оператор DROP VIEW table_name, выполнение которого приводит к отмене определения представления (реально это выражается в удалении данных о представлении из таблиц-каталогов базы данных). После выполнения операции пользоваться представлением с данным именем становится невозможно20Конструкция ALTER VIEW в языке SQL не поддерживается.

Заключение

В ходе чтения лекций, посвященных оператору SELECT языка SQL, мне неоднократно случалось слышать жалобы студентов на сухость начального материала и отсутствие иллюстрирующих примеров. Однако я не встречал ни одного учебного пособия по языку SQL, основанного на примерах (среди многочисленных изданий типа "SQL за 24 часа", "SQL для чайников" и даже "SQL для идиотов"), который действительно давал бы представление об SQL как языке, а не служил инструкцией армейского типа.

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

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

< Лекция 2 || Лекция 3: 12345 || Лекция 4 >
Алексей Ковтун
Алексей Ковтун

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

CREATE DOMAIN EMP_NO AS INTEGER

    CHECK (VALUE BETWEEN 1 AND 10000);

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

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

Александра Каева
Александра Каева
Евгений Вершинин
Евгений Вершинин
Россия, Нижний Новгород, Нижегородский государственный технический университет, 2008
Aleksandr Arshinskyi
Aleksandr Arshinskyi
Россия