Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Элементы синтаксических диаграмм

Поиск

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

Нижеследующие разделы настоящей главы содержат синтаксические диаграммы операторов SQL. Для записи диаграмм используются в основном стандартные обозначения формы Бэкуса-Наура (БНФ), но встречаются и дополнения. Ниже приводится полный список обозначений.

· Символом ‘ ::=’ обозначается равенство по определению.

· Ключевые слова, составляющие часть оператора, записываются прописными буквами и выделяются полужирным шрифтом. Так же выделяются специальные символы, являющиеся частями операторов.

· Метки-заполнители конкретных значений элементов схемы или переменных записываются курсивом. Они не являются частями операторов и не несут никакой смысловой нагрузки.

· Символ ‘_’ используется в метках-заполнителях вместо пробела. Слова, соединенные этим символом, образуют метку.

· Необязательные элементы оператора заключены в квадратные скобки ‘[’, ‘]’.

· Вертикальная черта ‘|’ используется в качестве разделителя в списке элементов. Она указывает, что любой предшествующий ей элемент может быть заменен любым следующим за ней.

· Фигурные скобки ‘{’, ‘}’ указывают, что всё находящееся внутри рассматривается как единое целое при использовании других специальных символов.

· Символ ‘…’ означает, что предшествующая часть оператора может быть повторена любое число раз без разделителей.

· Символ ‘.,..’ указывает, что предшествующая часть оператора может быть повторена любое число раз с разделителем ‘,’. Запятая после последнего повторения не ставится.

· Круглые скобки ‘ ( ’, ‘ ) ’ в диаграмме являются частью определяемого оператора.

· Символ ‘; ’ есть концевой ограничитель оператора.

Пробелы и символы перевода строки, встречающиеся в определениях операторов и примерах, используются исключительно для наглядности. Нет необходимости в точности повторять их в собственных программах.

Для иллюстрации действия операторов SQL далее используется «учебная» БД «Поставщик–Деталь–Изделие» (см. приложение А).

Язык манипулирования данными

Назначение операторов

В состав языка манипулирования данными (DML) входят четыре оператора, предназначенных для извлечения и обновления данных. Эти операторы (таблица 6.3) применяются только к именованным таблицам. Их общая особенность состоит в том, что они описывают конечный результат обработки данных, а не процедуру обработки. SQL-система сама определяет, где находятся нужные данные, и какие пути доступа к ним существуют, и сама генерирует эффективные последовательности операций для их получения (обновления).

Таблица 6.3 – Операторы DML

Название Назначение
SELECT Осуществляет выборку данных из одной или более таблиц, собирая их в неименованную временную таблицу.
INSERT Добавляет новые строки в существующую таблицу.
UPDATE Обновляет значения указанных полей в строках существующей таблицы.
DELETE Удаляет строки существующей таблицы.

 

Операторы DML являются декларациями, содержащими определения операций над данными на концептуальном уровне. Они объявляют системе о том, какие действия она должна выполнить, и указывают объекты схемы, которые должны при этом использоваться.

Оператор выборки данных

Оператор SELECT реализует концепции реляционной алгебры и реляционного исчисления и является наиболее сложной и богатой возможностями командой языка. Результатом действия оператора является неименованная таблица, на которую невозможно сослаться из других команд SQL. Тем не менее, произведенный оператором SELECT результат может быть использован для управления работой любого другого оператора DML. Кроме того, оператор SELECT используется в определениях ограничений, а представления можно трактовать как именованные операторы SELECT.

Оператор SELECT часто используется в предикатах SQL в качестве переменной в простом операторе сравнения или в качестве определения множества допустимых значений переменной в специальных предикатах. Это обеспечивает возможность вложения команд выборки данных, благодаря чему запрос любой сложности может быть сформулирован в виде одного оператора SELECT, содержащего несколько подзапросов – вложенных команд SELECT.

Многие основные и вспомогательные конструкции SQL созданы для описания понятий, связанных с выборкой данных. Поэтому мы начнем знакомство с языком именно с оператора SELECT, являющегося фундаментальным средством. Далее предполагается, что читатель владеет основными понятиями реляционной алгебры и реляционного исчисления, по крайней мере в объёме [2, пп. 2.5, 2.6].

Синтаксическая диаграмма оператораимеет вид:

SELECT [ DISTINCT ] { элемент_целевого_списка.,..}

| [ спецификатор. ]*

FROM {

{ имя_таблицы [ [AS] псевдоним [(имя_столбца., ..)] ]}

| { подзапрос [AS] псевдоним [(имя_столбца., ..)] }

| соединение

}.,..

[ WHERE предикат ]

[ GROUP BY { [ спецификатор. ] имя_столбца }.,..]

[ HAVING предикат ]

[ ORDER BY {{ имя_целевого_столбца [ ASC | DESC ]}.,..}

| {{ положительное_целое [ ASC | DESC ]}.,..}

]

;

Из синтаксической диаграммы видно, что в общем случае оператор может включать шесть предложений.[8] Два из них – SELECT и FROM – являются обязательными и входят в состав любого конкретного оператора выборки. Они указывают, что должно быть выбрано (целевой список предложения SELECT) и из каких таблиц (список таблиц в предложении FROM). Остальные четыре предложения (WHERE, GROUP BY, HAVING, ORDER BY) определяют условия, которым должны удовлетворять выходные данные.

Порядок следования предложений в любом реальном операторе SELECT должен соответствовать указаному в диаграмме.

Прежде чем познакомиться с деталями синтаксических конструкций, рассмотрим с концептуальной точки зрения процесс исполнения оператора в целом.

Обработка оператора SELECT

Последовательность обработки предложений в операторе SELECT (рис. 6.4) не вполне соответствует порядку их следования в синтаксической диаграмме.

Рис. 6.4 Порядок обработки предложений оператора SELECT

Первым всегда обрабатывается предложение FROM. Оно описывает источник данных – набор таблиц, содержащих запрашиваемые данные. В результате обработки в рабочем буфере системы создается неименованная временная таблица, которую мы будем называть далее F -таблицей. С концептуальной точки зрения она представляет собой расширенное прямое произведение таблиц, указанных после ключевого слова FROM [9].

Необязательные предложения WHERE, GROUP BY, HAVING, если они использованы в команде, обрабатываютсяв указанном порядке после предложения FROM. В результате обработки в рабочих буферах системы создаются неименованные временные таблицы, которые мы будем называть W -, G - и H -таблицами соответственно. Каждая из них является преобразованием таблицы предыдущего уровня.

W -таблица содержит только те строки F -таблицы, на которых предикат предложения WHERE принял значение TRUE.

G -таблица представляет собой F - или W -таблицу, строки которой собраныв группы с одинаковыми наборами значений в столбцах, указанных после ключевого слова GROUP BY.

H -таблица включает только такие группы строк из G -таблицы[10], на которых предикат предложения HAVING принял значение TRUE.

Выходная таблица запроса является результатом обработки предложения SELECT. В простейшем случае её можно представлять себе как реляционную проекцию F -, W -, G - или H -таблицы на столбцы, указанные после ключевого слова. На самом деле это неточно, так как элементами целевого списка запроса могут быть не только имена столбцов источника, но и выражения, агрегатные функции и т.п.

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

В процессе обработки оператора SELECT никаких изменений в физической базе данных не происходит. Система манипулирует копиями базовых таблиц в своих рабочих буферах.

На основании изложенного выше можно сформулировать следующий алгоритм исполнения оператора SELECT.

1. Вычислить и поместить в рабочий буфер F -таблицу – расширенное прямое произведение таблиц, указанных после слова FROM.

2. Если в состав оператора включено предложение WHERE, то для каждой строки F -таблицы вычислить значение предиката, указанного после ключевого слова. Вычислить и поместить в рабочий буфер W -таблицу, составленную из строк F -таблицы, на которых предикат принял значение TRUE.

3. Если в состав оператора включено предложение GROUP BY, то вычислить и поместить в рабочий буфер G -таблицу, собрав строки рабочего буфера в группы с одинаковыми значениями столбцов, указанных после ключевого слова, иначе выполнить п. 5.

4. Если в составе оператора присутствует ключевое слово HAVING, то для каждой группы строк G -таблицы вычислить значение предиката, указанного после ключевого слова. Вычислить и поместить в рабочий буфер H -таблицу, составленную из строк G -таблицы, на которых предикат принял значение TRUE.

5. Если в рабочем буфере находится F -таблица или W -таблица, то для каждой строки рабочего буфера вычислить значения столбцов, указанных после ключевого слова SELECT, и сформировать строку выходной таблицы запроса.

Иначе, если в рабочем буфере находится G -таблица или H -таблица, то для каждой группы строк рабочего буфера вычислить значения столбцов, указанных после ключевого слова SELECT, и сформировать одну строку выходной таблицы запроса.

6. Если в составе оператора присутствует ключевое слово ORDER BY, то отсортировать строки выходной таблицы запроса по значениям столбцов, указанных после ключевого слова.

Ни одна реляционная СУБД не реализует этот алгоритм вследствие его сугубой неэффективности. Его следует считать алгоритмическим определением оператора SELECT.

Рассмотрим теперь синтаксические конструкции оператора более детально.

Предложение SELECT

Предложение SELECT описывает целевой список – заголовок выходной таблицы запроса.

Список может задаваться посредством перечисления элементов.

элемент_целевого_списка::=

{

{

{[ спецификатор. ] имя_столбца }

| выражение

| агрегатная_функция

}

[ AS имя_целевого_столбца ]

}

| символьная_константа

спецификатор – имя или псевдоним источника данных;

имя_столбца – имя столбца источника данных;

выражение – допустимое выражение для вычисления значения;

агрегатная_функция – функция множества значений (столбца), возвращающая скалярное значение [2, п.2.5.5];

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

символьная_константа – любая последовательность допустимых символов.

В этом случае порядок следования столбцов выходной таблицы запроса задаётся явно, а типы и длины значений столбцов наследуются от соответствующих столбцов базовых таблиц.

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

Примеры допустимых предложений SELECT приведены ниже.

Предложение FROM

Предложение FROM определяет исходные данные для запроса – источник данных. Обычно источниками данных являются именованные таблицы.

имя_таблицы – имя базовой таблицы или представления.

[ AS ] псевдоним [(имя_столбца., ..)]– необязательная конструкция, определяющая новое имя таблицы и, возможно, новые имена её столбцов. Ключевое слово AS смысловой нагрузки не несёт. Псевдоним используется для ссылок в последующих предложениях команды и действителен только внутри того оператора SELECT, в котором определён. Обычно именованным таблицам назначают псевдонимы для того, чтобы облегчить понимание запроса человеком. Однако в ряде случаев псевдонимы необходимы для разрешения конфликтов имён.

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

Конструкция

подзапрос [ AS ] псевдоним [(имя_столбца.,..)]

предназначена для обеспечения ссылок на столбцы результата запроса. Здесь подзапрос – заключённый в круглые скобки оператор SELECT произвольной сложности. В этом случае псевдоним обязателен. Он используется как локальное имя неименованной таблицы, произведённой подзапросом.

Рассмотрим здесь несколько запросов на выборку данных к нашей «учебной» БД (см. приложение А). В примерах используются только обязательные предложения оператора SELECT. Реализации источников данных приведены в приложении А.

Пример 1. Получить имена и статусы всех поставщиков.

SELECT S.Snam, S.St

FROM S;

Этот оператор произведёт следующую таблицу:

Snam St
Иван  
Николай  
Григорий  
Петр  
Константин  
Иван  
Сергей  
Владимир  
Егор  

Процедура её постороения может (концептуально!) состоять из перечисленных ниже шагов.

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

Шаг 2. Скопировать в рабочий буфер базовую таблицу S. Тем самым будет создана F -таблица, эквивалентная S.

Шаг 3. Выделить в рабочем буфере пространство для выходной таблицы запроса и форматировать его в соответствии с определениями столбцов S.Snam, S.St.

Шаг 4. Скопировать в выделенное пространство содержимое столбцов Snam, St временной таблицы, созданной на шаге 2.

Временная таблица, созданная на шаге 4, и есть выходная таблица запроса. Она может содержать дубликаты строк, т.е., строго говоря, не является реляционной проекцией таблицы S на столбцы Snam, St. В дальнейшем мы будем называть эту операцию SQL-проекцией. Действительно, первая и последняя строки приведённой выше таблицы дублируют друг друга. Для того чтобы получить «чистую» проекцию, следует записать оператор так[11]:

SELECT DISTINCT Snam, St

FROM S;

Использованное здесь ключевое слово DISTINCT сообщит системе, что для завершения работы над запросом она должна выполнить ещё один шаг:

Шаг 5. Исключить дубликаты строк из временной таблицы, созданной на шаге 4.

Замечание. На практике это может привести к потере информации. Так, в нашем примере существует два различных поставщика с одинаковыми именами и статусами. Удалив дубликат строки из выходной таблицы, мы утеряем информацию об одном из них.

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

SELECT DISTINCT Snam AS Имя, St AS Статус

FROM S;

В этом случае формирование выходной таблицы завершится следующим шагом:

Шаг 6. Во временной таблице, созданной шагом 5, изменить имена столбцов Snam и St на Имя и Статус соответственно.

Вот выходная таблица, построенная этим оператором:

Имя Статус
Владимир  
Григорий  
Иван  
Константин  
Николай  
Петр  
Егор  
Сергей  

Пример 2. Получить номера и наименования всех деталей и их веса в килограммах.

SELECT Pnum, Pnam, We/1000

FROM P;

Этот оператор реализует реляционную операцию расширения схемы [2, с.82]. Шаги 1 и 2 процедуры обработки этого запроса аналогичны описаным выше. На следующем шаге будет сформирована новая временная таблица, содержащая неименованный столбец, принимающий значения выражения We/1000. Затем система выполнит SQL-проекцию этой таблицы на столбцы Pnum, Pnam и дополнительный неименованный столбец. Результат приведён ниже.

Pnum Pnam  
P1 корпус 0,3
P2 разъём 0,003
P3 кнопка 0,005
P4 корпус 0,8
P5 панель 0,1
P6 кинескоп 1,2
P7 кнопка 0,01
P8 панель 0,45
P9 лампочка 0,001

Следующий оператор произведёт более наглядную таблицу.

SELECT Pnum AS Номер,

Pnam AS Наименование,

We/1000 AS Вес,

'кг' AS Ед. измер.

FROM P;

При обработке предложения SELECT этого оператора временная таблица, построенная предложением FROM, будет дополнена двумя именованными столбцами. Они будут принимать значения выражений, одно из которых является символьной константой. Выходная таблица запроса имеет вид:

Номер Наименование Вес Ед. измер.
P1 корпус 0,3 кг
P2 разъём 0,003 кг
P3 кнопка 0,005 кг
P4 корпус 0,8 кг
P5 панель 0,1 кг
P6 кинескоп 1,2 кг
P7 кнопка 0,01 кг
P8 панель 0,45 кг
P9 лампочка 0,001 кг

Если источником данных является одна базовая таблица, обязательные предложения оператора SELECT могут указывать лишь на две операции – расширения схемы и SQL-проекции.

6.2.6 Предикаты SQL

Предикаты используются в предложениях WHERE и HAVING оператора SELECT для определения условий, которым должны удовлетворять выбираемые строки F - или G -таблицы. Кроме того, в операторах обновления данных они указывают область действия, а в операторах определения объектов задают ограничения на вводимые значения данных.

предикат::= [(] [NOT] элементарный_предикат

[{AND | OR} предикат ] [)] [IS [NOT] 3VL-значение ]

элементарный_предикат::= предикат_comparision

| предикат_between

| предикат_in

| предикат_like

| предикат_null

| предикат_quantifired_comparision

| предикат_exists

| предикат_unique

| предикат_match

| предикат_overlap

3VL-значение::= TRUE | FALSE | UNKNOWN

SQL использует трёхзначную логику (3VL). Это обусловлено тем, что допускаются неопределённые (NULL) значения столбцов. NULL -значения могут появляться в строках производных таблиц в результате выполнения некоторых операций, например, внешних соединений. Эти значения могут участвовать в операциях сравнения. Поскольку невозможно сказать что-либо определённое о результате сравнения с участием NULL, приходится наряду с TRUE (истина) и FALSE (ложь) вводить ещё одно возможное значение результата сравнения – UNKNOWN (неизвестно) – и определять исчисление высказываний на трёхзначном множестве.

Предикаты SQL могут принимать значения TRUE, FALSE или UNKNOWN.

Предикаты могут быть операндами булевых операторов AND, OR, NOT, а также SQL-оператора IS. Ниже приведены таблицы истинности для этих операторов.



Поделиться:


Последнее изменение этой страницы: 2016-04-07; просмотров: 522; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.142.198.108 (0.015 с.)