SQL для простых смертных [Мартин Грабер] (pdf) читать онлайн

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

Understanding

SQL
MARTIN GRUBER

SQL

для простых смертных
Мартин Грабер

Издательство "ЛОРИ"

Understanding SQL.
Martin Gruber.
© Copyright All rights reserved

Ьу

SQL для

простых смертных.

Мартин Грабер.

Переводчик В.А.Ястребов
Научный редактор П.И.Быстров.
Верстка М.Алиевой.

Copyrigl1t © 1990 SYBEX Inc., 2021 Challenger Drive,
Alameda, СА 94501.

Перевод© Издательство «ЛОРИ»,

2014

Посвящается Ли и Джанет Фесперман, предоставившим мне

возможность полностью посвятить себя написанию этой книги.

БЛАГОДАРНОСТИ

Мне хотелось бы поблагодарить
воспользоваться

FirstSQL

FFF Software за

разрешение

при подготовке этой книги.

Содер:нсание

Введение

Глава

1.

Х\

Введение в реляционные базы данных
Что такое реляционная база данных?

3
5
7

Пример базы данных
Итоги
Глава

2.

...... .

Введение в

SQL .
SQL?

9

Как работает

Глава

г,~ава

Глава

3.

4.

5.

10

Различные типы данных

12

Итоги

15

.......... .

Использование

17

Формирование запроса

SQL для выборки данных из таблиц
. . . . . . . . . . . . . .
Определение выборки - предложение WHERE
Итоги . . . . . . . . . . . . . . . . . . . . . . . .

18
24

26

Использование реляционных и булевых операторов
для создания более сложных предикатов

29

Реляционные операторы
Булевы операторы.

30
32

Итоги

37

....... .

Использование специальных операторов в "условиях"

Оператор
Оператор

39
40
41
44

IN . . . . .
BETWEEN

Оператор LIКE

47
49

Оператор
Итоги
Глава

6.

IS NULL
....... .

Суммирование данных с помощью функций агрегирования

51
52
61

Что такое функции агрегирования?

Итоги
Глава

7.

................ .

Форматирование результатов запросов.

63
64

Строки и выражения
Упорядочение выходных полей

Итоги

67
71

.............. .

vii

Содержание

Глава

8.

Использование множества таблиц в одном запросе

75
76
81

.

Соединение таблиц
Итоги

Глава

9.

Операция соединения, операнды которой представлены одной таблицей

83

Как выполняется операция соединения двух копий одной таблицы

84
90

Итоги
Глава

10.

Вложение запросов

93

.

94
105

Как выполняются подзапросы?
Итоги

Глава

11.

.......... .

107
108
115

Связанные подзапросы
Как формировать связанные подзапросы
Итоги

Глава

12.

Глава

13.

Глава

14.

................. .

Использование оператора

EXISTS .
EXISTS? . . .
Использование EXISTS со связанными подзапросами
Итоги . . . . . . . . . . . . . . . . . . . . . . . . .

117

Как работает оператор

118

Использование операторов

127

Специальный оператор

128

ANY, ALL и SOME
ANY или SOME
Специальный оператор ALL . . . . . . .
Функционирование ANY, ALL 11 EXISTS при потере данных
с неизвестными данными .
Итоги . . . . . . . . . . . . . . . . . . .
Использоваю1е предложения

UNION

Объединение множества запросов в один
Использование
Итоги
Глава

15.

UNION с ORDER ВУ
................. .

139
143
145
146
151
157
159

160
160
162
163
165

DML . .
. . . . . . . . .

Изменение значений полей
Итоги

........... .

Использование подзапросов с командами обновле1111я

Использование подзапросов в
Использован11е подзапросов с

viii

135
или

Команды обновления

Исключение строк из таблицы

16.

119

124

Ввод, уда:1е1ше и 11зменение значений полей

Ввод значений

Глава

.

INSERT
DELETE

167
168
170

Содержание

Использование подзапросов с

...... .

173
174

Создание таблиц

177

Команда

178
179
181
182
183

Итоги
Г.1ава

17.

Индексы

UPDATE

CREATE ТABLE
......... .

Изменение таблицы, которая уже была создана
Исключение таблицы
Итоги

Глава

18.

........ .

185
186
195

Ограничения на м11ожество допустимых значений данных
Ограничения в таблицах

Итоги
Глава

19.

.......... .

Поддержка целостности данных
Внешние и родительские ключи
Ограничения

FOREIGN

197
198
199
204
209

.

КЕУ (внешнего ключа)

Что происходит при выполнении команды обновления
Итоги

Глава

20.

............ .

211
212
212
221

Введение в представления
Что такое представления?
Команда

CREATE VIEW

Итоги
Глава

21.

223
224
228
232

Изменение значений с помощью представлений

Обновление представлений

. . . . . . . . . . . . .

Выбор значений, размещенных в представлениях
Итоги

Глава

22.

.................. .

Определение прав доступа к данным
Пользователи

235
236
237
241
245
247

. . . .

Передача привилегий
Лишение привилегий
Другие типы привилегий

Итоги

Г.'Jава

23.

.......... .

Глобальные аспекты

249
250
252
253
255
259

SQL

Переименование таблиц

. .

Каким образом база данных размещается для пользователя?

Когда изменения становятся постоянными?
Как

SQL работает

Итоги

. . . . . . . . .

одновременно с множеством пользователей

............................... .

ix

Содержание

Глава

24.

Как поддерживается порядок в базе данных

Системный каталог

SQL

. . . . . . . . . . .

Комментарии к содержимому каталога

Оставшаяся часть каталога

. .

Другие пользователи каталога

Итоги
Глава

25.

............. .

SQL с другими языками программировании
SQL) . . . . . . . . . . . . . . . . . . . . . .
Что включается во встроенный SQL? . . . . . . . . . . . .
Использование переменных языка высокого уровня с SQL
SQLCODE . . . . . . . .
Обновление курсоров . .

261
262
266
268
275
276

Использование
(встроенный

Индикаторы переменных
Итоги

.......... .

279
280
282
288
291
293
296

Приложения
А. Ответы к упражнениям

301

В. Типы данных

319
320
322

ТипыАNSI

SQL . . .
..... .

Эквивалентные типы данных в других языках

С. Некоторые общие отклонения от стандарта
Типы данных

.

SQL

. . .

Команда FORМAT

. . . . . . . . . . . . . . . .
.................... .
Операции INTERSECT (пересечение) и MINUS (разность)
Автоматические OUTER JOINS (внешние соединения) .
Ведение журнала . . . . . . . . . .
Функции

О. Справка по синтаксису и командам

.
SQL . . . . . . . . . . .
SQL

Элементы

Команды

325
326
328
330
332
333
334
337
338
345

Е. Таблицы, используемые в примерах

355

F. SQL сегодня ..
SQL сегодня

357
358

ВВЕДЕНИЕ
SQL (обычно произносится "SEQUEL") - структурированный язык запросов
(Structured Query Language). Он позволяет создавать реляционные базы данных,
представляющие собой набор связанных данных, хранящихся в таблицах, и опери­
ровать ими.

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

нию и интеграции информации из множества разнообразных источников.

Благодаря своей элегантности и независимости от специфики компьютера, а также
поддержке лидерами в области технологии реляционных баз данных, SQL стал и в
ближайшем обозримом будущем останется таким стандартным языком. Именно по
этой причине, тот, кто предполагает работать с базами данных в девяностые годы на­
шего столетия, должен владеть языком SQL.
Стандарт SQL определен американским национальным институтом стандартов
(American National Standarts Institute) и в настоящее время принят также ISO
(Intemational Standards Organization) в качестве международного стандарта. Однако по­

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

Кто мо:нсет воспользоваться этой книгой?
Для чтения этой книги требуются минимальные знания из области компьютеров и
баз данных. Использовать

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

xi

ние материала и мастерство. Можно выполнять полезные задания немедленно, и, по

мере их выполнения, мастерство будет расти.
Поскольку

SQL является

частью многих программ, выполняющихся на различных

компьютерах, никаких предположений относительно специфики использования языка

не делается. Эта книга является самым общим пособием. Вы сможете непосредствен­
но применить полученные знания в любой системе, использующей

SQL.
SQL представ­

Книга предназначена для новичков в области баз данных, однако

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

ния

SQL.

Как организована эта книга?
Каждая глава вводит новую группу взаимосвязанных понятий и определений. Они
базируются на рассмотренном ранее материале и содержат практические вопросы для
закрепления полученных знаний. Ответы на практические вопросы приведены в при­
ложении А.
Первые семь глав содержат основные понятия реляционных баз данных и SQL,
за ними следуют основы запросов (queries). Запросы команды, используемые
для поиска данных в базах данных; они представляют собой наиболее общий и

наиболее сложный аспект SQL. В главах с 8 по 14 техника запросов усложняется.
Вводятся различные способы комбинирования запросов и запросы более чем к од­
ной таблице. Другие аспекты

SQL:

создание таблиц, ввод в них значений, предос­

тавление и закрытие доступа к созданным таблицам

по

23.

Глава

24

данных. В главе

-

рассмотрены в главах с

15

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

25

речь идет об использовании

SQL

в программах, написанных на

других языках.

В зависимости от того, как будет использоваться

SQL,

часть информации, рас­

положенной в конце книги, может не пригодиться. Не все пользователи создают

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

разделы, которые никогда не придется использовать. Именно по этой причине вве­
дение в запросы полностью представлено в начале книги. Запросы

-

это основа,

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

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

Содержимое книги по главам выглядит следующим образом:



xii

Глава

1 дает понятие реляционной базы данных и концепции первичных клю­
чей (priшary keys). В ней также приводятся и поясняются три таблицы, на кото­
рых базируется множество представленных в книге примеров.



Глава

2

ориентирует вас в мире

SQL.

В ней рассматриваются важные вопросы

структуры языка, различные типы данных, распознаваемые
щие соглашения



Глава

SQL

SQL,

некоторые об­

и терминология.

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

3

уточнению. После изучения этой главы вы сможете использовать

SQL с

практи­

ческой пользой.



Глава

4

иллюстрирует, каким образом применяются в

SQL

два типа стандарт­

ных математических операторов, отношения(=,, и т.д.) и булевы операции

(AND, OR, NOT).



Глава

5

вводит ряд операторов, которые используются так же, как операторы

отношения, но являются специфичными для

SQL.

В этой главе даются разъяс­

нения по вопросу потери данных, и определены NULL-значения.



Глава

6

учит применять операторы, позволяющие выводить данные на основе

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



Глава

поясняет ряд действий, возможных при выводе запроса: выполнение

7

математических операций над данными, включение текста, сортировка.



Глава

показывает, как простой запрос может извлекать информацию более

8

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



Глава

9

демонстрирует технику получения ответа на запрос по множеству таб­

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



Глава



научит выполнять запрос и использовать его результат в другом за­

ll

расширяет технику, рассмотренную в главе

просе.



Глава

10,

и учит использовать

вложенные запросы многократно.



Глава

12

вводит новый тип специального оператора

SQL. EXISTS -

оператор,

действующий на весь запрос, а не на отдельное простое значение.



Глава

13

вводит новый тип операторов

оператору



Глава

14

EXISTS,

-ANY, ALL, SOME,

которые, подобно

действуют на весь запрос.

вводит команды, позволяющие непосредственно комбинировать ре­

зультаты множественных запросов способом, отличным от их последовательно­
го выполнения.

xiii



Глава

15

вводит команды, позволяющие определить, какие значения хранятся в

базе данных, а также команды вставки, удаления и обновления значений.



Глава

16

расширяет мощность только что введенных команд. В ней показано,

как запросы могут управлять их выполнением.




Глава

17

учит создавать новую таблицу.

Глава

18 детально

объясняет процесс создания таблиц. Вы узнаете, как предусмот­

реть отказ от автоматического выполнения некоторого вида изменений.



Глава

19

исследует логические связи, существующие между данными, на осно­

ве совпадения значений.



Глава

20

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

отличную от той, что хранится в базе данных.



Глава

21

касается сложных вопросов изменения значений в представлениях, ко­

гда вы реально изменяете соответствующие таблицы. Именно с этим связана
здесь необходимость рассмотрения специальных вопросов.



Глава

22

рассказывает о привилегиях: кто имеет право обращаться с запросами

к таблицам, кто имеет право изменять их содержимое, как эти права назначают­
ся пользователям, как пользовате.1и их лишаются и т.д.



Глава

23

представляет некоторые ранее не рассмотренные важные моменты.

Например, мы обсудим те изменения базы данных, которые становятся посто­
янными, а также выполнение ряда операций в



Глава

24

описывает, как

SQL

SQL.

поддерживает структурирование баз данных и ка­

ким образом осуществляется доступ к ним.



Глава

25

фокусирует внимание на специальных проблемах и процедурах, свя­

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

FETCH.
В приложениях вы найдете ответы на вопросы (приложение А), описание таблиц,
рассматриваемых в качестве примеров (приложение В), детальные сведения о различ­
ных типах данных (приложение С), общие элементы, отличные от стандарта (прило­

жение

D),

руководство по командам

(приложение

xiv

F).

SQL (приложение

Е), взгляд на современный

SQL

Соглашения, принятые в этой книге
SQL

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

той базы данных, предлагая ей выполнить определенные действия. Эти инструкции в
общем виде называют предложениями, но мы в большинстве случаев будем использо­
вать термин "команды", чтобы показать, что они имеют область действия.
Термины выделены курсивом в тех местах, где они в первый раз встречаются.
В синтаксисе команд курсив используется для того, чтобы показать, что слова имеют
дополнительный смысл.
В примерах представлен текст, который следует ввести в программу обработки
базы данных, и показан результат для конкретного программного продукта

(FirstSQL,

программа, работающая с базой данных на IВМ РС). Результат, полученный с помо­
щью других программных продуктов, может отличаться от приведенного, но основ­

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

xv

1

ШrnWШllJM·•'(Q
Введение
в реляционные

базы данных

Глава

1. Введение в реляционные базы данных

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

SQL,

поэтому вы

можете пропустить ее, если достаточно хорошо владеете основным понятиями реля­

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

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

иЕ. Мы рекомендуем постоянно иметь копию этих таблиц перед глазами.

Что такое реляционная база данных?
Реляционная база данных

-

это связанная информация, представленная в виде

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

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

-

представленных в каждой строке. Адресная книга может выгля­

деть таким образом:

Name

Telephone

Address

(Имя)

(Телефон)

(Адрес)

Gcrтy

(415 )365-8775
(707) 874-3553
(762)976-3665

127 Primrose Ave., SF
246 #4 3rd St., Sonoma
778 Modernas, Barcelona

Farish
Ce\ia Brock
Yves Grillet

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

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

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

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

Balance (Баланс).

2

Patient

(Пациент),

Doctor

(Врач),

Insurer

(Страховка),

Что такое реляционная база данных?

Patient

Doctor

Insurer

(Пациент)

(Врач)

(Страховка)

(Баланс)

Farish
Grillet
Brock

Drume
Halben
Halben

В.С./В.S.

$272.99
$44.76
$9077.47

None
Health, Inc.

Balance

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

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

Brock,

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

SQL предоставит доктору Halben

необходимую информацию практически мгновенно.

Порядок строк произволен
Дriя обеспечения максимальной гибкости при работе с данными строки таблицы, по
определению, никак не упорядочены. Этот аспект отличает базу данных от адресной кни­
ги. Строки в адресной книге обычно упорядочены по алфавиту. Одно из мощных средств,
предоставляемых реляционными системами баз данных, состоит в том, что пользователи

могут упорядочивать информацию по своему желанию.
Рассмотрим вторую таблицу. Содержащуюся в ней информацию иногда удобно рас­
сматривать упорядоченной по имени, иногда в порядке возрастания или убывания
баланса (Balance), а иногда сгруппированной по доктору. Внушительное множество
возможных порядков строк помешало бы пользователю проявить гибкость в работе с
данными, поэтому строки предполагаются неупорядоченными. Именно по этой причи­

не вы не можете просто сказать: "Меня интересует пятая строка таблицы". Независимо

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

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

3

Глава

1. Введение в реляционные базы

сколько пациентов с именем

данных

Mary Smith.

В подобном случае нет простого способа их

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

(p1·imary key of t/1e

tаЫе).

Первичный ключ таблицы

-

жизненно важное понятие структуры базы данных.

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

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

ния ссылочной целостности

(referential integrity)

в главе

19.

Столбцы поименованы и пронумерованы
В отличие от строк, столбцы таблицы (также называемые пошн1и

(fields)

упорядо­

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

"Address"

как на "столбец номер три". Естествен­

но, это означает, что каждый столбец данной таблицы должен иметь имя, отличное от
других имен, для того, чтобы не возникло путаницы. Лучше всего, когда имена опре­
деляют содержимое поля. В этой книге мы будем использовать аббревиатуру для име­
нования столбцов в простых таблицах, например: с11а111е

-

для имени покупателя

для даты поступления (order date). Предположим также, что
таблица содержит единственный цифровой столбец, используемый как первичный
ключ. В следующем разделе детально объясняются таблицы, используемые в качестве

(customer name), odate -

примера и их ключи.

Пример базы данных
Таблицы

1.1, 1.2, 1.3

образуют реляционную базу данных, которая достаточно

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

SQL,

мы реко­

мендуем скопировать их и постоянно иметь перед глазами. Можно заметить, что пер­

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

4

Пример базы данных

Таблица

1.1. Salespeople

(Продавцы)

SNUM

SNAME

СIТУ

со мм

1001

Рее!

London

.12

1002

.13

Seпes

San Jose

1004

Motika

London

.11

1007

Rifkin

Barcelona

.15

1003

Axelrod

New York

.10

Таблица

1.2. Customers

(Покупатели)

CNUM

CNAME

СIТУ

RAТING

SNUM

2001

Hoffman

London

100

1001

2002

Giovanпi

Rome

200

1003

2003

Liu

San Jose

200

1002

2004

Grass

Berlin

300

1002

2006

Clemens

London

100

1001

2008

Cisneros

San Jose

300

1007

2007

Pereira

Rome

100

1004

АМТ

ODATE

CNUM

SNUM

3001

18.69

10/03/1990

2008

1007

3003

767.19

10/03/1990

2001

1001

3002

1900.10

10/03/1990

2007

1004

3005

5160.45

10/0311990

2003

1002

3006

1098.16

10/03/1990

2008

1007

3009

1713.23

10/04/1990

2002

1003

3007

75.75

10/0411990

2004

1002

3008

4723.00

10/05/1990

2006

1001

3010

1309.95

10/0611990

2004

1002

3011

9891.88

10/06/1990

2006

1001

Таблица

1.3. Orders

ШiUM

(Заказы)

Например,

(salespeople)

поле snum в таблице Customers определяет, каким продавцом
обслуживается конкретный покупатель (customer). Номер поля snum ус-

5

Глава

1. Введеиие в реляциоиные базы даииых

танавливает связь с таблицей

(salespeople).

Salespeople, которая дает информацию об этом продавце
Очевидно, что продавец, который обслуживает данного покупателя, су­

ществует, т.е. значение поля snum в таблице Customers присутствует также и в таблице
Salespeople. В этом случае мы говорим, что система находится в состоянии ссылочной
целостности (referential iпtegrity). Это понятие более подробно и формально объясня­
ется в главе 19.
Сами по себе таблицы предназначены для описания реальных ситуаций в деловой
жизни, когда можно использовать

SQL для ведения дел, связанных с продавцами, их
покупателями и заказами. Давайте зафиксируем состояние этих трех таблиц в какой­

либо момент времени и уточним назначение каждого из полей таблицы.
Перед вами объяснение столбцов таблицы l . l :
ПОЛЕ

СОДЕРЖИМОЕ

snum

Уникальный номер, приписанный каждому продавцу ("номер

служащего")

sname

Имя продавца

city

Место расположения продавца

comm

Вознаграждение (комиссионные) продавца в форме с десятич­
ной точкой

Таблица

1.2

содержит следующие столбцы:

ПОЛЕ

СОДЕРЖИМОЕ

cnum

Уникальный номер, присвоенный покупателю

cname

Имя покупателя

city

Место расположения покупателя

rating

Цифровой код, определяющий уровень предпочтения данного

покупателя. Чем больше число, тем больше предпочтение

snum

Номер продавца, назначенного данному покупателю (из табли­
цы

Salesperson)

И, наконец, столбцы таблицы

6

1.3:

Итоги

ПОЛЕ

СОДЕРЖИМОЕ

onum

Уникальный номер, присвоенный данной покупке

amt

Количество

odate

Дата покупки

cnum

Номер покупателя, сделавшего покупку (из таблицы

snum

Номер продавца, обслужившего покупателя (из таблицы

Customers)

Salespeople)

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

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

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

Теперь мы готовы к непосредственному погружению в

SQL.

Следующая глава, к

которой вам время от времени придется возвращаться, дает общее представление о
языке и ориентирует вас в изложенном в книге материале.

7

Работаем на

SQL

1.

Какое поле в таблице Custoшers является первичным ключом?

2.

Дайте объяснение столбцу с номером

3.

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

4.

Почему нельзя попросить показать вам первые пять строк таблицы?

(Ответы см. в приложении А.)

8

4

в таблице Custoшers?

2
Введение в

SQL

Глава

2. Введение в SQL

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

стях, существующих в

SQL.

Здесь же уточняется контекст специфической информа­

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

SQL,

не

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

Как работает
SQL -

SQL?

это язык, ориентированный специально на реляционные базы данных. Он

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

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

ввода значений в таблицу и для поиска в ней данных. Для нахождения каких-то кон­
кретных строк пришлось бы выполнить последовательность действий, например:

l.

Посмотреть очередную строку таблицы.

2.

Оттестировать ее и убедиться, что это та строка, которая Вас интересует.

3.

Запомнить ее до тех пор, пока не будет просмотрена вся таблица.

4. Определить, есть ли в таблице еще строки.

5.

Если в таблице еще есть строки (просмотрены не все строки), то вернуться к шагу

6.

Если в таблице больше нет строк (просмотрены все строки таблицы), вывести все

1.
значения, полученные на третьем этапе.

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

SQL

единого целого.

Как осуществляется связь с АNSI-таблицей?
Стандарт SQL определен ANSI (American National Standards Institute - Американ­
ским национальным институтом стандартов). SQL не является изобретением ANSI,
он - продукт исследований фирмы IВМ. Однако другие компании тоже внесли свою
лепту в развитие SQL; по крайней мере, компания Oracle превзошла IВМ в создании
популярного рыночного программного SQL-продукта.
После того, как на рынке появилось несколько конкурирующих SQL-продуктов,

ANSI

10

определила стандарт, которому все они должны удовлетворять. Однако вве-

Как работает

дение стандарта

SQL

post factum

SQL?

порождает ряд проблем. Результирующий стандарт

в некотором смысле ограничен: то, что определено

ANSI,

не всегда является

наиболее полезным с точки зрения практического применения, поэтому создатели

SQL-продуктов стараются разрабатывать их таким образом, чтобы они соответст­
вовали стандарту

ANSI,

но не были бы слишком жестко ограничены его требова­

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

-

СУБД), обычно придают

ANSI SQL дополнительные

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

ANSI

тоже следует проанализировать. Рассмотреть каждое отдельное исключение и от­
клонение от стандарта невозможно, однако полезные идеи, как правило, копируют­
ся и применяются одинаково в различных программных продуктах, даже если они

не специфицированы

ANSI. ANSI -

это своего рода минимальный стандарт; мож­

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

Интерактивная версия встроенного

SQL

Существуют два SQL: интерактивный и встроенный. В основном эти две формы
SQL работают одинаково, но используются по-разному.
Интерактивный SQL применяется для выполнения действий непосредственно в
базе данных с целью получить результат, который используется человеком. При при­
менении этой формы

SQL

вводится команда, она выполняется, после чего можно не­

медленно увидеть выходные данные (если таковые есть).

Встроенный

SQL

состоит из команд

SQL,

включенных в программы, которые в

большинстве случаев написаны на каком-то другом языке программирования (напри­
мер,

Cobol

или

Pascal).

Такое включение может сделать программу более мощной и

эффективной. Однако, несовместимость этих языков программирования со структу­
рой

SQL

и присущим ему стилем управления данными требует внесения ряда расши­

рений в интерактивный

SQL.

Выходные данные команд

SQL

во встроенном

SQL

"заносятся" в переменные или параметры, используемые программой, в которую

включены предложения

SQL.

В этой книге представлена интерактивная форма

SQL,

что позволит обсуждать ко­

манды и их действие, не обращая внимания на то, как они взаимодействуют с другими
языками. Именно интерактивный

SQL наиболее полезен для непрограммистов. Все,
SQL, справедливо и для его встроенной формы.

что характерно для интерактивного

Изменения, которые следует выполнить в связи со встроенной формой, рассматрива­
ются в последней главе этой книги.

11

Глава

2.

Введение в

SQL

Подразделы

SQL

Как в интерактивном, так и во встроенном
подразделов. В процессе освоения

SQL имеется множество секций или
SQL придется придерживаться данной терминоло­

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

реализациях

SQL.

Им придается особое значение в

ANSI,

и они полезны на концепту­

альном уровне, но во многих SQL-продуктах они практически не выделены, и поэто­
му стали функциональными категориями SQL-команд.

Язык определения данных (Data Definition Language, DDL; в ANSI он называется
также языком определения схемы (Schema Definition Language)) состоит из тех команд,
которые создают объекты (таблицы, индексы, представления) в базе данных. Язык ма­
нипулирования данными (Data Manipulation Language, DML) - это множество команд,
определяющих, какие данные представлены в таблицах в любой момент времени. Язык
управления данными

(Data Control Language, DCL)

состоит из предложений, опреде­

ляющих, может ли пользователь выполнить отдельное действие. Согласно
является частью

DDL.

ANSI, DCL

Важно не путать эти названия. Речь идет не о различных языках

как таковых, а о разделах команд

SQL,

сгруппированных в соответствии с их функцио­

нальным назначением.

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

данных должны явно отличаться друг от друга, чтобы можно было применить подхо­
дящие способы их обработки и сравнения.
В SQL каждому полю приписывается "тип данных" (data type ), который определя­
ет, какого рода значения могут содержаться в поле. Все значения для данного поля
должны быть одного типа. В таблице Customers, например, поля cname и city являются
строками текста, тогда как поля rating, snum, cnum числовые. Именно по этой при­

чине невозможно занести значения "Highest" или "None" в поле rating, имеющее чи­
словой тип. Это удачное ограничение, поскольку оно накладывает некоторую
структуру на конкретные данные. Операцию сравнения, которая выполняется для од­
них строк и не выполняется для других, невозможно произвести, если значения поля

имеют смешанный тип данных.
Определение этих типов данных является той областью, в которой многие коммер­
ческие СУБД и официальный стандарт

SQL имеют существенные различия. Стандарт
ANSI SQL распознает только текстовый и числовой типы, тогда как многие коммерче­
ские СУБД используют и другие специальные типы данных. Заметим, что типы DATE
(дата) и TIME (время) почти de-facto являются стандартными (хотя конкретные их
форматы отличаются). Некоторые СУБД поддерживают такие типы данных как

MONEY

12

(деньги) и

BINARY

(двоичный).

(BINARY -

это специальное числовое

Различные типы данных

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

-

так ее легче

использовать и понимать.)

ANSI определяет несколько
ANSI полностью перечислены

различных типов числовых значений. Типы данных
в приложении В. Сложность числовых типов

ANSI

объясняется, по крайне мере частично, попыткой поддержать совместимость вложен­
ного

SQL с

множеством других языков.

Два типа данных

аббревиатуру

INT

и

ANSI, INTEGER и DECIMAL (для
DEC соответственно}, адекватны и

которых можно использовать
теоретическим целям, и мно­

жеству практических приложений в деловой жизни. INTEGER отличается от
DECIMAL тем, что запрещает использовать цифры справа от десятичной точки, а так­
же саму десятичную точку.

Типом данных для текста является

CHAR (CHARACTER),

который относится к

строке текста. Поле типа CHAR имеет фиксированную длину, равную максимальному
числу букв, которые можно ввести в это поле. Большинство реализаций SQL имеет не­
стандартный тип, названный VARCHAR, - это текстовая строка любой длины вплоть
до максимума, определяемого конкретной реализацией SQL. Значения CHAR и
VARCHAR заключаются в одиночные кавычки, как, например, 'текст'. Различие между
ними состоит в том, что для типа CHAR отводится участок памяти, достаточный для
хранения строки максимальной длины, а для

VARCHAR

память выделяется по мере

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

в том числе и цифр. Однако, число

1 не

есть то же самое, что символ

'1 '.

Символ

'1'

это

совсем другая часть печатного текста, которая не распознается компьютером как чи­

словое значение

1. 1+1=2, но '1' + '1'

не равно

'2'.

Значения типа

CHARACTER хра­

нятся в компьютере как двоичные значения, но для пользователя представляются в

виде печатного текста. Преобразование выполняется в соответствии с форматом, оп­
ределяемым той системой, которой вы пользуетесь. Это может быть формат одного из
двух стандартных типов (возможно, с расширениями), которые применяются в компь­
ютерных системах : ASCII (используется во всех персональных и большинстве малых
компьютеров) и EBCDIC (используется для больших компьютеров). Определенные
операции, такие как упорядочение значений поля по алфавиту, зависят от формата.
Значения этих двух форматов будут рассмотрены в главе
Тип

DATE

В реализациях

4.

будет применяться в соответствии с требованиями рынка, а не

SQL,

не распознающих тип

DATE,

ANSI.

можно объявить дату символьным

или числовым полем, но это затруднит выполнение множества операций. Следует оз­

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

Кто такой "пользователь"?
SQL устанавливается,

как правило, в компьютерных системах, имеющих не од­

ного, а многих пользователей, которых нужно уметь различать (у семейного РС мо­

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

13

Глава

2. Введение в SQL

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

системе, сообщая компьютеру, какой именно пользователь, идентифицированный
кодом авторизации

ID,

находится на связи. Что касается компьютера, то любое чис­
ID, является для него одним пользовате­

ло пользователей, имеющих один и тот же

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

SQL

ID.
придерживается этого правила. В большинстве SQL-систем действия припи­

сываются определенному

ID,

который обычно соответствует определенному пользо­

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

USER может использоваться как аргумент
ID пользователя, дающего команду.

в команде. Он

обозначает авторизационный

Соглашения и терминология
Ключевые слова это слова, имеющие специальное значение в

SQL.

Они являются

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

(comma11ds) или сообщения (stateme11ts) - это инструкции, которые да­
SQL. Команды состоят из одной или более логически различных
называемых предложения.ми (фразами, c/auses). Предложения начинаются с

ются базе данных

частей,
ключевого слова, по которому они обычно и называются, и состоят из ключевых слов
и аргументов. Примерами предложений являются: "FROM Salespeople" и "WHERE

city = 'London"'. АргуА1енты заканчивают предложение или модифицируют его смысл.
В приведенных примерах "Salespeople" является аргументом, а FROM - ключевым
словом предложения FROM. Также "city = 'London'" является аргументом предложе­
ния WHERE. Объекть1 - это структуры в базе данных, которые имеют имена и хра­
нятся в памяти. Они включают базовые таб.1ицы, представления (то есть два вида
таблиц) и индексы.

Объяснение того, как формулируются команды, будет осуществляться в основном
на примерах. Однако существует более формальный метод описания команд с исполь­
зованием стандартных соглашений, который иногда применяется в следующих главах.
Упомянутые соглашения полезно знать в случае столкновения с ними в друтой доку­
ментации по

SQL.

Квадратные скобки

тить, круглые скобки

14

( ... )

([ ])

выделяют те части, которые можно опус­

показывают, что предшествующее им можно повторить

Итоги

любое число раз. Слова, заключенные в угловые скобки(),

-

специальные терми­

ны, которые объясняются по мере того, как вводятся.

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

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

SQL.

Вы сможете вывести сами опре­

деленную информацию из базы данных.

15

Работаем на
1.

SQL

Каковы основные различия между типами данных в

2.

Есть ли в

3.

Какой подраздел

4.

Что такое ключевое слово?

ANSI

тип данных

DA ТЕ?

SQL используется для

(Ответы даны в приложении А.)

16

SQL?

ввода значений в таблицы?

Использование

SQL

для выборки данных
из таблиц

Глава

3. Использование SQL

для выборки данных из таблиц

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

-

критерий, который можно применять для

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

С этой особенностью

SQL более

подробно мы ознакомимся в последующих главах.

Формирование запроса
SQL символизирует структурированный язык запросов (Structured Query
Language). Запросы являются наиболее часто используемым аспектом SQL. Есть кате­
гория пользователей SQL, которые используют язык только для формулировки запро­
сов. Поэтому изучение SQL начинается с обсуждения запроса и того, как он
выполняется в этом языке.

Что такое запрос? Это команда, которая формулируется для СУБД и требует пре­
доставить определенную указанную информацию. Эта информация обычно выводит­
ся непосредственно на экран дисплея компьютера или используемый терминал, хотя в
ряде случаев ее можно направить на принтер, сохранить в фай,1е или использовать в
качестве исходных данных для другой команды или процесса.

Как осуществляется связь за11росов?
Запросы являются частью

DML.

Но так как они совершенно не изменяют инфор­

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

DML,

воздействующие на

содержимое базы данных, а не просто показывающие его.

Все запросы в

SQL конструируются

на базе одной команды. Структура этой коман­

ды проста, потому что ее можно расширять для того, чтобы выполнить очень сложные
вычисления и обработку данных. Эта команда называется

Команда

SELECT.

SELECT

В простейшей форме команда

SELECT

дает инструкцию базе данных для поиска

информации в таблице. Например, можно получить таблицу

Salespeop\e,

введя с кла­

виатуры следующее:

SELECT snum, sname, city, comm
FROM Salespeople;
Выходные данные для этого запроса представлены на рис.

3 .1.

Команда просто выводит все данные из таблицы. Большинство программ, как по­
казано выше, также выводит заголовки столбцов. Некоторые программы допускают

18

Формирование запроса

".

· - --SOl Exccut1on l o q - - - - · · - - - - SllECT snum snamo. c1ty. comm
Salespeople

р--

I IROM

."..

1001
1002
1004
1007
101!3

Рис.

3.1.

Команда

,,,

,.,,",,

Peel
Serres
Motika
Rifkin
Axelrod

. -

-

!

э.1.q,,1

0.
0.
0.
0.
"'.

London
San Jose
London
Barcelona
New York

12
13
11
15
10

SELECT

тщательное форматирование выходных данных, но это лежит за пределами специфи­
каций стандарта. Далее приводится объяснение каждой части этой команды:

SELECT

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

слова, за которым следует пробел.

snum, sname ".

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

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

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

FROM
Salespeople

FROM, так

же как и

SELECT,

является ключевым словом, ко­

торое должно быть представлено в каждом запросе. За ним
следует пробел, а затем

-

имя таблицы, которая используется

как источник информации для запроса. В приведенном приме­

ре это таблица

Salespeople.

Символ "точка с запятой"(;) используется во всех интерактив­
ных командах

SQL для

сообщения базе данных, что команда

сформулирована и готова к выполнению. В некоторых системах

19

Глава

3. Использование SQL

для выборки данных из таблиц

этот символ заменен на символ "слэш обратный"

("\")

в строке,

которая непосредственно следует за концом команды.

Стоит заметить, что запрос по своей природе не обязательно упорядочивает выход­
ные данные каким-либо определенным образом. Одна и та же команда, выполненная
над одними и теми же данными в различные моменты времени, в результате выдает

данные, упорядоченные по-разному. Обычно строки выдаются в том порядке, в кото­
ром они представлены в таблице, но этот порядок может быть совершенно произволь­

ным. Необязательно, что данные в результате выполнения запроса будут
представлены в том порядке, в котором они вводятся или хранятся. Можно упорядо­
чить выходные данные непосредственно с помощью SQL-команд, указав специальное

предложение. Позже будет объяснено, как это сделать. Сейчас же просто констатиру­
ем факт отсутствия какого-либо порядка в представлении выходных данных.
Использование клавиши возврата каретки (клавиши Eпter) является произволь­
ным. Можно ввести запрос в одной строке следующим образом:

SELECT snum, sname, city, comm FROM Salespeople;
Поскольку в

SQL точка

с запятой применяется для того, чтобы пометить конец ко­

манды, большинство SQL-пporpaмм использует клавишу "Возврат каретки" (выпол­

няется нажатием клавиши

Return

или

Enter)

как пробел.

Выбор чего-либо простейшим способом
Если необходимо увидеть каждую колонку таблицы, существует упрощенный ва­
риант сделать это. Можно использовать символ "*" ("звездочка"), который заменяет
полный список столбцов.

SELECT •
FROM Salespeople;
Результат выполнения этой команды тот же, что и для рассмотренной ранее.

SELECT в общем

виде

Обобщая предыдущие рассуждения, следует отметить, что команда
чинается с ключевого слова

SELECT,

SELECT на­

за которым следует пробел. После него сле­

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

-

(*)

(звездочка). За звездочкой следует ключевое слово

FROM,

за

пробел и имя таблицы, к которой направляется запрос. Символ точка с запя­

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

20

Формирование запроса

Просмотр только определенных столбцов таблицы
Мощность команды SELECT заключается в ее свойстве извлекать из таблицы лишь
определенную информацию. Надо отметить возможность просмотра только указан­

ных столбцов таблицы. Для этого достаточно пропустить столбцы, которые нет необ­
ходимости просматривать, в части команды SELECT. Например, по запросу

SELECT sname, comm
FROM Salespeople;
получаются выходные данные, представленные на рис.

3.2.

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

Рис.

3.2.

Выбор определенных столбцов

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

(*)

извлечет столбцы в соответствии с их поряд­

ком, но если указать столбцы раздельно, они выстраиваются их в любом желаемом
порядке. В таблице
бец "дата заказа"
заказа"

(onum)

Orders

(odate),

зададим такой порядок столбцов: сначала разместим стол­

за ним

и "количество"

- столбец
(amt):

"номер продавца"

(snum),

затем

-

"номер

SELECT odate, snum, onum, amt
FROM Orders:

21

Глава

3. Использоваиие SQL

для выборки даниых из таблиц

Выходные данные, полученные по этому запросу, представлены на рис.

3.3.

Очевидно, что структура информации в таблицах является просто основой для ее
реструктуризации средствами

SQL.

Устранение избыточных данных
DISТINCT

Рис.

3.3.

-

аргумент, дающий возможность исключить дублирующиеся значе-

Переупорядоченные столбцы

ния из результата выполнения предложения

SELECT.

Предположим, необходимо уз­

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

Orders.

Не имеет

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

давцов

(snum).

Необходимо ввести:

SELECT snum
FROM Orders;
чтобы получить результат, представленный на рис. 3.4.
Для того чтобы получить список без повторений, который легче прочесть, нужно
ввести следующую команду:

SELECT DISTINCT snum
FROM Orders;
Выходные данные для этого запроса представлены на рис.

3.5.

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

DISTINCT

точные данные. Если таковых нет, не следует использовать D!SТINCT, поскольку он
может скрыть проблемы. Предположим, все имена покупателей различны. Если кто-то

22

Формирование запроса

Р11с.

3.4. SELECT с

повторениями

Рис.

3.5. SELECT без

повторений

введет второго покупателя с фамилией
нии

SELECT DISТINCT cname,

Clemens

в таблицу

Customers

при использова­

можно не заметить, что имеются дублирующиеся дан­

ные. Будут получены ошибочные сведения о
информации об избыточности данных.

Clemens,

поскольку в этом случае нет

23

Глава

3. Использование SQL

Параметры DISТINCT.
предложения

SELECT.

для выборки данных из таблиц

DISТINCT можно задать только один раз для данного

Если

SELECT

извлекает множество полей, то он исключает

строки, в которых все выбранные поля идентичны. Строки, в которых некоторые зна­
чения одинаковы, а другие

различны, включаются в результат. DISТINCT, факти­

-

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

6),

исключая воз­

можность их повторения.

DISТINCT в сравнении с

ALL.

Альтернативой

DISTINCT

является

ALL.

Это

ключевое слово имеет противоположное действие: повторяющиеся строки включа­

ются в состав выходных данных. Поскольку часто бывает так, что не заданы ни
DISТINCT, ни ALL, предполагается ALL; это ключевое слово имеет преимущество
перед функциональным аргументом.

Определение выборки

-

предложение

WHERE
Таблицы бывают достаточно большими с тенденцией к увеличению по мере добав­
ления строк. В данный момент времени интересны только некоторые строки таблицы.

SQL дает возможность задать

критерий определения строк, которые следует включить

в состав выходных данных. Предложение

WHERE команды SELECT позволяет опре­
делить предикат, условие, которое может быть либо истинным, либо ложным для ка­
ждой строки таблицы. Команда извлекает только те строки из таблицы, для которых
предикат имеет значение "истина". Предположим, необходимо узнать имена всех про­
давцов в Лондоне (London). В этом случае можно ввести следующую команду:

SELECT sname, city
FROM Salespeople
WHERE city

= 'London';

Лри наличии предложения

WHERE

программа обработки базы данных просматри­

вает таблицу строка за строкой и для каждой строки проверяет, истинен ли на ней пре­
дикат. Следовательно, для записи о продавце Рее/ программа просмотрит текущее
значение в столбце city (город), определит, что оно равно 'London', и включит эту стро­
ку в состав выходных данных. Запись о продавце

Serres

не включается и т.д. Выход­

ные данные для приведенноm выше запроса представлены на рис.

3.6.

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

WHERE,

был представлен в

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

24

О1tределение выборки

Рис.

3.6. SELECT с

предложением

-

предло:ж:ение

WHERE

WHERE

своего рода оценка кредита или оценка, основанная на значении предыдущих поку­

пок. Такие цифровые коды могут быть полезны в реляционных базах данных как спо­
соб обобщения сложной информации. Можно выбрать всех покупателей
рейтингом

(rating) 100

(Customers)

с

следующим образом:

SELECT *
FROM Customers
WHERE rating = 100;
Здесь не используются одиночные кавычки, поскольку поле
вым. Результат запроса представлен на рисунке
К предложению

WHERE

rating

является число­

3.7.

относятся все комментарии, сделанные в этой главе ра­

нее. Т.е. можно использовать номера столбцов, иск~1ючать повторяющиеся строки или
переставлять столбцы в командах

SELECT,

использующих

WHERE.

25

Глава

Рис.

3. Использование SQL

3. 7. SELECT с

для выборки данных из таблиц

числовым полем в предикате

Ип~оги
Мы выяснили, что существует несколько способов получения представленной в
таблице информации в том виде, который вас интересует. Например, можно перестав­
лять или исключать столбцы таблицы, а также сохранять или исключать повторяю­
щиеся строки.

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

управления строками, которые должны войти в результат запроса. Именно это свойство
предикатов и делает запросы

SQL

столь мощными. В следующих нескольких главах мы

рассмотрим характерные черты и возможности предикатов. Глава

4

посвящена операто­

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

та, и способам комбинирования множества условий в единственный предикат.

26

Работаем на
l.

Запишите команду
количество

2.

SELECT, которая выводит порядковый номер (ordernumber),
(amount) и дату (date) для всех строк таблицы Order.

Запишите запрос, который выдает все строки таблицы
имеет номер

3.

SQL

Customers,

где продавец

l 001.

Запишите запрос, который выдает строки таблицы

salesperson

в таком порядке:

city, sname, snum, comm.
4.

Запишите команду SELECT, которая выдает rating и следом за ним name каждого
покупателя (customer), проживающего в San Jose.

5.

Запишите запрос, позволяющий получить значения столбца

давцов (salespeople ), номера
лице

Orders,

snum для всех про­
(orders) которых находятся в настоящее время в таб­

причем повторения требуется исключить.

(Ответы представлены в прило:жении А.)

27

Использование
реляционных

и булевых операторов

для создания более
слоJ1Сных предикатов

Глава

4. Использование реляционных и

булевых операторов

Из главы 3 выяснилось, что предикаты могут приписывать предложениям с ра­
венством значения "истина" или "ложь", а также оценивать операторы сравнения от­
личные от равенства. В этой главе рассмотрены и другие операторы сравнения,
применяемые в

SQL,

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

менения и комбинирования значений предиката. В булевом выражении единственный
предикат может содержать любое количество условий, что позволяет получить очень

мощные предикаты. Здесь также объясняется применение круглых скобок для струк­
турирования сложных предикатов.

Реляционные операторы
Реляционный оператор

-

это математический символ, который задает определен­

ный тип сравнения между двумя значениями. Уже известно как применяются равенст­

ва, такие как 2 + 3 = 5 или city = 'London'. Однако существуют и другие операторы
сравнения. Предположим, необходимо вычислить продавцов (Salespeople), комисси­
онные (commissioпs) которых превышают заданное значение. В этом случае следует
воспользоваться сравнением типа "больше или равно".

SQL

распознает следующие

операторы сравнения:

Равно

>

Больше, чем

<

Меньше, чем

>=

Больше и.1и равно

= 200

Рис.

4.1.

Использование "больше, чем"

(>}

31

Глава

4. Использование реляционных и

булевых операторов

Булевы операторы
SQL распознает основные

булевы операторы. Булевы выражения

-

это те выраже­

ния, относительно которых, подобно предикатам, можно сказать, истинны они или

ложны. Булевы операторы связывают одно или несколько значений "истина/ложь" и в
результате получают единственное значение "истина/ложь". Стандартные булевы опе­
раторы, распознаваемые SQL, это AND, OR, NОТ. Существуют и другие, более
сложные булевы операторы (как, например, "исключающее ИЛИ"), но их можно по­
строить с помощью трех простых. Булева логика "истина/ложь" представляет собой
полный базис для работы цифрового компьютера. Поэтому фактически весь

SQL (или

какой-либо другой язык программирования) можно свести к булевой логике. Далее пе­
речислены булевы операторы и основные принципы их действия:

• AND

берет два булевых выражения (в виде А

AND

В) в качестве аргументов и

дает в результате истину, если они оба истинны.

• OR два

булевых выражения (в виде А

OR

В) в качестве аргументов и оценивает

результат как истину, если хотя бы один из них истинен.

• NOT

берет единственное булево выражение (в виде

NOT

А) в качестве аргу­

мента и изменяет его значение с истинного на ложное или с ложного на истин­
ное.

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

(customers)

из

San Jose,

чей рейтинг

(rating)

превышает

200:

SELECT •
FROM Customers
WHERE city

= 'San

Jose'

AND rating > 200;
Выходные данные для этого запроса представлены на рис.

4.2.

Существует только

один покупатель, удовлетворяющий этому условию.

При испоj1ьзовании

OR ,

будут получены сведения обо всех тех покупателях

(custoшers}, которые либо проживают в
шающий 200.

San Jose,

либо имеют рейтинг

SELECT •
FROM Customers
WHERE city = ·san Jose·
OR rating > 200;
Результат выполнения этого запроса представлен на рис.

32

4.3.

(rating},

превы­

Булевы операторы

Рис.

4.1. SELECT с

использованием

AND

Рис.

4.3. SELECT с

использованием

OR

NOT

дает возможность получить отрицание (противоположное значение) булева

выражения. Вот пример запроса с использованием

NOT:

SELECT *
FROM Customers
WHERE city

= ·san

Jose·

OR NOT rating > 200;

33

Глава

Рис.

4. Использование реляц1101111ых и

4.4. SELECT с

использованием

булевых операторов

NOT

Результат выполнения этого запроса представлен на рис.

4.4.

Все записи, за исключением

не находится в

его рейтинг превышает

200,

Grass,

были выбраны.

Grass

San Jose

и

таким образом он не удовлетворяет обоим условиям. Каж­

дая из других строк удовлетворяет либо первому, либо второму условию (либо каждому
из них). Заметим, что оператор NOT должен предшествовать булеву выражению, значе­
ние которого он должен изменить, но не может располагаться непосредственно перед

оператором сравнения, как это можно сделать во фразе на английском языке. Таким об­
разом некорректно вводить

rating NOT > 200
в качестве предиката, несмотря на то, что эту фразу можно легко сформулировать по­
анrлийски. Отсюда следует ряд проблем. Например, как

SQL оценит

следующее?

SELECT *
FROM Customers
WHERE NOT city = ·san Jose·
OR rating > 200;
Применяется ли

NOT

к выражению

city = 'San Jose' или к двум выражениям: тому,
rating > 200? В соответствии с приведенной записью пра­
вариант. SQL применяет NOT только к тому булеву выраже­

что указано, и выражению
вильным является первый

нию, которое непосредственно следует за ним. Можно получить другой результат по
следующей команде:

SELECT *
FROM Customers
WHERE NOT (city

34

·san Jose'

Булевы 011ераторы

OR rating > 200);
SQL понимает

круглые скобки следующим образом: все то, что расположено внут­

ри крутлых скобок, вычисляется прежде всего и рассматривается как единственное
выражение по отношению к тому, что расположено за пределами крутлых скобок (это

SQL из­
city = 'San Jose'

соответствует стандартной интерпретации в математике). Другими словами,

влекает каждую строку и определяет, выполняется ли для нее условие
или

rating > 200.

Если одно из этих выражений истинно, то булево выражение, распо­

ложенное в круглых скобках, тоже истинно. Однако, если булево выражение в круглых

скобках истинно, пре;:щкат в целом ложен, поскольку

NOT

превращает истину в ложь

и наоборот. Результат выполнения этого запроса представлен на рис.

4.5.

Вот преднамеренно усложненный пример. Проследим его логику (результат вы­
полнения запроса представлен на рис.

Рис.

4.5. SELECT с

использованием

NOT

4.6):

и круглых скобок

SELECT •
FROM Orders
WHERE NOT((odate

= 10/03/1990

AND snum > 1002)

OR amt > 2000.00);
Комбинации булевых операторов в сложных выражениях не столь просты, как каж­
дый из в отдельности. Способ оценки сложного булева выражения следующий: оце­
нить булево(ы) выражение(ия), имеющее(ие) наибольшую глубину вхождения в

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

круглые скобки.

35

Глава

4. Использование реляционных и

булевых операторов

Дадим детальное объяснение оценки рассмотренного выше примера. Наибольшую
глубину вхождения в булево выражение имеет предикат:

1002,

со связкой

AND,

odate = 10/03/1990 and snum >

образующий булево выражение, которое оценивается как ис­

тинное для всех тех строк, которые удовлетворяют каждому из этих условий. Это со­
ставное булево выражение (которое мы назовем булево выражение номер
краткости,

Bl)

соединено с

amt > 2000.00

(выражение В2) с помощью

OR

1

или, для

и образует

третье выражение (В3), которое является истинным для данной строки в том случае,
если либо

Bl

либо В2 истинны для этой строки. В3 полностью содержится в круглых

скобках, которым предшествует

NOT,

и образует заключительное булево выражение

(В4), которое является условием предиката. Следовательно, В4

-

предикат запроса

истинен, если В3 ложен и наоборот. ВЗ ложен, если ложен каждый из

Bl

и В2.

Bl

-

ло­

жен для строк, в которых либо

order date не совпадает с заданным значением
snum не превышает 1002. В2 ложен для всех строк, в кото­
рых значение поля amount не превосходит 2000.00. Любая строка с суммой, превы­
шающей 2000.00, делает В2 истинным, отсюда В3 тоже истинно, а 84 ложно.
10/03/1990,

либо значение

Следовательно, все такие строки исключаются из числа выходных данных. Остаю­

щиеся строки от
является строка с

3 октября 1990 года с snum, превышающим 1002 (такой, например,
onum 3001 за октябрь, 3, 1990 с snum 1007), делают В! истинным,

следовательно, и В3 истинно, а значит предикат ложен. Эти записи также исключают­

ся из рассмотрения. Оставшиеся строки входят в состав выходных данных (см. рис.

4.6).

Рис.

4.6.

36

Сложный запрос

Итоги

Итоги
В этой главе более полно представлены сведения из области предикатов. Показано,

как можно найти значения, которые связаны с данным значением любым количеством
способов, заданных с помощью различных реляционных операторов, как применяют­
ся булевы операторы AND и OR для комбинации сложных условий, каждое из кото­
рых может рассматриваться как единственный предикат. Булев оператор

NOT

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

на составные части, каждая из которых является простой.
В главе

5

будут представлены особые операторы языка

SQL.

37

Работаем на

SQL

1.

Запишите запрос, который покажет все заявки, превышающие

2.

Запишите запрос, который покажет имена (names) и названия городов
всех продавцов в

3.

London

с комиссионными

Запишите запрос для таблицы

(commission),

Customers, включающий в выходные данные всех
100, в том случае, если они расположены не в

Rome.
Каков будет результат выполнения следующего запроса?

SELECT *
FAOM Orders
WHEAE (amt < 1000
NOT (odate

ОА

= 10/03/1990

AND cnum > 2003));
5.

Каков будет результат выполнения следующего запроса?

SELECT *
FAOM Orders
WHEAE NOT((odate = 10/03/1990
AND amt >
6.

ОА

= 1500);

Как упростить запись следующего запроса?

SELECT snum,sname,city,comm
FAOM Salespeople
WHERE (comm > +.12 OR
comm < .14);
(Ответы см. в 11риложении А.)

38

(cities) для
.10.

превышающими

покупателей, для которых rating 1006)

Использование
специальных
операторов

в "условиях,,

Глава

5. Ис11ользова11ие специальных 011ераторов в

"условиях"

Кроме булевых операторов и операторов сравнения, рассмотренных в главе

4,

использует специальные операторы IN, BETWEEN, LIKE и IS NULL. Вы научи­
тесь применять их, подобно операторам сравнения, для получения более выразитель­

SQL

ных и мощных предикатов. Обсуждение

IS NULL

касается значений пропускаемых

данных и NULL-значений, фиксирующих отсутствие данных.

OnepamoplN
IN

полностью определяет множество, которому данное значение может принадле­

жать или не принадлежать. Если нужно найти всех продавцов, расположенных либо в
либо в

'Barcelona',

'London',

основываясь только на том, что известно к настоящему

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

5.1 ):

SELECT •
FROM Salespeople
WHERE city =
OR ci ty

·вагсеlоnа·

· London · ;

Однако существует более простой способ получить ту же самую информацию:

SELECT •
FROM Salespeople
WHERE city IN ('Barcelona·, 'London');

11

Sl-ll ~----------SUL lxeCL1tJon Log- ~-~~

___

1f НОМ S,11 ""Р"ОР] '-'
'IW11lH[ c1ty - ·uarcelona'
1 011
с 1t у
'l oпdon' .
1

.""".

Рис.

5.1.

40

Поиск продавцов

1

•••

jjFIШ

1001 Peel
101114 Motika
1007 Rifkin

(Salespeople) в

l-:

э.1"1,,1

London
London
Barcelona

городах

Barselona

0. 12
0. 11
0. 15

или

London

Оператор

- - ---------oOL fxcc11t1or1 Lоц 0 ~
1, ::,1L1 С f *
1 f/ОГ~ ::, J lf,spr0 op] е
WHll!l c1ty IN ( lJar·celoпd',
Lоnсюп')

___

BETWEEN

1,
1

1'

м1111"9

0. 12
0.11
0. 15

1001 Peel
1004 Motika
1007 Rifkin
••~~~-вrowse : ti~+

Рис.

5.2. SELECT с

использованием

IN

Выходные данные этого запроса представлены на рис.

Как видно из примера,

IN

1
э.1 11 ;,м

51ыш

5.2.

определяет множество, элементы которого точно пере­

числяются в круглых скобках и разделяются запятыми. Если в поле, имя которого ука­

зано слева от IN, есть одно из перечисленных в списке значений (требуется точное
совпадение), то предикат считается истинным. Если элементы множества имеют чи­
словой, а не символьный тип, то одиночные кавычки непосредственно слева и справа

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

1001, 1007, 1004.
5.3:

Выходные данные для следующего запроса представле­

SELECT •
FROM

Customers

WHERE snum IN (1001, 1007, 1004);

Оператор
Оператор

BETWEEN

BETWEEN сходен с IN.
IN, BETWEEN задает

Вместо перечисления элементов множества, как

это делается в

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

IN, BETWEEN

AND

и конечное значение. Также как и

чувствителен к порядку: первое значение в предложении должно быть

первым в соответствии с алфавитным или числовым порядком. (В отличие от англий­
ского языка в SQL не говорят: значение расположено между ("is BETWEEN") значени-

41

Глава

5. Использование специальных операторов в

rrsu-EC ;---•

~~-~~-SQL

'FROM Customers
WfHRfsrшmIN(HHJ1

l:.xecutron Log~-~~--~ __

HHJI

Рис.

5.3. SELECT с

Hoffman
Clemens
Cisneros
Pereira

использованием

rs;-L~CT

llFROM

1004)

-··

MЭll!l,,M ми;;;;,1

2001
2006
2008
2007

London
London
San Jose
Rome

IN

1001
1001
1007
1004

11

10 AND

12.

е1р1ш

использованием

BETWEEN

и значение11, но просто значение л1ежду

влечь из таблицы
имеют величину в

,
э.1 11 1.11

0. 12
0. 11
0.10

("BETWEEN") значением и значение~~.
LIKE.) Следующий запрос позволит из­
Sa\espeople всех продавцов (salespeople), комиссионные которых
диапазоне .10 и .12 (выходные данные представлены на рис. 5.4):

Это замечание справедливо и для оператора

SELECT •

FROM Salespeople

42

MiifЩM

с числовыми значениями

1001
1004
1003

ем

100
100
300
100

1

1

Salespeople

MilJIШM

5.4. SELECT с

,,,,.."_

i

* ~--------SOL Exccutron 109°~-~~- ~ ~ ~ ~ 1 ]

WH[RE comm BElWElN

Рис.

"условиях"

Оператор

WHERE comm

BEТWEEN

BETWEEN

.10 AND .12;

Оператор BETWEEN является включающим, т.е. граничные значения (в данном
примере это .1 О и .12) делают предикат истинным. SQL непосредственно не подцер­
живает исключающий

Необходимо сформулировать граничные значения

BETWEEN.

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

SELECT *
FROM Salespeople
WHERE (comm BEТWEEN . 10, AND . 12)
AND NOT comm IN ( .10, .12);
Выходные данные для этого запроса представлены на рис.

5.5.

Пусть эта запись и неуклюжа, но она показывает, как новые операторы можно ком­

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

IN

и

BETWEEN

используются, как и операторы сравнения, для сопоставления

значений, одно из которых является множеством (для

IN)

или диапазоном (для

BETWEEN).
Аналогично всем операторам сравнения,
лях, представленных в двоичном

(ASCII)

BETWEEN

действует на символьных по­

эквиваленте, т.е. для выборки можно вос­

пользоваться алфавитным порядком. Следующий запрос выбирает всех покупателей
имена которых попадают в заданный алфавитный диапазон:

SELECT •
FROM Customers
WHERE cname BEТWEEN

·д·

AND 'G';

Выходные данные для этого запроса представлены на рис.

, ---1

1,

~-

Sf ll С f •
1 liO"l 0,,1!

-~SOl

lxecLJt1on

5.6.

log~--~-

-

,
'

•~ре "Р

1 ,,

Wlll
(SELECT AVG (amt)
FROM Orders inner
WHERE inner.cnum = outer.cnum);
В маленькой таблице, рассматриваемой в качестве примера, где большинство поку­
пателей имеют только один заказ, большинство значений совпадает со средним и, сле­
довательно, не извлекается. Можно ввести команду по-другому (выходные данные
представлены на рис.

11.5):

SELECT *
FROM Orders outer
WHERE amt >=
(SELECT AVG (amt)
FROM Orders inner

112

Как форАtuровать связанные lloдзallpocы

WHERE inner.cnum

= outer.cnum);

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

Рис.

11.4.

Связывание таблицы с ее копией

м.1.ща;

3003
3002
3005
3006
3009
3010
3011

Рис.

11.5.

767.19
1900. 10
5160.45
1098. 16
1713.23
1309.95
9891.88

10/03/1990
10/03/1990
10/03/1990
10/03/1990
10/04/1990
10/06/1990
10/06/1990

Выбор заказов, величина которых превышает среднее значение для их покупателей или

совпадает с ним

113

Глава

11.

Связанные подзапросы

Связанные подзапросы в НА VING
В предложении

HAVING

могут использоваться и связанные подзапросы. В этом

случае необходимо ограничить внешние ссылки теми элементами, которые могут не­

посредственно применяться в самом предложении HAVING. Как стало известно из
главы 6, предложение HAVING может использовать только функции агрегирования из
предложения SELECT или поля из предложения GROUP ВУ. Это и есть единственные
внешние ссылки, которые можно делать, потому что предикат предложения HAVING
оценивается для каждой группы из внешнего запроса, а не для каждой строки. Следо­
вательно, подзапрос будет выполняться один раз для каждой группы выходных дан­
ных внешнего запроса, а не для каждой отдельной строки.
Предположим, необходимо суммировать значения поля

Orders,

amounts (amt)

таблицы

сгруппировав их по датам и исключив те дни, когда сумма не превышает мак­

симальное значение, по крайней мере на

2000.00:

SELECT odate, SUM (amt)
FROM Orders
GROUP

ВУ

а

odate

HAVING SUM (amt) >
(SELECT 2000.00 +
FROM Orders

МАХ

(amt)

Ь

WHERE a.odate

= b.odate);

Подзаnрос вычисляет максимальное (МАХ) значение для всех строк с одной и той

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

предложения
и HAVING.

WHERE.

В самом подзапросе не должно быть предложений

GROUP

ВУ

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

выполнимы и с помощью

другого.

Различие в их применении заключается в ранее упомянутой необходимости ис­
пользовать иногда DISТINCT в команде соединения

Uoin),

тогда как этого не требует­

ся в подзапросах. Есть также ряд вещей, которые можно сделать только с помощью

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

114

Итоги

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

Итоги
В главе было рассмотрено одно из сложных понятий

SQL -

связанные подзапро­

сы. Мы выяснили, как они соотносятся с операцией соединения, как их можно исполь­
зовать с функциями агрегирования и с предложением

HAVING.

Вы ознакомились со

всеми типами подзапросов.

Следующий шаг
и оператор

IN,

-

введение некоторых специальных операторов, использующих, как

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

ко с подзапросами. Первый из них,

EXISTS,

рассмотрен в главе

IN
12.

применяемых толь­

115

Работаем на

1.

SQL

Запишите команду

SELECT, использующую связанные подзапросы и выбираю­

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

2.

Запишите два запроса, которые выбирают (по имени и номеру) всех продавцов,
проживающих в городах, где у них нет покупателей. Один запрос должен ис­

пользовать операцию соединения

(join),

а второй

-

связанные подзапросы. Ка­

кое из решений является более элегантным?
(Подсказка: один из возможных вариантов решения этой задачи

-

найти всех

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

(Ответы см. в 1tриложении А.)

116

Использование
оператора

EXISTS

Глава

12. Использование оператора EXJSTS

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

EXISTS.

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

EXISTS

в обычных и связанных подзапросах. Будут рассмотрены специальные случаи

его употребления для агрегатов, NULL-значений и булевых значений. Вы сможете
усовершенствовать навыки работы с подзапросами, рассматривая более сложные спо­
собы их применения.

Как работает оператор
EXISTS -

EXISTS?

оператор, генерирующий значение "истина" или "ложь", другими сло­

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

OR

и

NOT.

AND,

Используя подзапрос в качестве аргумента, этот оператор оценивает его

как истинный, если он генерирует выходные данные, а в противном случае как лож­

ный. В отличие от прочих операторов и предикатов, он не может принимать значение

unknown.

Например, нужно извлечь данные из таблицы

один (или более) покупатель из нее находится в
са представлены на рис.

12. l ):

SELECT cnum, cname, city
FROM Customers
WHEREEXISTS

Giovanni
Liu
Grass
Clemens
C1sneros
Pereira

Рис.

12.1.

118

Использование оператора

London
San Jose
Rome

EXISTS

Customers в том случае, если
San Jose (выходные данные для запро­

Использование

EXJSTS со

связанными подза11росами

(SELECT *
FROM Customers
WHERE city = ·san Jose');
Внутренний запрос выбрал все данные обо всех покупателях из

EXISTS

San Jose.

Оператор

внешнего предиката отметил, что подзапрос генерирует выходные данные, и

поскольку выражение

EXISTS

является единственным в этом предикате, он принима­

ет значение "истинно". Здесь подзапрос (не являющийся связанным) выполняется
только один раз для всего внешнего запроса и, следовательно,

значение для всех случаев. Поскольку

EXISTS

имеет единственное

в данном примере делает предикат ис­

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

специфической информации не стоит.

Выбор столбцов с помощью
В приведенном примере

EXISTS

EXISTS

выбирает один столбец, в отличие от с звездочки,

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

EXISTS,

поскольку он вообще не применяет полученных значений, а лишь фикси­

рует наличие выходных данных подзапроса.

Использование

EXISTS со

связанными

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

EXIST

ин­

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

SELECT DISTINCT snum
FROM Customers outer
WHERE EXISTS
(SELECT *
FROM Customers inner
WHERE inner.snum = outer.snum
AND inner.cnum outer.cnum);

119

Глава

Рис.

12. Использование оператора EXISTS

11.2.

Использование оператора

EXISTS

со связанными подзапросами

Для каждой строки-кандидата внешнего запроса (представляющей рассматривае­
мого в настоящий момент покупателя), внутренний запрос находит строки, имеющие

соответствующее значение

snum (имеет того

же продавца), но не значение

cnum (соот­

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

(snum)

EXISTS

истинен для

из таблицы внешнего запроса включа­

ется в состав выходных данных. Если бы не был задан DISТINCT, каждый из таких

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

Комбинирование

EXISTS и

соединений

Иногда кроме номера требуется получить о каждом продавце больше информации.
Это можно сделать соединением таблиц
представлены на рис.

Customers

12.3):

SELECT DISTINCT first.snum, sname, first.city
FROM Salespeople first, Customers second
WHERE EXISTS
(SELECT•
FROM Customers third
WHERE second.snum

120

third.snum

и

Salespeople

(выходные данные

Использование

EXJSTS со связанными подзапросами

AND second.cnum third.cnum)
AND first.snum = second.snum;
Внутренний запрос тот же, что и в предыдущем примере, изменены только алиасы.

Внешний запрос является соединением таблиц

Salespeople и Customers.

Новое предло­

жение основного предиката (AND first.snum = second.snum) оценивается на том же
уровне, что и предложение EXISTS. Это функциональный предикат самого соедине­
ния, сравнивающий две таблицы из внешнего запроса в терминах общего для них поля
snum. Поскольку используется булев оператор AND, оба условия, сформулированные
в предикатах основного запроса, должны быть истинными для истинности этого пре­
диката. Следовательно, результаты подзапроса действуют в случаях, когда вторая

часть запроса истинна и соединение выполняется. Комбинирование соединений и
подзапросов указанным способом является весьма эффективным методом обработки
данных.

Рис.

12.3.

Комбинирование

EXISTS с JOIN

Использование

(соединением)

NOT EXISTS

Из предыдущего примера ясно, что
операторами. С

EXISTS легче

EXISTS
-

всего применять

можно комбинировать с булевыми
и чаще всего применяется

- опера­
NOT. Один из способов поиска всех продавцов, имеющих только одного покупате­
ля, - это поставить NOT перед EXISTS в предыдущем примере (см. рисунок 12.2)
(выходные данные для запроса представлены на рис. 12.4):
тор

SELECT DISTINCT snum
FROM Customers outer

121

Глава

12. Исllользование 01repamopa EXISTS

WHERE NOT EXISTS
(SELECT •
FROM Customers inner
WHERE inner.snum = outer.snum
AND inner.cnum outer.cnum);

Рис.

12.4.

Использование

EXISTS и
EXISTS

EXISTS

с

NOT

агрегаты

не может использовать агрегатные функции в своем подзапросе. Это есте­

ственно. Если функция агрегирования находит строки для работы с ними, то

EXISTS

принимает значение "истина", и ему безразлично реальное значение функции; если
функция не находит никаких строк, то значение

зовать функции агрегирования с

EXISTS

EXISTS -

"ложь". Попытка исполь­

подобным образом свидете.1ьствует о том,

что проблема не была правильно понята.
Подзапрос для предиката

EXISTS

тоже может иметь в своем составе один или не­

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

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

В любом случае можно получить тот же результат проще

-

выбрать поле, которое

используется в агрегатной функции, вместо применения самой функции. Другими
словами, предикат

EXISTS (SELECT COUNT (DISТINCT sname) FROM sa\espeop\e)
EXISTS (SELECT sname FROM Sa\espeop\e), причем первый

эквивалентен предикату
из них тоже допустим.

122

Ис11олыование

EXJSTS со

связаиными подзапросами

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

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

SQL.

Нужную информацию можно полу­

чить путем связывания всех трех рассматриваемых нами в примерах таблиц:

SELECT •
FROM Salespeople first
WHERE EXISTS
(SELECT •
FROM Customers second
WHERE first.snum

= second.snum

AND 1 <
(SELECT COUNT(•)
FROM Orders
WHERE Orders.cnum = second.cnum));
Выходные данные представлены на рис.

12.5.

SПdПН~

Р

Рис.

12.5.

Использование

EXISTS

London
San Jose
Barcelona
Dn Р Up ~•

cumm
12
". 13
". 15

1.

14~

Home

в сложном подзапросе

123

Глава

12. Использование оператора EXISTS

Можно рассмотреть оценку данного запроса следующим образом. Взять каждую
строку таблицы Salesperson в качестве строки-кандидата (внешний запрос) и выпол­
нить подзапросы. Для каждой строки-кандидата из внешнего запроса взять каждую
строку из таблицы Customers (средний запрос). Если текущая строка покупателя
(customer) не соответствует текущей строке продавца (т.е. если first.snum
second.snum), то предикат среднего запроса ложен. Как только в среднем запросе най­
дется покупатель, который соответствует продавцу во внешнем запросе, нужно перей­

ти к самому внутреннему запросу, чтобы определить, истинен ли предикат среднего
запроса. Самый внутренний запрос выполняет подсчет заказав (orders) для текущего
покупателя (из среднего запроса). Если это число превышает

1, то

предикат среднего

запроса принимает значение "истина", и строка выбирается. Это делает предикат

EXISTS

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

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

SQL,

покажутся элементарными.

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

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

(view)).

Итоги
Несмотря на свою кажущуюся простоту,
но весьма гибким и мощным операторам

EXISTS относится к наиболее сложным,
SQL. В этой главе вы познакомились с мно­

гочисленными возможностями этого оператора и существенно расширили свои зна­

ния в области логики сложных подзапросов.
Следующий шаг

-

рассмотрение трех других специальных операторов, исполь­

зующих подзапросы в качестве аргументов: ANY, ALL, SOME. Из главы 13 вы узнае­
те, что они могут служить альтернативой уже известным операторам, а во многих
случаях даже более полезны.

124

Работаем на

1.

SQL

Запишите запрос с

EXISTS

для того, чтобы извлечь всех продавцов, имеющих

покупателей с рейтингом, превышающим

300.

2.

Как решить эту же проблему, применяя соединение?

3.

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

4.

Запишите запрос, извлекающий из таблицы

Customers покупателя, назначенного

каждому продавцу, который уже имеет по крайней мере одного покупателя (по­

купатель, который выбирается, не учитывается) с заявками в таблице

Orders

(Подсказка: по структуре запрос сходен с трехуровневым подзапросом, рассмот­

ренным в примере).

(Ответы см. в приложении А)

125

Использование

ANY,
ALLuSOME

операторов

Глава

13. Использование операторов ANY, ALL и SOME

В данной главе вы познакомитесь еще с тремя специальными операторами, ори­
ентированными на подзапросы. (Реально их два, поскольку

ANY

и

SOME

совпадают

по назначению и использованию.) Этими операторами исчерпываются возможные
типы предикатов

SQL,

используемых в подзапросах. Мы рассмотрим множество спо­

собов формулирования одного и того же запроса, применяя различные типы предика­
тов в подзапросах; вы узнаете преимущества и недостатки каждого подхода.

ANY, ALL и SOME так же, как и EXISTS, используют в качестве аргументов подза­
EXISTS они отличаются тем, что применяются в конъюнкции с опе­
раторами отношения. В этом плане они сходны с оператором IN, т.е. берут все
просы; однако, от

значения, полученные в подзапросе и рассматривают их как единое целое. Однако, в
отличие от

IN,

их можно применять только с подзапросами.

Специмьный оператор
Начнем с операторов

ANY

или

SOME.

ANY или SOME

Независимо от применения, они выполня­

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

них городах (выходные данные для этого запроса представлены на рис.

Рис.

13.1.

128

Использование оператора

ANY

13.1):

Специш~ьный

Ollepamop ANY или SОЛ1Е

SELECT *
FROM Salespeople
WHERE city = ANY
(SELECT city
FROM Customers);
Оператор

ANY

берет все значения поля

в таблице

sity

Customers, полученные в
(ANY) значение совпа­

подзапросе, и оценивает результат как истину, если какое-либо

дает со значением поля city из текущей строки внешнего запроса. Это означает, что
подзапрос должен выбирать значения того же типа, которые сравнились в основном
предикате. В этом отношении

ANY отличается

от

EXISTS,

который просто определяет

реально не используемые результаты.

Использование

IN или EXISTS вместо ANY

Чтобы сформулировать предыдущий запрос, можно воспользоваться операто­
ром

IN:

SELECT *
FROM Salespeople
WHERE city IN
(SELECT city
FROM Customers);
Запрос генерирует выходные данные, представленные на рис.

--_

----~~~so1

,f SI 1 1 ( l •
'f HOГ'IJ ::-..1 l с-__,рсор

fxecLJt1on

Log--

-

13.2.

-~
1

1

1 ('

'Wlll !tumr1 ·,)

.""".

11111111 Peel
11111112 Serres
11111114 Motika

1

,
'

,

."..

london
San Jose
London




1'""'

. 12
111.13
111. 11



11
1

:

t __ --~ ~~~~ _-~ __ _ -~~-~-- __ _

1

Рис.

13.2.

Использование

IN

как альтернативы

i

1

ANY

129

Глава

13. Использование операторов ANY, ALL

Оператор

ANY

и

SOME

может использовать другие операторы отношения кроме равенства

и, следовательно, выполняет сравнения, отличные от сравнений в

IN.

Например, мож­

но найти всех продавцов, имеющих покупателей, имена которых следуют в алфавит­
ном порядке за именем продавца (выходные данные представлены на рис.

13.3):

SELECT *
FROM Salespeople
WHERE sname < ANY
(SELECT cname
FROM Custome rs);
Все строки, которые были выбраны, сохраняются для

Serres

и

Rifkin,

поскольку

они не имеют покупателей, имена которых следуют за их именами в алфавитном по­
рядке. Это эквивалентно следующему запросу с

рого представлены на рис.

EXISTS,

выходные данные для кото­

13.4:

SELECT *
FROM Salespeople outer
WHERE EXISTS
(SELECT *
FROM Customers inner
WHERE outer.sname < inner.cname);
Любой запрос, сформулированный с

EXISTS,

ANY

(или с

ALL),

можно сформулировать и с

хотя обратное утверждение неверно. Строго говоря, версии с

EXISTS

не со­

всем идентичны версиям с ANY или ALL. Различие заключается в обработке NULLзначений (эта проблема будет рассмотрена позже в этой главе). Можно обойтись без

____

_

Sl L f ( 1 •
• ROM S,1 I

1lw11LHt

_ _.__

~о~

Excct1t

1ог1

Lоч---

~~-

-

---

·~r11111L>

,рсор

1 t-'

1

< ANY

1

' ( Ч l l ( 1 r 11,;me
11 f= О theп
{ПО NULLS produced}
ЕХЕС SQL UPDATE Salespeople
SET comm = comm + .01
WHERE CURRENT OF High_cust;
Else
{опе ОГ both NULL}
begiп

if i_a <

О theп

writelп ('salespersoп

if i_b <

· ,id_пum, · has

по

city');

О theп

293

Глава

25.

Использование

SQL с другими

языками программирования

wri teln ( · salesperson ·, id_num, · has

по

commissions ·);

end;
{else}
end; {while}
SQL CLOSE CURSOR High_cust;

ЕХЕС

Из примера ясно, что в одном случае включено ключевое слово

INDICATOR,

во

втором случае оно не использовалось с целью иллюстрации этих возможностей; по

действию индикаторов переменных эти два варианта ничем не отличаются. Извлека­
ется каждая строка, но команда UPDATE выполняется в том случае, если не обнаруже­

но NULL-значение. Если получено NULL-значение, то выполняется

else -

часть

программы, которая печатает предупреждающее сообщение, определяющее, где кон­
кретно было обнаружено NULL-значение. Замечание: индикаторы должны проверять­
ся во включающем языке, как в рассмотренном примере, а не в предложении
команды

SQL, что

WHERE

в общем-то законно, но может привести к непредсказуемым резуль­

татам.

Использование индикатора переменных для эмуляции

NULL-значений
Можно трактовать индикаторы переменных, связанные с каждой переменной

включающего языка как способ эмуляции NULL-значений SQL. Поскольку одно из
этих значений используется в программе, например, в предложении if ". then, можно
контролировать соответствующий индикатор переменной, чтобы увидеть, принимает
ли она значение

NULL. В этом случае возникает возможность различной трактовки
переменных. Например, если NULL-значение было найдено в поле city для значения
переменной включающего языка city, которая связана с индикатором _переменной i_

city,

можно установить значение переменной

city

равным последовательности пробе­

лов, что необходимо, когда предполагается печатать это значение; оно не имеет значе­
ния для логики конкретной программы. Конечно,

i_city

автоматически принимает

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

if ". then:

if city = 'London' then
comm := comm + .01
else comm := comm - .01;
Любое значение, введенное в переменную

'London', либо

личиваются, либо уменьшаются. Но в
друrому:

ЕХЕС

SOL UPDATE Salespeople
comm = comm + .01
WHERE ci ty = 'London';
SЕТ

294

city,

будет либо равно значению

не равно ему. Следовательно, комиссионные в любом случае либо уве­

SQL

эквивалентная команда работает по­

Индикаторы переменных

и

ЕХЕС

SQL UPDATE Salespeople
SЕТ comm = comm - .01;
WHERE city 'London';

(Версия

Pascal

работает только с единственным значением, тогда как версия SQL
city в версии SQL было равно NULL, то

действует на целой таблице.) Если значение
оба предиката принимают значение

comm не изменяется

unknown

(неизвестно) и, следовательно, значение

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

используя индикатор переменной и задав условие, исключающее NULL-значения:

if i_city >= О then
begin
if city = 'London· then
comm := comm + .01
else comm := comm - .01;
end;
{ begin и end необходимы

в данном случае для большей наглядности

}

В более сложной программе можно присвоить булевым переменным значение "ис­
тина", чтобы определить ситуацию, когда city имеет значение NULL. Затем можно
просто проверить это значение переменной.

Другие пользователи индикатора переменных
Индикатор переменной можно использовать для назначения NULL-значений. Доба­
вить их к именам переменных включающего языка в команде UPDATE или INSERT, как
в команде

SELECT.

Если индикатор переменной имеет отрицательное значение, то в

поле следует поместить NULL-значение. Например, следующая команда поместит

NULL-значение в поле
менных

i_a

или

i_b

city

и в поле

comm таблицы Salesperson,

если индикаторы пере­

имеют отрицательное значение; в противном случае они получат

значения переменных включающего языка:

ЕХЕС

SQL INSERT INTO Salespeople
VALUES (:id_num, :salesperson, :loc:i_a, :comm:i_b);

Индикаторы переменных используются и для определения усечения строк, когда

символьное значение

SQL вносится

в переменную включающего языка, длина которой

недостаточна для сохранения всех символов. Это специальная проблема для нестан­
дартных типов данных

VARCHAR

и

LONG

(см. приложение С). В этом случае в пере­

менную заносятся начальные символы строки, а те символы, которые не умещаются в

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

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

295

Глава

25.

Использование

SQL

с другими языками программирования

для выяснения рассматриваемой здесь ситуации нужно выполнить проверку индикатора

переменной на

>

О, а не на

< О.

Итоги
SQL-команды включаются в процедурные языки программирования для комбиниро­
вания сил двух подходов. Реализации такой возможности требует некоторых расширений

SQL.

Команды встроенного

SQL транслируются

с помощью программы, названной пред­

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

SQL заменяются

вызовом подпрограмм, которые

создаются с помощью встроенного препроцессора; эти подпрограммы называются моду­

лями доступа. С помощью такого подхода

ANSI поддерживает встроенный SQL для язы­
ков программирования Pascal, FORTRAN, COBOL, PL/1. Другие языки также
используются разработчиками. Наиболее важным из них является С.
При описании встроенного SQL следует обратить особое внимание на следующее:


Все встроенные команды

SQL

начинаются словами ЕХЕС

SQL

и заканчивают­

ся в зависимости от используемого языка высокого уровня.



Все переменные языка высокого уровня, используемые в командах

ны быть внесены в раздел описаний

SQL

SQL,

долж­

до своего применения.



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



Выходные данные для запросов могут храниться непосредственно в перемен­
ных языка высокого уровня с помощью

INTO

тогда и только тогда, когда за­

прос выбирает единственную строку.



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

ходными данными и курсором). Пока курсор открыт, можно использовать
команду

FETCH

для доступа к выходным данным запроса: по одной строке для

каждого выполнения команды



FETCH.

Курсоры могут быть обновляемыми или "только для чтения". Чтобы быть об­
новляемым, курсор должен удовлетворять всем тем критериям, что и представ­

ление. Он не должен использовать предложения

ORDER ВУ

и

UNION,

которые

запрещено применять в представлении. Необновляемый курсор является курсо­
ром "только для чтения".

296

Итоги



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

DELETE

WHERE CURRENT OF. DELETE

SQL UPDATE и
UPDATE долж­

или

ны принадлежать той таблице, доступ к которой осуществляется через курсор
запроса.

• SQLCODE может быть объявлен

как переменная числового типа для каждой про­
граммы, использующей встроенный SQL. Значения этой переменной устанавли­
ваются автоматически после выполнения каждой SQL-команды.



Если команда

SQL

выполняется нормально, но не формирует выходных данных

либо не выполняет ожидаемых изменений в базе данных,

SQLCODE

принимает

значение 100. Если команда выдает ошибку, то SQLCODE принимает некоторое
отрицательное значение, описывающее причину ошибки, в зависимости от кон­
кретной SQL-системы. В противном случае



Предложение

WHENEVER

SQLCODE

равен нулю.

можно использовать для определения действия, ко­

торое следует выполнить, если SQLCODE принимает значение 100 (NOT
FOUND - не найдено) или отрицательное значение (SQLERROR - ошибка
при выполнении SQL). Это действие заключается в переходе к некоторой опре­
деленной точке программы (GOTO ) или к выполнению "пустого дейст­
вия" (CONTINUE, эквивалентно понятию "ничего не делать"). По умолчанию
принято "пустое действие".



В качестве индикаторов можно использовать только числовые переменные.
Переменные-индикаторы следуют за другими именами переменных в команде

SQL без



каких-либо разделяющих символов, за исключением слова

Обычно значение переменной-индикатора равно О. Если команда
разместить значение

NULL

INDICATOR.

SQL

пытается

в переменную языка высокого уровня, использую­

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

SQL

NULL-значения, которые будут специально интерпретироваться в основ­

ной программе.



Переменные-индикаторы можно использовать для вставки NULL-значений в
команды

SQL INSERT или UPDATE.

Они принимают положительные значения

при возникновении ситуации усечения строк.

297

Глава

25.

Использование

SQL

Работаем на

с другими языками программирования

SQL

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

не знакомым с языком программирования

Pascal

(либо с каким-либо другим языком,

из числа тех, что можно использовать для иллюстрации). Обратите внимание на ис­

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

Pascal.

Из программ опущены все детали, выходящие за пределы представ­

ленного в данной главе материала (определение устройств ввода/вывода, связи с базой
данных и так далее). Здесь мы представляем один из многих вариантов выполнения
этих упражнений.

1.

Разработайте простую программу, которая выбирает все сочетания
и

cnum из таблиц Ordres и Custorners и

snum

позволяет увидеть все эти комби­

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

snum для

Orders
Customers, то значе­

этой строки заменяется на соответствующее. Можно

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

ANSI,

(огра­

которое относится и к представлениям, но редко исполь­

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

cnums

являются корректными, и

т.д.). Следует предусмотреть секцию объявлений

(DECLARE)

и удосто­

вериться, что все используемые курсоры объявлены.

2.

Предположим, данная программа соответствует ограничению

ANSI,

ка­

сающемуся запрета на использование для курсов или представлений ха­

рактеристики "обновляемый". Как нужно модифицировать программу в
этом случае?

3.

Разработайте программу, которая дает возможность пользователю изме­
нить значения поля

city для

продавцов, автоматически увеличивая на

.01

комиссионные для продавцов, перемещенных для обслуживания в

Barcelona,

и уменьшая их на .О 1 для продавцов, перемещенных для обслу­

San Jose. Кроме того, продавцы, расположенные в данный мо­
London, теряют .02 своих комиссионных независимо от смены го­

живания в

мент в

рода, тогда как для продавцов, не расположенных в настоящее время в

298

London, их следует увеличить до .02. Изменения комиссионных базируются на
факте перемещения продавцов. Это не относится к продавцам, распо
ложенным в

London. Что касается возможности содержания в полях city
comm NULL-значений, следует придерживаться трактовки, принятой
SQL. Замечание: это несколько более сложная программа.

и
в

(Ответы даны в приложении А.)

299

А
Ответы
к упра31Снениям

Приложение А. Ответы к упражнениям

ГЛАВА

1

1. cnum
2. rating

3.

Запись

Поле

4.

-

-

альтернативное название строки.

альтернативное название столбца.

Потому что, по определению, порядок строк не имеет значения.

ГЛАВА2

1.

Символ (или текст) и число.

2.

Нет.

3.

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

4.

Слово, которое распознается

(DML, Data Manipulation Language).

SQL,

как специальная инструкция.

ГЛАВАЗ

1. SELECT onum, amt, odate
FROM Orders;
2. SELECT •
FROM Customers
WHERE snum =1001;
3. SELECT city, sname, snum, comm
FROM Salespeople;
4. SELECT rating, cname
FROM Customers
WHERE city ='San Jose';
5. SELECT DISTINCT snum
FROM Orders;
ГЛАВА4

1. SELECT • FROM Orders WHERE amt >1000;
2. SELECT sname, city
FROM Salespeople
WHERE city ='London'
AND comm >. 10;
3. SELECT •
FROM Customers
WHERE rating >100
OR city ='Rome·;

301

Приложение А. Ответы к упраJкнениям

или

SELECT •
FROM Customers
WHERE NOT rating < =100
OR city =· Rome';
или

SELECT •
FROM Customers
WHERE NOT (rating < =100
AND city < >'Rome');
Можно предложить и другие решения.

4. onum
3001
3003
3005
3009
3007
3008
3010
3011
5. onum
3001
3003
3006
3009
3007
3008
3010
3011
б.

ГЛАВА

amt
18.69
767.19
5160.45
1713.23
75.75
4723.00
1309.95
9891.88
amt
18.69
767.19
1098.16
1713.23
75.75
4723.00
1309.95
9891.88

odate
10/0311990
10/03/1990
10/03/1990
10/04/1990
10/04/1990
10/0511990
10/06/1990
10/0611990
odate
10/0311990
10/03/1990
10/03/1990
10/04/1990
10/04/1990
10/05/1990
10/0611990
10/06/1990

SELECT •
FROM Salespeople;

5

1. SELECT •
FROM Orders
WНERE odate IN (10/03/1990, 10/04/1990);
и

SELECT •
FROM Orders

302

cnum
2008
2001
2003
2002
2004
2006
2004
2006
cnum
2008
2001
2008
2002
2004
2006
2004
2006

snum
1007
1001
1002
1003
1002
1001
1002
1001
snum
1007
1001
1007
1003
1002
1001
1002
1001

Приложение А. Ответы 1< упражнениям

WHERE odate BEТWEEN 10/03/1990 AND 10/04/1990;
SELECT •
FROM Customers
WHERE snum IN (1001,1004);
SELECT *
FROM Customers
WHERE cname BEТWEEN . А. AND . н.;

2.

3.

Замечание: В системах, использующих АSСП-коды, указанные границы не включа­
ют фамилию

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

следует символ

4.

Giovanni и Grass. Символ 'G' можно
'Z' - последний символ алфавита.

использовать в случае, если за ним

SELECT •
FROM Custome rs
WHERE cname LIKE . сх . ;
SELECT •
FROM Orders
WHERE amt < > О
AND (amt IS NOT NULL);

5.

нлн

SELECT •
FROM Orders
WHERE NOT (amt = О
OR amt IS NULL);
ГЛАВА

6

1. SELECT COUNT( •)
FROM Orders
WHERE odate = 10/03/1990;
2. SELECT COUNT (DISTINCT city)
FROM Custome rs;
з. SELECT cnum, MIN (amt)
FROM Orders
GROUP ВУ cnum;
4. SELECT MIN (cname)
FROM Customers
WHERE cname LIKE 'GX';
5. SELECT city
МАХ (rating)
FROM Custome rs

303

Приложение А. Ответы к упраж11ениям

GROUP ВУ ci ty;
6. SELECT odate, count (DISTINCT snum)
FROM Orders
GROUP ВУ odate;
ГЛАВА

7

1. SELECT onum, snum, amt•.12
FROM О rde rs;
2. SELECT · For the city·, city·, · the highest rating is ·,
МАХ (rating)
FROH Customers
GROUP ВУ ci ty;
3. SELECT rating, cname, cnum
FROH Customers
ORDER ВУ rating DESC;
4. SELECT odate, SUH (amt)
FROH Orders
GROUP ВУ odate
ORDER ВУ 2 DESC;
ГЛАВА8

1. SELECT onum, cname
FROM Orders, Customers
WHERE Customers.cnum = Orders.cnum;
2. SELECT onum, cname, sname
FROM Orders, Customers, Salespeople
WHERE Customers.cnum = Orders.cnum
AND Salespeople.snum = Orders.snum;
3. SELECT cname, sname, comm
FROH Salespeople, Customers
WHERE Salespeople.snum=Customers.snum
AND comm > . 12;
4. SELECT onum,comm•amt
FROM Salespeople, Orders, Customers
WHERE rating > 100
AND Orders.cnum = Customers.cnum
AND Orders.snum = Salespeople.snum;
ГЛАВА

1.

304

9
SELECT first.sname, second.sname
FROM Salespeople first, Salespeople second
WHERE first.city = second.city

Приложение А. Ответы к упражнениям

AND first.sname < second.sname;
Алиасы могут иметь имена, отличные от указанных.

2.

SELECT cname, first.onum, second.onum
FROM Orders first, Orders second,Customers
WHERE first.cnum = second.cnum
AND first.cnum = Customers.cnum
AND first.onum < second.onum;

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

3. SELECT a.cname, a.city
FROM Customers а, Customers
WHERE а. rating = b.rating
AND Ь. cnum = 2001;
ГЛАВА

Ь

10

1.

SELECT •
FROM Orders
WHERE cnum =
(SELECT cnum
FROM Customers
WHERE cname = ·c1sneros");

или

SELECT •
FROM Orders
WHERE cnum IN
(SELECT cnum
FROM Customers
WHERE cname = Cisne гоs · ) ;
2. SELECT DISTINCT cname, rating
FROM Customers, Orders
WHERE amt>
(SELECT AVG (amt)
FROM О rde гs)
AND Orders.cnum = Customers.cnum;
3. SELECT snum, SUM (amt)
FROM Orde гs
GROUP ВУ snum
HAVING SUM (amt) >
(SELECT МАХ (amt)
FROM Orders);

305

Приложение А. Ответы к упражнениям

ГЛАВАJJ

1. SELECT cnum, cname
FROM Customers outer
WHERE rating =
(SELECT МАХ (rating)
FROM Customers inner
WHERE inner. ci ty = outer. city);

2.

Решение с помощью связанных подзапросов

SELECT snum, sname
FROM Salespeople main
WHERE city IN
(SELECT city
FROM Customers inner
WHERE inner.snum < > main.snum);
Решение с помощью соединения:

SELECT DISTINCT first.snum, sname
FROM Salespeople first, Customers second
WHERE first.city = second.city
AND first.snum < > second.snum;
Связанный подзапрос находит всех покупателей, которые не обслуживаются дан­
ным продавцом и дает возможность выявить ситуацию, когда кто-то из них находится

в том же городе. Решение с помощью соединения проще и более соответствует интуи­
тивным соображениям. Он выявляет случаи, когда значения в поле
значения в поле

snums не совпадают.

city

совпадают, а

Следовательно, с помощью операции соединения

получается более элегантное решение проблемы. Надо принять это во внимание, на­

чиная с этого момента. Более элегантный подзапрос для решения этой проблемы будет
рассмотрен позже.

ГЛАВА

12

1. SELECT •
FROM Salespeople first
WHERE EXISTS
(SELECT •
FROM Customers second
WHERE first.snum = second.snum
AND rating = 300);
2. SELECT a.snum, sname, a.city, comm
FROM Salespeople а, Customers Ь
WHERE a.snum = b.snum
AND b.rating = 300;
3. SELECT •
FROM Salespeole а
WHERE EXISTS

306

Приложение А. Ответы к упражнениям

(SELECT •
FROH Customers Ь
WHERE b.city = a.city
AND a.snum < > b.snum);
4. SELECT •
FROH Customers а
WHERE EXISTS
(SELECT •
FROM Orders Ь
WHERE a.snum = b.snum);
AND а. snum < > Ь. snum);
ГЛАВА

13

1. SELECT •
FROM Custome rs
WHERE rating > = ANY
(SELECT rating
FROH Customers
WHERE snum = 1002);
2.
cnum
cname
2002
Giovanni
2003
Liu
2004
Grass
Cisneros
2008
З.
SELECT •
FROM Salespeople
WHERE city < > ALL
( SELECT city
FROM Custome rs);

city
Rome
San Jose
Berlin
San Jose

rating
200
200
300
300

snum
1003
1002
1002
1007

или

4.

SELECT •
FROM Salespeople
WHERE NOT city = ANY
(SELECT city
FROM Customers);
SELECT •
FROM Orders
WHERE amt > ALL
(SELECT amt
FROM Orders а, Customers Ь
WHERE a.cnum = b.cnum
AND Ь.city = 'London');

307

Приложение А. Ответы к упраJ1снениям

5.

ГЛАВА

SELECT •
FROM Orders
WHERE amt >
(SELECT МАХ (amt)
FROM Orders а, Customers Ь
WHERE a.cnum = b.cnum
AND b.city = 'London');

14

1. SELECT cname, city, rating, 'High Rating·
FROM Customers
WHERE rating > = 200
UNION
SELECT cname, city, rating, · Low Rating·
FROM Customers
WHERE rating = 200
UNION
SELECT cname, city, rating, · Low Rating·
FROM Customers
WHERE NOT rating > = 200:
Различие между двумя предложениями заключается в способе записи второго пре­
диката. В обоих случаях строка 'Low Rating' имеет предшествующий пробел, таким

образом длина этой строки совпадает с длиной строки

SELECT cnum, cname
FROM Customers а
WHERE 1 <
( SELECT COUNТ( •)
FROM Orders Ь
WHERE a.cnum = b.cnum)
UNION
SELECT snum, sname
FROM Salespeople а
WH~RE 1 <
(SELECT COUNT (•)
FROM Orders Ь
WHERE a.snum = b.snum)
ORDER ВУ 2;
3. SELECT snum
FROM Salespeople

2.

308

'High Rating'.

Приложение А. Ответы к у11ражнениям

WHERE city = ·san Jose·
UNION
(SELECT cnum
FROM Customers
WHERE city = ·san Jose·
UNION ALL
SELECT onum
FROM Orders
WHERE odate = 10/03/1990);
ГЛАВА

15

1. INSERT INTO Salespeople (city, cname, comm, cnum)
VALUES (" San Jose ", "Blanco ", NULL, 1100);
2. DELEТE FROM Orders WHERE cnum = 2006;
З. UPDATE Customers
SЕТ rating = rating + 100
WHERE ci ty = 'Rome' ;
4. UPDATE Customers
SЕТ snum = 1004
WHERE snum = 1002;
ГЛАВА

16

1. INSERT INTO Multicust
SELECT •
FROM Salespeople
WHERE 1 <
(SELECT COUNT(•)
FROM Customers
WHERE Customers.snum = Salespeople.snum):
2. DELETE FROM Customers
WHERE NOT EXISTS
(SELECT •
FROM Orders
WHERE cnum = Customers.cnum);
З. UPDATE Salespeople
SET comm = comm + (comm•.2)
WHERE 3000 <
(SELECT SUM (amt)
FROM Orders
WHERE snum = Salespeople.snum);
Можно представить более наглядную версию этой команды, которая корректна
только для случая, когда комиссионные (comm) не превышают 1.0 (100 процентов).

UPDATE Salespeople

309

Приложение А. Ответы к упражнениям

SET comm = comm + (comm• .2)
WHERE 3000 <
(SELECT SUM (amt)
FROM Orders
WHERE snum = Salespeople.snum)
AND comg + (comm•.2) < 1.0;
Существуют другие успешные способы решения этих проблем.

ГЛАВА

17

1. CREATE TABLE Customers
(cnum
integer,
cname
char(10),
city
char(10).
rating
intege г,
snum
integer);
2. CREATE INDEX Datesearch ON Orders(odate);
(В примерах используются произвольные имена индексов.)
З. CREATE UNIQUE INDEX Onumkey ON Orders (onum);
4. CREATE INDEX Mydate ON Orders (snum, odate);
5. CREATE UNIQUE INDEX Combination ON
Customers (snum, rating);

ГЛАВА

18

1.

CREATE TABLE Orders
(onum
integer NOT NULL PRIMARY
amt
decimal,
adate
date NOT NULL,
cnum
integer NOT NULL,
snum
integer NOT NULL,
UNIQUE (snum, cnum));

КЕУ,

или

CREATE TABLE Orders
(onum integer NOT NULL UNIQUE,
amt
decimal,
odate date NOT NULL,
cnum
integer NOT NULL,
snum
integer NOT NULL.
UNIQUE (snum, cnum));
Первый вариант ответа является более предпочтительным.

2. CREATE TABLE Salespeople
(snum
integer NOT NULL PRIMARY

310

КЕУ,

Приложение А. Ответы к упражнениям

sname
char(15) СНЕСК (sname BEТWEEN 'АА' AND 'MZ'),
city
char(15),
comm
decimal NOY NULL DEFAULT = .10);
CREATE TABLE Orders
(onum
integer NOT NULL,
amt
decimal,
odate
date,
cnum
integer NOT NULL,
snum
integer NOT NULL,
СНЕСК ((cname > sname) AND (onum > cnum))):

з.

ГЛАВА

19

1.

2.

CREATE TABLE Cityorders
(onum
integer NOT NULL PRIMARY КЕУ,
amt
decimal,
cnum
integer,
snum
integer,
city
char(15),
FOREIGN КЕУ (onum,amt,snum)
REFERENCES Orders (onum, amt, snum)
FOREIGN КЕУ (cnum, city)
REFERENCES Customers (cnum, city) ) :
CREATE TABLE Orders
(onum
integer NOT NULL,
decimal,
amt
odate
date,
integer NOT NULL,
cnum
integer,
snum
prev
integer,
UNIOUE ( cnum, onum),
FOREIGN КЕУ (cnum, prev) REFERENCES Orders (cnum, onum) ): 9

ГЛАВА20

1.

2.

CREATE VIEW Highratings
AS SELECT •
FROM Customers
WHERE rating =
(SELECT МАХ (rating)
FROM Custome rs);
CREATE VIEW Citynumber
AS SELECT city, COUNT (DISTINCT snum)
FROM Salespeople
GROUP ВУ ci ty;

311

Приложение А. Ответы к упражнениям

з.

4.

CREATE VIEW Nameorders
AS SELECT sname, AVG (amt), SUM (amt)
FROM Salespeople, Orders
WHERE Salespeople.snum = Orders.snum
GROUP ВУ sname;
CREATE VIEW Multcustomers
AS SELECT •
FROM Salespeople а
WHERE 1 <
(SELECT COUNT(•)
FROM Customers Ь
WHERE а. snum = Ь. snum);

ГЛАВА21

1. #1 является необновляемым из-за использования DISТINCT.
#2 является необновляемым, поскольку он использует соединение, функцию аг­
регирования и GROUP ВУ.
#3 является необновляемым, поскольку он базируется на # 1, который, в свою
очередь, является необновляемым.

#4 является обновляемым.
2.

з.

CREATE VIEW Commissions
AS SELECT snum,comm
FROM Salespeople
WHERE comm BEТWEEN .10 AND .20
WITH СНЕСК OPTION;
CREATE TABLE Orders
(onum
integer NOT NULL PRIMARY КЕУ,
amt
decimal,
odate
date DEFAULТ VALUE = CUROATE,
snum
integer,
cnum
integer);
CREATE VIEW Entryorders
AS SELECT onum, amt, snum, cnum
FROM Orders;

ГЛАВА22

1. GRANT UPDATE (rating) ON Customers ТО Janet;
2. GRANT SELECT ON Orders ТО Stephen WITH GRANT OPTION;
з. REVOKE INSERT ON Salespeople FROM Claire;
4. War 1: CREATE VIEW Jerrysview
AS SELECT •
FROM Customers
WHERE rating BEТWEEN 100 AND 500

312

Приложение А. Ответы к упражнениям

WHITH СНЕСК OPTION;
2: GRANT INSERT, UPDATE ON Jerrysview то Jerry;
Шаг 1: CREATE VIEW Janetsview
AS SELECT •
FROM Customeгs
WHERE гating =
(SELECT MIN (rating)
FROM Customers);
Шаг 2:GRANT SELECT ON Janetsview то Janet;
Шаг

5.

ГЛАВА23

1. CREATE DBSPACE Myspace
(pctindex 15,
pctf ree
40);
2. CREATE SYNONYM Orders FOR Diane.Orders;

3.

Они должны откатываться назад.

4.

Исключительное использование.

5.

Только для чтения.

ГЛАВА24

1. SELECT a.tname, а.оwпег, b.cname, b.datatype
FROM SYSTEMCATALOG а, SYSTEMCOLUMNS Ь
WHERE a.tname = b.tname
AND а.оwпег = b.owner
AND a.numcolumns > 4;
Замечание: Поскольку большинство имен столбцов соединяемых таблиц различно,
не все случаи использования алиасов а и Ь в представленной команде являются необ­
ходимыми. Имена алиасов представлены для большей ясности.

2. SELECT tname, synowner, COUNT (ALL synonym)
FROM SYTEMSYNONS
GROUP ВУ tname, synowner;
3. SELECT COUNT (•)
FROM SYSTEMCATALOG а
WHERE numcolumns/2 <
(SELECT COUNT (DISTINCT cnumber)
FROM SYSTEMINDEXES Ь
WHERE a.owner = b.tabowner
AND а. tname = Ь. tname);
ГЛАВА25

1.

ЕХЕС

SQL BEGIN DECLARE

SECТION;

313

Приложение А. Ответы к упражнениям

SQLCOOE: intege г;
требуется всегда

cnum
snum

iпtegeг;

integeг;

custпum:

integeг;

salesnum: iпtegeг;
SQL ENO DECLARE SECTION;
ЕХЕС SQL DECLARE Wгопg_Огdегs AS CURSOR FOR
SELECT cпum, snum
FROM Огdегs а
WHERE snum < >
(SELECT sпum
FROM Customeгs Ь
WHERE a.cпum = b.cпum);
{ Здесь используется SQL. Рассмотренный запрос
ЕХЕС

таблицы Oгdes,

локализует строки

которые не согласуются со строками таблицы Customeгs.}

SQL DECLARE Cust_assigns AS CURSOR FOR
SELECT cnum,sпum
FROM Customeгs;

ЕХЕС

Этот курсор используется для поддержки правильных

значений столбца sпum.}

begin { основная программа }
ЕХЕС SQL OPEN CURSOR Wгопg_Огdегs;
while SQLCODE = О do
{Цикл пока значение переменной Wгong_Oгdeгs пусто.}

begin
SOL FETCH Wгong_Oгdeгs INTO
(: cпum, : snum);
if SQLCODE=O then
ЕХЕС

begiп

Если значение переменной Wгопg_Огdегs пусто,

то в этом

цикле ничего

не должно выполняется.}

ЕХЕС

SQL OPEN CURSOR

Cust_Assigпs;

гереаt

SOL FЕТСН Cust_Assigпs
INTO (:custпum, :salesпum);
until :custпum = :cпum;
Повторение команды FETCH uпtil ... приведет
ЕХЕС

перемещается

значение
ЕХЕС

wаг

за

шагом

до

пор,

cnum из Wгong_Orders не будет
SQL CLOSE CURSOR Cust_assigns;

{Таким образом,
Значение,

пока

ЕХЕС

к тому,

строка,

что курсор Cust_Assigпs

содержащая

текущее

найдена.}

каждое повторное выполнение происходит с начала цикла.

полученное с помощью этого курсора,

salesnum.}

314

тех

SOL UPDATE

Ordeгs

хранится в переменной

Приложение А. Ответы к упражнениям

SЕТ sпum = :salesпum
WHERE CURRENT OF Wroпg_Orders;
епd; { Еспи SQLCODE = О }
end; {Пока SQLCDDE ... выполнить}
ЕХЕС SQL CLOSE CURSOR Wroпg_Orders;
end; { основная программа }

2.

В программе, которую использовал автор, решение заключалось в простом

включении

onum( первичный ключ таблицы Orders в курсоре Wrong_orders). В коман­
UPDATE следует использовать предикат WHERE onum = :ordemum (в предположе­
нии, что объявлена переменная целого типа ordemum) вместо WHERE CURRENT OF
Wrong_Orders. Результирующая программа будет выглядеть примерно так (большинст­

де

во комментариев из предыдущей версии опущено):

SQL BEGIN DECLARE SECTION;
SQLCODE:
iпteger;

ЕХЕС

oderпum

iпteger;

cпum

iпteger;

sпum

iпteger;

custпum:

iпteger;

salesпum:

iпteger;

SQL END DECLARE SECTION;
ЕХЕС SQL DECLARE Wroпg_Orders AS CURSOR FOR
SELECT oпum, cnum, sпum
FROM Orders а
WHERE sпum < >
(SELECT snum
FROM Customers Ь
WHERE a.cnum = b.cnum);
ЕХЕС SQL DECLARE Cust_assigns AS CURSOR FOR
SELECT cnum,sпum
FROM Custome rs;
begin { основная программа
ЕХЕС SQL OPEN CURSOR Wroпg_Orders;
while SQLCODE = О do { Цикл, выполняемый до
пуст }
ЕХЕС

тех пор,

пока Wroпg_Orders

begiп

SQL FЕТСН Wroпg_Orders
INTO (: oderпum, : cпum, : snum);
if SQLCODE=O then
begin
ЕХЕС SOL OPEN CURSOR Cust_Assigns
repeat
ЕХЕС SQL FETCH Cust_Assigпs
INTO (: custпum, : salesnum);
uпtil :custпum = :cпum;
ЕХЕС

315

Приложение А. Ответы к упражнениям

SOL CLOSE CURSOR Cust_assigпs;
SOL UPDATE Огdегs;
SET sпum = :salesпum
WHERE CURRENT OF Wгопg_Огdегs;
епd; { if SOLCODE = О }
епd; { While SOLCODE ... do}
ЕХЕС SOL CLOSE CURSOR Wгопg_Огdегs;
епd; { основная программа }
З.
ЕХЕС SOL BEGIN DECLARE SECTION;
integeг;
SOLCODE
newcity
packed аггау[1 .. 12] of сhаг;
commпull
boolean;
ЕХЕС
ЕХЕС

cityпull

Ьооlеап;

cha г;
ЕХЕС SOL ENO DECLARE SECTION;
ЕХЕС SOL DECLARE CURSOR Salespeгsoп AS
SELECT • FROM SALESPEOPLE;
begin { основная программа }
ЕХЕС SOL OPEN CURSOR Salespeгsoп;
ЕХЕС SOL FЕТСН Salespeгsoп
INTO (:sпum, :sпame, :city:i_cit:comm:i_com);
{ Выбор (fetch) первой строки. }
while SOLCODE = О do
Цикл выполняется пока (while) есть строки в таблице
гesponse

Salespeгsoп.}

begiп

if i_com <
if i_cit <

О theп commпull
О theп cityпull

Установить булевы флаги,

if

cityпull

:
:

= tгue;
= tгue:

которые соответствуют NULL-значениям

then

begiп

wгite ("Для Salespeгsoпне обнаружено текущее значение столбца
city', sпum, 'Необходимо предпринять какие-либо действия?
(У(да)/N(нет))');
Данное приглашение соответствует случаю,

геаd

когда значение

( геsропsе):

Значение переменной геsропsе используем позже.

епd { if citynull }
else { поt citynull }
begiп

if

поt commпull

then

{Выполняем сравнение и действия для случая,
переменной

316

commnull

NULL
begin

отлично от

когда значение

city

пусто

(NULL)}

Приложение А. Ответы к у11ражнениям

{Для ситуации "если не

if city='London· then comm : = comm - .02
else comm : = comm + .02;
end;
commnull", begin и end указаны для ясности.
write ('Текущий город для продавца ·, snum,
Желаете изменить значение? (Y/N)');

city, ·

Замечание: Для продавца, которому в данный момент не назначен город, комиссион­

ные назначаются в зависимости от того, проживает он в Лондоне или нет.

read ( response);
response содержит значение независимо от того, имеет ли
переменная citynull значение "истина" или "ложь". }
end; { else not citynull }
if response = ·у· then
begin
write ('Введите новое значение для city: · );
read (newcity);
if not commnull then
{ Эта операция может быть выполнена только для значений, отличных от NULL }
case newcity of:
begin
'Barcelona': comm: = comm+.01,
'San Jose':comm: = comm-.01
end; { case and if not commnull}
ЕХЕС SQL UPDATE Salespeople
SЕТ city=:newcity, comm = : comm:i_com
WHERE CURRENT OF Salesperson;
{ Переменная-индикатор comm принимает NULL-значение в нужной ситуации}
епd; { если response = ·у·, если respoпse'Y',
{

Переменная

то никаких изменений выполнять не требуется.}
ЕХЕС

{

SQL FЕТСН Salesperson
INTO (:sпum,: sname, :с ity:i_cit,
: comm: i_com);

}
end; { пока SQLCODE = О }
ЕХЕС SQL CLOSE CURSOR Salesperson;
end; { основная программа }

Перейти к следующей строке

317

в
Типы данных

SQL

Приложение В. Типы данных

SQL

Типы данных, признаваемые ANSI, представлены символьным типом (CHAR) и
несколькими типами числовых значений, которые можно разбить на две категории:
точные числовые значения и приближенные числовые значения. Точные числовые

значения содержат цифры с десятичной точкой или без нее в традиционном представ­
лении числовых значений. Приближенные числовые значения представлены в экспо­
ненциальной форме (по основанию

1О).

Другие отличия

между этими двумя

числовыми типами менее существенны.

Иногда типы данных используют аргумент, названный в книге аргументом разме­
ра, точный формат и значение которого зависят от конкретного типа данных. Если ар­
гумент размера опущен, принимаются значения по умолчанию для всех типов.

TunыANSI
Далее представлены типы данных

ANSI

(название в скобках является синонимом).

ТЕКСТ (ТЕХТ)
Тип данных

Описание

CHAR
(CHARACTER)

Строка текста в формате, определенном разработчиком. Для
этого типа аргумент размера

-

целое неотрицательное число,

задающее максимальную длину строки. Значения этого типа
можно заключить в одиночные кавычки, например, 'текст'. Две

следующие друг за другом одиночные кавычки

("),

расположен­

ные внутри строки, задают один символ одиночной кавычки.

ТОЧНО ЧИСЛОВЫЕ (ЕХАСТ NUMERJC)
Тип данных

Описание

DEC (DECIMAL)

Десятичное число, т.е. число, которое может иметь в своем

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

320

TunыANSI

вышает его. Масштаб определяет максимальное количество
разрядов справа от десятичной точки. В том случае, когда мас­
штаб равен нулю, поле эквивалентно типу "целый"

(INTEGER).
NUMERIC

Совпадает с

DECIMAL,

за исключением того, что макси­

мальное количество разрядов не может превышать аргумента
точности.

INT (INTEGER)

Число без явно представленной десятичной точки. Этот тип эк­
вивалентен типу

DECIMAL,

не имеющему разрядов справа от

десятичной точки, т.е. с масштабом, равным О. Аргумент разме­
ра не используется (он назначается автоматически в зависимо­

сти от конкретного способа реализации).

SMALLINT

Совпадает с

INTEGER,

за исключением того, что в зависимости

от конкретного способа реализации, размер, принятый по умол­
чанию для этого типа, может быть (или не быть) меньше, чем
для типа

INTEGER.

ПРИБЛИЖЕННЫЕ ЧИСЛОВЫЕ

(APPROXIMATE NUMERIC)

Тип данных

Описание

FLOAT

Число с плавающей точкой, представленное в экспоненциаль­

ной форме по основанию

1О.

Аргумент размера содержит един­

ственное число, задающее минимальную точность.

REAL

Совпадает с

FLOAT,

за исключением того, что аргумент разме­

ра не используется. Точность устанавливается по умолчанию в

зависимости от конкретного способа реализации.

DOUBLE
PRECISION
(или DOUBLE)

Совпадает с

REAL,

ной реализации для

за исключением того, что точность кою,-рет­

DOUBLE PRECISION, может превышать
REAL.

точность конкретной реализации для

321

Приложение В. Типы даниых

SQL

Эквивалентные типы данных в других
языках

При вк.1ючении

SQL

в другие языки значения, используемые в командах

получаемые в результате выполнения команд

SQL,

SQL

и

обычно хранятся как перемен­

ные включающего языка (см. главу

25). Эти переменные должны быть совместимы
SQL, которые они содержат. В приложениях, не яв­
официального стандарта SQL, ANSI предоставляет для приме­

по типам данных со значениями
ляющихся частью
нения

в

качестве включающих

языков

PASCAL, PL/I, COBOL, FORTRAN.

программирования следующие языки:

Одна из возникающих здесь проблем

-

необ­

ходимость определить эквивалентность типов данных для переменных, используе­
мых в этих языках.

Далее представлены эквиваленты для четырех, определенных

ANSI,

языков.

PVI
Тип в

SQL

Эквивалент в

PL/I

CHAR

CHAR

DECIMAL

FIXED

INTEGER

FIXED BINARY

FLOAT

FLOAT BINARY

DECIМAL

COBOL
Тип в

SQL

Эквивалент в

COBOL

CHAR( )
INTEGER

PIC
PIC

Х()

NUMERIC

PIC S() DISPLAY

PASCAL
Тип в

SQL

Эквивалент в

PASCAL

INTEGER

INTEGER

REAL

REAL

CHAR()

PACKED ARRAY [1 .. ] OF CHAR

322

Эквивалент11ые типы да1111ых в других языках

FORTRAN
Тип в

SQL

Эквивалент в

CHARACTER

CHARACTER

INTEGER

INTEGER

REAL

REAL

DOUBLE
PRECISION

DOUBLE
PRECISION

FORTRAN

323

с

ШtELIJJrnuШLЫD
Некоторые общие
отклонения от

стандарта

SQL

Приложение С. Некоторые общие отклоиения от стандарта

SQL

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

SQL,

ANSI,

ни в стандарте

ISO,

но являются общими для

в силу того, что в практике они были признаны полезны­

ми. В этом приложении рассматриваются подобные характеристики. Естественно, что

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

Типы данных
Типы данных, поддерживаемые стандартом
Они представлены типом

CHARACTER

SQL,

рассмотрены в приложении В.

и множеством числовых типов. Фактически,

разрабатываемые приложения могут быть гораздо более сложными в плане реально
используемых типов данных. Обсудим некоторые нестандартные типы данных.

ТИПЫ DATE (дата) и
Тип данных

DATE

TIME

(время)

широко используется несмотря на то, что он не является часгью

стандарта. Мы применяли этот тип в таблице

mm/dd/yyyy.

Orders, предполагая формат:
IBM в качестве стандартного

Такой формат представления даты принят

для США. Конечно, возможны и другие, и конкретные реализации часто поддержива­

ют множество форматов, предоставляя возможность выбора в соответствии с потреб­

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

Стандарт

Формат

Пример

Формат

ISO (lntemational
Standards Organization)

yyyy-mm-dd

1990-10-31

Формат JIS (Japanese
Industrial Stadard)

yyyy-шm-dd

1990-10-31

Формат EUR (IВМ
European Stadard)

dd.mm.yyyy

10.31.1990

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

также сравнивать, например,
в хронологическом порядке.

326

date

А

< date

В означает, что дата А предшествует дате В

Типы данных

Есть множество программ, в которых, помимо дат, принят специальный тип для

времени (ПМЕ); для представления времени также определено множество форматов,
включая следующие:

Стандарт

Формат

Пример

Формат

hh-mm-ss

21.04.37

hh-mm-ss

21.04.37

hh-mm-ss

21.04.37

ISO (Intemational
Standards Organization)
Формат JIS (Japanese
lndustrial Standard)
Формат EUR (IВМ European
Standard)
Формат USA (IВМ USA
Standard)

hh.mm

АМ/РМ

Для данных, представленных в формате

TIME,

9.04

РМ

определены операции сложения и

сравнения (как и для данных, представленных в формате

DATE),

причем количество се­

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

(CURDATE

и CURТIME соответственно). Эти константы сходны с константой

USER

в

том смысле, что их значения постоянно обновляются.
Можно ли включить время и дату в одно поле? Некоторые реализации включают
только тип

DATE,

предполагая, что этого вполне достаточно. Напротив, есть реализа­

ции, в которых определен тип ТIMESTAMP, который определяется как комбинация
двух типов

-

DATE

и ПМЕ.

ТИПЫ ТЕХТ STRJNG (строка текста)

ANSI

поддерживает один тип для представления текста. Это тип

CHAR.

Предпо­

.1агается, что любое поле этого типа имеет индивидуальную длину. Если строка,
вставляемая в поле, имеет меньшую длину, то она дополняется пробелами; длина

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

Например, операция

UNION

применима только к символьным полям одинаковой

длины.

Многие разработки поддерживают строки переменной длины и для этого
данных

CHAR

VARCHAR и LONG VARCHAR (часто

называемый просто

LONG).

-

типы

Поле типа

всегда занимает при размещении в основной памяти количество символов, оп­

ределяемое

VARCHAR

максимальным

количеством символов,

хранящихся

в

поле, а поле

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

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

254 до 2048 символов для типа VARCHAR и вплоть до 16К символов для типа LONG.
Тип LONG обычно используется для текстов более или менее одинаковой природы
(например, для поясняющих текстов) или для данных, которые трудно сжать до про-

327

Приложение С. Некоторые общие отклонения от стандарта

стого поля. Тип

VARCHAR

SQL

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

изменяется в достаточно широких пределах.

Не рекомендуется использовать тип

VARCHAR вместо CHAR. Реализация опера­
VARCHAR сложнее и, следовательно, мед­
CHAR. Кроме того, тип VARCHAR использует

ций поиска и обновления для полей типа

леннее, чем для полей типа
определенный объем основной памяти для хранения длины строки. Следует оценить,

какая часть множества значений поля будет отличаться по длине, а также будут ли зна­
чения поля объединяться с другими полями, прежде чем решить какому из типов от­
дать предпочтение: CHAR или VARCHAR. Часто тип LONG используют для хранения
двоичных данных. Конечно, поля типа

LONG

не всегда кажутся удачными, но тем не менее в

имеют ограничения по длине, которые

SQL можно

работать с данными такого

типа. Детали следует уточнять по соответствующим руководствам.

Команда FORМAT
Набор средств для обработки результата в стандартном
Хотя многие реализации включают

SQL

SQL

весьма ограничен.

в пакеты программ, предоставляющие раз­

личные средства для выполнения этой функции, некоторые реализации используют
команду, подобную команде FORМAT, в самом

SQL

для применения определенных

структур при оформлении ответа на запрос. Среди возможных функций команды

FORMAT следует

отметить следующие:



установка ширины столбцов (для печати);



определение способа представления NULL-значений;



назначение новых имен столбцов;



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



применение подходящих или изменение заданных форматов, содержащих дату,
время или денежную единицу;



подведение итогов и подытогов без исключения полей, по которым оно произ­
водится, как и с помощью
задачи

в

некоторых

SUM.

Один из возможных подходов к решению этой

программных

продуктах

-

использование

предложения

COMPUTE.
Команду

FORMAT можно

включить непосредственно до или после запроса, для

которого эта команда применяется, в зависимости от реализации. Обычно одна ко­

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

FORMAT NULL ·- _ _ _ _
FORMAT BTITLE 'Заказы,
FORMAT EXCLUDE (2, З);

328


сгруппированные по продавцам';

Функции

Первое из этих предложений определяет способ печати NULL-значений в виде

'_______ '.

В соответствии со вторым предложением заголовок, указанный в ка­

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

FORMAT

можно применить для выбора конкретных столбцов

таблицы с целью их использования в предложении

ORDER ВУ для упорядочения
FORMAT выполняются

выходных данных. Поскольку особые функции команды

по-разному, полное описание ее возможных применений выходит за границы дан­

ной книги.
Существуют другие команды, которые с успехом могут пополнить список таких
функций. Команда

SET похожа

на команду

FORMAT.

Она может служить альтернати­

вой команде FORМAT либо быть командой, область действия которой распространя­
ется на все запросы текущего сеанса пользователя, а не только на один запрос.

Некоторые реализации начинают команды с ключевого слова

ключевого слова

FORMAT.

COLUMN,

а не с

Например:

COLUMN odate FORMAT dd-mon-yy;
Это предложение задает формат представления поля даты

1O-Oct-90 для

вывода ре­

зультатов запросов.

Предложение

COMPUTE,

упомянутое ранее, включается в запрос таким образом:

SELECT odate, amt
FROM Orders
WHERE snum = 1001
COMPUTE SUM ( amt);
В соответствии с этим запросом будут получены все заказы для
даты

(odate)

и количества (ашt), а затем

-

итог по полю

осуществляют подведение итогов, используя

COMPUTE

amt.

Peel

с указанием

Некоторые реализации

как команду. В такой реали­

зации прежде всего определяется прерывание:

BREAK ON odate;
По этой команде происходит разделение результата сформулированного выше за­
проса на группы таким образом, что в пределах одной группы значение поля

odate ос­

тается постоянным. Теперь можно ввести следующее предложение:

COMPUTE SUM OF amt ON odate;
Столбец, указанный после ключевого слова
пользован в команде

ON,

должен быть предварительно ис­

BREAK.

Функции
В АNSI-стандарте

SQL

можно применять функции агрегирования к столбцам и ис­

*

пользовать их значения в скалярных выражениях, например: comm
100. Существует и
множество других полезных функций, применимых на практике. Функции SQL, отли­
чающиеся от стандартных функций агрегирования, можно применять в предложении

329

Приложение С. Некоторые общие отклонения от стандарта

SELECT запроса, точно так же,

SQL

как и стандартные, но при этом они воздействуют не на

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

SELECT, если

не оговорено нечто другое.

Математические функции
Данные функции применяются к числовым значениям.
Функция

Назначение

ABS(X)

Абсолютное значение Х (преобразует отрицательное или
положительное в положительное)

CEIL(X)

Х имеет десятичное значение, которое следует

FLOOR(X)

Х имеет десятичное значение, которое следует

округлить сверху.

округлить снизу.

GREATEST(X,Y)

Возвращает большее из двух значений.

LEAST(X,Y)

Возвращает меньшее из двух значений.

MOD(X,Y)

Возвращает остаток от деления Х на У.

POWER(X,Y)

Возвращает Х, возведенный в степень У.

ROUND(X,Y)

Округляет Х до У десятичных разрядов. Если У не
указан, то округляет до целого.

SIGN(X)

Возвращает минус, если Х

<

О, и плюс

-

в противном

случае.

SQRT(X)

Возвращает квадратный корень из Х.

Символьные функции
Эти функции могут применяться к строкам текста или столбцам, для которых определен тип данных ТЕХТ, к заданным явно строкам текста или их комбинациям.
Функция

Назначение

LEFT( ,Х)

Возвращает Х самых левых символов из строки.

RlGHT(,X)

Возвращает Х самых правых символов
из строки.

ASCil()

Возвращает ASCII-кoд, который представляет
строку в памяти компьютера.

330

Функции

CHR()

Возвращает символы, соответствующие
ASCII-кoдy.

()

VALUE

Возвращает математическое значение строки.
Предполагается, что строка

или

CHAR

VARCHAR,

из чисел. VALUE('З')

число

UPPER

()

3

типа

имеет тип

но состоит

выдает

INTEGER.

Все символы в строке переводятся в

"большое" (заглавное, строчное) написание.

LOWER

()

Все символы в строке переводятся в "малое"
(прописное) написание.

INIТCAP ()

LENGTH

()

ll

Все символы в строке переводятся в
написание "в одном регистре". В некоторых
реализациях функция называется PROPER.
Возвращает количество символов в строке.
Комбинирует две строки в выходных

данных, таким образом, что первая из них
непосредственно

второй.

(11

предшествует

называется оператором

конкатенации.)

LPAD

(,Х,'*')

Заполняет строку слева символом

"*"

или

любым другим символом, указанным в
кавычках, для того, длина строки стала

равной Х.

RPAD

( ,Х,'*')

Совпадает с

LPAD,

за исключением того, что

заполнение строки осуществляется справа.

SUBSTR

( ,Х,У)

Извлекает У символов из строки, начиная с
позиции Х.

331

Приложение С. Некоторые общие отклонения от стандарта

SQL

Функции даты и вре.Iнени
Эти функции воздействуют на значения "дата" и "время".
Функция

Назначение

DАУ()

Извлекает день месяца из даты. Аналогичные функции
существуют для MONTH (месяца), YEAR (года),

HOUR

(часа),

SECOND

(секунды) и т.д.

Определяет название дня недели по дате.

WEEKDAY
()

Прочие
Эти функции применимы к любому типу данных.
Функция

Назначение

NVL(,)

NVL (NULL Value)



определяемое вторым аргументом, вместо каждого

подставляет ,

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

Операции
и

MINUS
Команда

INTERSECT (пересечение)
(разность)

UNION

связывает два запроса, объединяя результаты выполнения каждо­

го из них в один. Два других способа комбинирования результатов отдельных запро­
сов базируются на использовании операций

INTERSECT
-

(разность). Результат выполнения операции INТERSEPT

(пересечение) и
строки,

MINUS

которые содер­

жатся в результате выполнения каждого из участвующих в операции запросов. Резуль­
тат выполнения операции

MINUS -

только те строки, которые получаются в

результате выполнения одного из участвующих в операции запросов, но не содержат­
ся в другом.

Следовательно, следующие два запроса:

SELECT •

FROM Salespeople
WHERE city

332

= 'London·

Автоматические

OUTER JOINS (внешние соединения)

INTERSECT
SELECT *
FROM Salespeople
WHERE 'London' IN
(SELECT city
FROM Customers
WHERE Customers.snum = Salespeople.snum);
выводят строки, выбираемые каждым их этих запросов и содержащие сведения о тех
продавцах в Лондоне, которые имеют, по крайней мере, одного покупателя в своем
городе.

С другой стороны:

SELECT *
FROM Salespeople
WHERE city='London'
MINUS
SELECT *
FROM Salespeople
WHERE 'London' IN
(SELECT city
FROM Customers
WHERE Customers.snum = Salespeople.snum);
в результате выполнения такой команды строки, выбранные первым запросом,
удаляются из выходных данных второго, т.е. мы получаем
сведения обо всех
продавцах из Лондона, не имеющих покупателей в этом городе. Иногда операцию
MINUS называют DEFFERENCE.

Автоматические

OUTER JOINS (внешние

соединения)
В главе

14 было показано, как выполнить операцию внешнего соединения, исполь­
UNION. Некоторые программы, осуществляющие обработку баз данных,

зуя команду

предусматривают непосредственные способы выполнения внешнего соединения. В
отдельных реализациях указывается бинарная операция "плюс"

(+)

после предиката,

которая говорит о том, что следует рассматривать строки, удовлетворяющие условию,

и строки, условию не удовлетворяющие. Условие предиката будет содержать поле, ис­

пользуемое в обеих таблицах, а NULL-значения включаются, если соответствие не

333

Приложение С. Некоторые общие отклонения от стандарта

SQL

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

SELECT a.snum, sname, cname
FROM Salespeople а, Customers
WHERE a.snum=b.snum (+);
что эквивалентно следующей операции

SELECT a.snum, sname, cname
FROM Salespeople а, Customers
WHERE a.snum = b.snum
UNION
SELECT snum, sname, ·_
FROM Salespeople
WHERE snum NOT IN
(SELECT snum
FROM Customers);

Ь

UNION:
Ь

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

FORMAT

NULL-

в этом приложении).

Ведение журнш~а
Реализация

SQL,

если она поддерживает доступ многих пользователей, скорее все­

го обеспечивает и какую-то возможность фиксации обращений к базе данных. Суще­
ствуют два основных вида таких средств: ведение журнала и ведение отчета (аудит).
Цели их применения различны.

Ведение ;журнала выполняется для защиты данных от сбоев в системе. Во-первых, ис­
пользуется зависящая от реализации процедура, которая позволяет восстановить текущее

состояние базы данных: создается внешняя копия содержимого базы данных, которая мо­
жет хранится где-либо (независимо от компьютера). Затем в журнале фиксируются изме­

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

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

334

Ведение J1еурнш~а

JORNAL ON;

SЕТ

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

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

AUDIT INSERT ON Salespeople
Предложения

ON

ВУ

Diane;

или ВУ могут быть опущены, в результате задается режим про­

верки для всех объектов и для всех пользователей соответственно. Если вместо
AUDIТ

Diane,

INSERT указать AUDIT ALL, будут фиксироваться все действия пользователя
в том числе и с файлом базы данных Salespeople.

335

Справка по синтаксису
и командам,

Приложение

Справка по синтаксису и командам

D.

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

SQL. Первая часть содержит элементы, используемые
- детали синтаксиса и краткие объяснения команд.

для создания SQL-команд; вторая

Рассматриваются следующие стандартные соглашения (названные ВNF-со­
rлашениями):



Ключевые слова задаются большими буквами.

• SQL
(<

и другие специальные термины указаны в угловых скобках и курсивом

апd

>).



Любые части команды указаны в квадратных скобках



Круглые скобки

(... )

([ and ]).

показывают, что предшествующая часть команды может

быть повторена любое число раз.



Вертикальный разделитель

( 1)

указывает, что все стоящее перед ним можно за­

менить всем тем, что за ним следует.



Фигурные скобки

( { and }) определяют:

все, что указано внутри них, должно рас­

сматриваться как единое целое при применении к нему других символов.



Два двоеточия и знак равенства(:

:

=)означают, что правая часть этой конст­

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

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

(* nonstandard *).
Замечание: Терминология, используемая здесь, не является официальной термино­
ANSI. Официальная терминология представляется слишком запутанной, и ее уп­

логией

ростили. Поэтому иногда используются термины, отличные от

ANSI,

ANSI,

либо термины

но с некоторыми отличиями от стандарта. Например, определение

содержит две части: одна часть
рая часть

-

-

та, которая стандартно называется , вто­

та, которая называется .

Элементы

SQL

Этот раздел содержит элементы команд

SQL.

Они разбиты на две категории: ос­

новные элементы языка и функциональные элементы языка. Основные элементы язы­
ка

-

это основные строительные блоки языка; когда

SQL

выполняет разбор команды,

он, прежде всего, оценивает каждый символ в тексте команды в терминах этих элемен­

тов. отделяет одну часть команды от другой; все то, что расположено

338

Элементы

SQL

между двумя соседними считается единицей. На базе выделения та­
ких единиц в тексте запроса

SQL

интерпретирует команду.

Элементы, отличные от ключевых слов, являются функциональными и интерпре­
тируются в

SQL. Части команды, расположенные между

ll



- -



символ пробела



символ конца строки (зависит от реализации)



[ {! } ... ]

Замечание: В строгом соответствии со стандартом
буквы могут быть только большими
и не может содержать

ANSI,
более

18

символов.


Элемент

Определение



%



любой из следующих:

или





[любая печатаемая строка в одиночных кавычках]

Элемент

,( ) .:=+

* - /

>=

342

1



Элементы

SQL

<
>=


Если какое-либо из равно
кат сравнения> имеет значение

unknown.

NULL, то



Предикат "между" А

AND

[NOT]

=В AND А

IS NOT NULL дает тот
IS NULL).

же результат, что и предикат NОТ(]}., ..

[

[

..

пароль>]

CONNECT дает определенные права, среди них право вести журнал. RESOURCE
дает пользователю право создавать таблицы. DBA предоставляет практически неогра­
ниченные права. IDENТIFIED ВУ используется с

CONNECT

для изменения пароля

пользователя.

349

Приложение

D.

Справка 110 синтаксису и командам

INSERT
Синтаксис

INSERT INTO
VALUES



[

()

()

INSERT создает один

]

1 ;

или более новых столбцов в таблице, имя которой указано в

команде. Если используется предложение

VALUES,

то значения, перечисленные в

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

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

OPENCURSOR
Синтаксис
ЕХЕС

SQL OPEN CURSOR



OPEN CURSOR выполняет запрос,

связанный с . Выходные дан­

ные после выполнения этой команды можно получить построчно с помощью команды

FETCH

(по одной строке в результате выполнения одной команды

REVOKE (*не соответствует

стандарту

FETCH).

*)

Синтаксис

REVOKE { ALL [PRIVILEGES]
.,

.. } [ON

]

FROM { PUBLIC
.

, .. };

'

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

том случае, когда привилегия специфична для конкретного объекта.

350

КомандыSQL

ROLLBACK (WORK)
Синтаксис

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

SELECT
Синтаксис

SELECT { [OISTINCT ALL] ., .. } 1 •
[INTO (•только для
встроенного варианта использования•}]

FROM ., ..
[WHERE ]
[GROUP ВУ .,

.. ]

Предложение образует запрос и выводит значения из базы данных (см. главы

3-14).

Для неrо действуют следующие правила и определения.



Если ни



содержит ,

, , , либо
любую их комбинацию с использованием операторов, формирующих правиль­
ное выражение.



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

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



Если употребляется
мые в предложении

GROUP ВУ, то все , применяе­
SELECT, могут использоваться как ,

независимо

от того,

входят ли

они

в

состав

. Все должны быть представлены в
предложения SELECT. Для каждой отдельной комбинации значений из в результат включается одна
и только одна строка.



Если используется НА VING, то применяется к каждой строке ре­
зультата, формируемого в соответствии с предложением GROUP ВУ, если ре­
зультат применения для данной строки - "истина", то эта строка
включается в состав выходных данных.



Если используется

ORDER

ВУ, выходные данные имеют определенную после­

довательность вывода. Каждый ссылается на от­

дельный элемент , указанного в

предложении SELECT. Если является
спецификатором столбца, то совпадает со . В противном случае являет­
ся положительным целым числом, указывающим расположение в соответствующего предложения

SELECT.
ORDER

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

Выходные
ВУ. В пре­

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

ключевое слово DESC. , указанный в предложении
ВУ первым, имеет преимущество перед остальными в завершающей

ORDER

последовательности строк выходных данных.

Предложение

SELECT

оценивает каждую возможную строку-кандидат таблицы

(таблиц), полученную независимо. Строка-кандидат определяется следующим обра­
зом:



Если включена только одна , каждая строка этой таблицы
рассматривается как строка-кандидат.



Если включено более одной , то каждая строка каждой
таблицы комбинируется со всеми комбинациями строк из других таблиц. Каж­
дая такая комбинация рассматривается как строка-кандидат.

Для каждой строки-кандидата значения подставляются в , заданный в

предложении

WHERE; предикат принимает одно из значений: true, false, unknown.
GROUP ВУ, каждое при­

Если не используется

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

используется

GROUP

ВУ, то строки-кандидаты комбинируются с использованием аг­

регатных функций. Если никакой предикат не указан, то каждое применяется к каждой строке-кандидату или к каждой группе. Если

указано DISТINCT, то повторяющиеся строки исключаются из результата.

352

КомандыSQL

UNION
Синтаксис


{ UNION [ALL]



}... ;

Выходные данные двух или более запросов объединяются. Каждый из запросов
должен содержать одинаковое число элементов в в предложении

SELECT, а элементы, стоящие

на одном и том же месте в , должны быть совместимы по типу данных и
размеру.

UPDATE
Синтаксис

UPDATE



SET { = }.,

..

UPDATE выполняет замену значений столбцов, имена которых указаны в предло­
SET, соответствующим значением из .
Если в предложении WHERE указан , то замена значений выполняется
жении

только в тех строках таблицы, на которых принимает значение "истина".
Если

WHERE содержит предложение CURRENT OF, то

происходит замена значений в

текущей строке таблицы значениями из текущей строки курсора. Форма WHERE
CURRENT OF обычно используется только во встроенном SQL и только с применени­
ем курсора. Если отсутствует предложение WHERE, во всех строках выполняется за­
мена.

WHENEVER
Синтаксис
ЕХЕС

SQL WHENEVER





: : = SQLERROR

1

NOT FOUND

1

SQLWARNING

(в официальный стандарт не входит)


:: =

::

CONТINUE

1

GOTO



GO

ТО

=зависит от включающего языка.

353

w

~ Ь1] 1]

ffil

Е
ив

Таблицы,
используеJJ.tые
в примерах

Приложение Е. Таблицы, используемые в 1tримерах

Таблица

1. Salespeople (продавцы)

snum

sname

1001
1002
1004
1007
1003

Рее)

Таблица
cnum

2001
2002
2003
2004
2006
2008
2007
Таблица

Serres
Motika
Rifkin
Axelrod

city
London
San Jose
London
Barcelona
New York

2. Customers
cname
Hoffman
Giovanni
Liu
Grass
Clemens
Cisneros
Pereira

3: Orders

comm

.12
.13
.ll

.15
.10

(покупатели)

city
London
Rome
San Jose
Berlin
London
San Jose
Rome

rating

snum

100
200
200
300
100
300
100

1001
1003
1002
1002
1001
1007
1004

(заявки)

onum

amt

odate

cnum

snum

3001
3003
3002
3005
3006
3009
3007
3008
3010
3011

18.69
767.19
1900.10
5160.45
1098.16
1713.23
75.75
4723.00
1309.95
9891.88

10/03/1990
10/03/1990
10/03/1990
10/03/1990
10/03/1990
10/04/1990
10/04/1990
10/05/1990
10/06/1990
10/06/1990

2008
2001
2007
2003
2008
2002
2004
2006
2004
2006

1007
1001
1004
1002
1007
1003
1002
1001
1002
1001

356

F
SQLсегодня

Приложение

F. SQL

сегодня

SQLсегодня
В настоящее время

SQL

переживает новый подъем. В качестве коммерческо- го

продукта язык был впервые реализован в

Oracle в 1976 году, но официального стан­
SQL не существовало до 1986 года, когда он был опубликован как результат объ­
единенных усилий ANSI (the American National Standards Institute) и ISO (lnternational
Standards Organization). Поскольку ANSI является частью ISO, в данном приложении
мы ссылаемся на обе эти организации как на ISO. Стандарт 1986 года был пересмот­
рен в 1989 году, в него были введены средства, обеспечивающие ссылочную целост­
ность (referential integrity).
К тому времени, когда появился стандарт 86, ряд программных продуктов уже ис­
пользовал SQL, и ISO попытался закрепить в стандарте наиболее общие черты этих реа­

дарта

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

ISO

проанализировал все основные характеристики сущест­

вовавших к тому времени программных реализаций и определил весьма минимальный
стандарт. Некоторые существенные характеристики, например, как уничтожение объек­

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

тех характеристик, которые ранее были отданы на усмотрение разработчика. Несколько
лет эксплуатации конкретных систем и теоретических исследований дали новые идеи,

которые требуют единообразия при воrшощении в программных продуктах. Для удов­
летворения этих потребностей
Стандарт

ISO разработал новый стандарт SQL 92 .
SQL 92 превышает первый стандарт SQL по объему примерно в пять раз.

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

SQL 92,

включает как подмножество стандарт

89,

можно ссылаться на стандарт

если программный продукт удовлетворяет требованиям стандарта

89

92,

или некоторым

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

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

флаггера

(flagger) -

программы, проверяющей основной код и помечающей (марки­

рующей) все предложения

SQL,

не соответствующие стандарту

92.

Непомеченные

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

рой предложение соответствует стандарту, а его поведение

-

нет. Такое предложение

также помечается. В любом случае, этот стандарт более полон, чем предыдущий, по­

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

358

SQL

сегодня

Пользователи, схемы и сеансы связи
Одной из областей, в которой старый стандарт отсутствовал, а новый стандарт су­
щественно улучшен, является определение контекста применения

SQL -

определе­

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

группироваться в кластеры. Некоторые системы управления базами данных (СУБД)
используют эти термины не так, как определено в стандарте, об этом может свиде­
тельствовать системная документация.

С точки зрения отдельного сеанса

SQL,

кластер является целым миром. Он содер­

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

В стандарте уточняется смысл требований

SQL

относительно того, кто и какие

предложения может задавать. Тот, кто выдает предложения

SQL,

называется

агентом. Им может быть пользователь, непосредственно работающий с
приложение. Агент

SQL устанавливает

SQLSQL, или

связь с СУБД. Как только связь установле­

на, начинается сеанс. Реализации позволят SQL-агентам переключаться на некото­

рые другие связи и сеансы. В среде клиент/сервер эти связи или сеансы могут быть
полностью адресованы другому серверу. В любой момент времени может сущест­
вовать определенный текущий сеанс, который является активным и, возможно, не­
сколько других, которые в этот момент не действуют, но находятся на разных

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

Рассмотрим среду (контекст), в которой используются SQL-предложения и ряд но­
вых особых характеристик в стандарте

SQL 92.

Что нового в стандарте

92?

Стандарт

92,

за редкими исключениями, полностью включает в себя стандарт

89.

Если он вам известен, то достаточно ознакомиться лишь с обзором того, что было к
нему добавлено.

Предложения определения схемы.

Схема

(shema) -

это множествообъектов

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

SQL

определял процедуры создания

и удаления таблиц и других объектов, но он просто отождествлял схемы с идентифи­
каторами пользователей
его

ID,

(authorization IDs),

как правило, понимая под пользователем

что не оговорено в стандарте. Для пользователей, которые могут захотеть соз­

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

359

Приложение

F. SQL

сегодня

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

Временные таблицы.

В первом стандарте было выделено два типа таблиц: по­

стоянные базовые таблицы
цы

-

(base

taЫes) и представления

это основные (базовые) данные, а представления

виртуальные таблицы

(virtual
-

запросов. Оба типа таблиц

taЫes)

-

(views).
-

Базовые табли­

это, так называемые,

таблицы, выводимые из базовых с помощью

постоянные, хотя содержимое представления не опре­

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

базовых таблиц. Два из них (глобальные временные таблицы и созданные локаль­
ные временные таблицы) имеют, подобно представлениям, постоянные определе­

ния, как объекты в схеме, но их содержимое постоянно не хранится в базе данных.
Третий вид

-

локальные временные таблицы не имеет даже постоянно хранящего­

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

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

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

Встроенные операторы
стью предложения

JOIN.
Способность выполнять соединения является ча­
SELECT, но ранее не было механизмов встраивания SQL в авто­

матически генерируемые соединения различных типов. При определении множества

таблиц (или многократных вхождений одной и той же таблицы) в предложении

FROM

для запроса, предполагающего соединение, считается, что в оставшейся части

предложения определен тип соединения, который нужно выполнить. Например, но­
вый стандарт имеет встроенные операторы для получения соединения следующих
типов:

Cross

Это декартово произведение

-

все возможные комбинации

строк, входящих в соединенные таблицы.

Natural

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

более общем виде, как эквисоединение (соединение по равенст­
ву, по совпадению) двух или более таблиц для случая

360

SQL

сегодня

совпадения значений из столбцов, имеющих одинаковые имена.
(Эквисоединение

-

наиболее общий тип, это любое соедине­

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

дует за родительским. В противном случае можно просто полу­
чить естественное соединение.

Inner (outer)

Это такое эквисоединение таблиц А и В, при котором каждая
строка, представленная в одной таблице, имеет

соответствующую строку в другой таблице.

Left (outer)

Включает все строки из таблицы А, независимо от того, сопос­
тавимы они или нет, плюс все сопоставимые значения из В,
если это возможно. Несовпадающие строки помечаются как

NULL.

В общем случае слово

"outer"

является необязательным

и определяет, что несовпавшие строки представлены наряду с
совпавшими.

Right (outer)

Соединение, противоположное

Left:

все строки из таблицы В

представлены в конъюнкции с любой сопоставимой строкой
из А.
Комбинация левого и правого соединений. Все строки для каж­

Full

дой из таблиц представлены на основании того, что совпадение
было обнаружено.

Объединяющее соединение противоположное внутреннему со­

Union

единению

-

оно включает только те строки из каждой табли­

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

объединяющее соединение совпадает с левым. (Не путать объе­
диняющее соединение с оператором объединения

UNION,

ис­

пользуемым для объединения выходных данных множества
запросов).
Все указанные типы соединений поддерживаются специальными операторами в
предложениях запросов

Курсоры типа
Курсор

-

FROM.

READ-ONLY, SCROLLABLE,

INSENSIТIVE,

DYNAMIC.

это объект, используемый для хранения выходных данных запроса на об­

работку для приложения. В стандарте

SQL 89

курсор был обновляемым в принципе,

то есть не существовало серии правил и предложений, защищающих от обновлений.

Теперь можно объявить его

"read-only"

(только для чтения). Помимо расширения сек-

361

Приложение

F. SQL

сегодня

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

Sensitivity

(чувствительность) должна выполняться для того, чтобы отразить в

курсоре внешние изменения данных, поскольку курсор транслирует операцию

a-time

в операцию

item-at-a-time,

set-at-

обычную для языков программирования. Другими

словами, курсор может быть открыт, а затем прочитан (вызван) постепенно. Это дает
возможность изменять данные, на которые указывает курсор, в то время, когда они

еще читаются. Что случается, если другое предложение изменяет данные, которые

еще читаются открытым курсором? В соответствии со старым стандартом, ответ мог

быть только один "Знает только бог!" Согласно же стандарту
курсор нечувствительньш

(insensitive),

SQL 92,

можно объявить

и в этом случае он будет полностью игнориро­

вать внешний мир. Нечувствительными могут быть только курсоры

read-only.

Нынеш­

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

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

(saoll).

В общем случае

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

Последнее расширение концепции курсора
динамического языка

SQL,

-

динамические курсоры т.е. курсоры

которые не поддерживались в предыдущем стандарте. В

таком языке заранее неизвестно, какой запрос должен содержать курсор, поэтому со­

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

само имя курсора можно сделать переменным, используя предложение

CURSOR

вместо обычного

DECLARE CURSOR,

ALLOCATE

поэтому вы не должны знать зара­

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

Ориентация клиент/сервер.

Новый стандарт позволяет управлять связями, рас­

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

(client),

(''Ьack-end"), расположенной

(server).

(front-end)

на одном компьютере,

который пытается извлечь информацию из СУБД

на другом

компьютере, называемом

Много новых средств, относящихся к стандартизации процедур связи, схем

запирания и диагностики ошибок было мотивировано желанием клиентов единооб­
разно взаимодействовать с множеством СУБД и на множестве серверов.

362

SQL

Что такое архитектура клиент/сервер?

сегодня

В архитектуре клиент/сервер множест­

во компьютеров объединено в сеть, в которой все компьютеры подразделяются на
клиентов и серверов. Пользователи непосредственно взаимодействуют с клиентами

для выполнения большей части функций конечного пользователя. Серверы вьшолня­
ют различные интенсивные задания в ответ на запросы клиентов. СУБД обычно раз­

мещается на сервере и занимается обслуживанием требований клиентов.
соответствует таким

соглашениям,

поскольку,

являясь

SQL

декларативным

хорошо

языком,

он

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

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

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

и сети используются. Стандарт

92

определяет, что такое SQL-связь и содержит не­

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

SQL 92,

как и его предшественник, является функциональной спецификацией, прием­

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

миникомпьютеров и

mainframe

компьютеров.

Более сложное управление транзакциями.

ных предложений

SQL,

Транзакция

-

это группа правиль­

которые могут выполняться или не выполняться все вместе.

Ошибка в транзакции приводит к тому, что вся последовательность операций может

быть отменена

(canceled)

или для нее может быть выполнен откат

("rolled back").

СУБД автоматически начинает транзакцию всякий раз, когда применяется предложе­
ние, вызывающее ее выполнение, при условии, что никакая друтая транзакция не яв­

ляется активной. Транзакции заканчиваются предложением СОММIТ WORК (для
того чтобы сохранить изменения) или предложением

ROLLBACK

(при отказе от вне­

сения изменений или в случае сбоя или разъединения системе). Если транзакция не
может быть восстановлена, то следует выполнить ее откат;

ROLLBACK

никогда не

выполняется ошибочно.

Все это учитывалось в стандарте

86.

В стандарте

SQL 92 новым является следую­

щее:



Транзакция может быть определена "только для чтения"

(read

опlу). Это означа­

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

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

363

Приложение

F. SQL

сегодня

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



Нужно сохранять проверку ограничений до конца транзакции и можно ука­
зывать желаемые ограничения. Ограничения управляют содержимым базы
данных.



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



Транзакции могут специфицировать размер области диагностики для предложе­
ний внутри транзакции.

Уровни изоляции.

Предшествующий стандарт предполагал управление транзак-

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

тельностью, но теперь в

осуществлена некоторая стандартизация. Системы имеют

ISO

четыре уровня изоляции транзакций:

READ REPEAТABLE,

READ

UNCOММIТTED,

READ

СОММIТТЕD,

SERIALIZAВLE. Кроме того, можно определить, что транзакция

является "только для чтения"

(read-only}, а для

уровня изоляции

READ UNCOMMITTED

это необходимо.
Привилегии владельца уровня приложения.

Действия, выполняемые на базе

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

SQL

или

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

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

SQL,

могут в значительной степени регламентировать

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

продукты предполагают привилегии на владение приложением

(application-owned},

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

того, что модульный подход применяется, по-видимому, чаще других. Тем не менее

SQL 92 еще не поддерживает application-owned привилегии для встроенного или дина­
мического SQL. Для однопользовательского SQL привилегии, ориентированные на
приложение, несущественны. Поэтому они являются необязательными для языков

364

SQL

сегодня

программирования. Могут также существовать пользователи, выполняющие приложе­

ния с персональными привилегиями. Эта ситуация относится к классу "либо-либо".
Не может быть пользователей, выполняющих приложения с комбинацией их собст­
венных привилегий и привилегий приложения.
Процедура стандартного связывания.

В предыдущем стандарте связь

SQL-

предложения с идентификатором пользователя определялась конкретной реализаци­
ей. Идентификаторы пользователей имеют привилегии. при выполнении определен­
ных предложений, и, если пользователи создают объекты (такие как таблицы) то
получают право управления этими объектами. Они понятны пользователям, хотя
стандарт об этом явно не говорит. С точки зрения СУБД или операционной системы,

"пользователь" может не иметь соответствия один к одному с каким-либо другим
пользователем или пользователями реального мира. В некоторых коммерческих про­

граммных продуктах единственный идентификатор пользователя применяется не­
сколькими реальными пользователями или отдельные пользователи могут иметь по

несколько идентификаторов. Способ распознавания идентификатора пользователя
СУБД

-

процедура связи

-

обычно рассматривается только на уровне конкретной

реализации.

Стандарт

SQL 92

уточняет способ связи пользователей с СУБД непосредствен­

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

SET

CONNECТION. Совпадающие связи являются

частью той же транзакции. Таким образом новый, стандарт ориентирован на мир
клиент/сервер.
При использовании статического

SQL в

модульном языке программирования мож­

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

Каталог

(catalog)

в новом стандарте рас­

сматривается как набор схем. Он содержит информационную схему (Informatioп_

Schema),

которая представляет собой множество таблиц, описывающих содержимое

схем: какие столбцы в каких таблицах содержатся, какие представления определены,
какие привилегии связаны с каждым идентификатором пользователя и т.д. В ряде
коммерческих продуктов некоторые из этих таблиц получили название "каталог".
Стандартная информационная схема, определенная

SQL 92,

разрешает как пользова­

телям, так и приложениям применять одни и те же процедуры для получения инфор­

мации о любой схеме для любой СУБД, доступной для них.
Стандартные коды ошибок и диагностики.

На предшествующих этапах разви­

тия

SQL информация о результате SQL-операции передавалась через переменную число­
вого типа SQLCODE. Значение этой переменной устанавливается автоматически после

365

Приложение

F. SQL

выполнения

сегодня

каждого

предложения ДJIЯ определения,

что

произоrшю

при

выполнении

предложения. Предусмотрены три возможные ситуации:



Значение О определяет успешное завершение.



Значение

100 определяет,

что предложение выполнилось правильно, но не про­

извело никаких действий или не создало выходных данных. Например, если нет

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



SQLCODE

принима­

100.

Любое отрицательное значение свидетельствует об ошибке.

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

SQLCODE

поддерживается

для обеспечения совместимости "снизу вверх" в существующих программных продук­

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

SQLSTATE.

Это текстовая строка длиной в пять символов со стандартными значения­

ми для различных классов ошибок, ошибочных ситуаций, зависящих от конкретной

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

GET

DIAGNOSТICS.

Поддержка динамического

SQL.

Динамический

мый во время выполнения приложений,

-

SQL -

код

SQL,

генерируе-

специально не поддерживался в старом

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

SQL

в стандарте

92

являются динамические курсоры, предложения, генерируемые из

строк текста во время выполнения, области диагностики и области описания. Очень
важны также новые возможности связи.

Поддержка для С,

ADA

и

MUMPS.

только основной язык, но не встроенный

366

Официальный стандарт

SQL, хотя

86

поддерживал

и содержал четыре добавления, оп-

SQL

сегодня

ределяющие встроенный SQL для Pascal, Fortran, COBOL, PL/l. В стандарт 92 добавле­
ны· С, Ada, MUMPS и теперь все языки являются частью официального стандарта.
Домены.

Теоретики реляционной модели данных, и среди них

E.F.Codd (domains),

теории реляционных баз данных, стимулируют применение доАtенов

отец

исхо­

дя из того, что тип данных должен определяться более точно, чем это позволяет сде­

лать стандарт множества типов данных.

Например, тип номеров телефонов

отличается от типа номеров в кодах секретности. Хотя оба типа являются числовы­
ми, не имеет смысла непосредственно сравнивать эти значения, так как они опреде­
лены

на различных доменах.

SQL 92 разрешает

пользователям создавать домены как объекты в схеме, а затем оп­

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

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

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

Ограничения

-

это правила, устанав­

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

в определения базовых таблиц были включены ограничения двух видов:

ограничения на столбцы и ограничения на таблицы. Первые были частями определе­
ния столбца и контролировали предложения ориентированные на вставку или изме­
нение

значения

следовательно,

в

столбце,

могли

а вторые

содержать

правила,

-

частью

определения

используемые

для

таблицы

контроля

и,

множества

столбцов таблицы. В обоих случаях ограничения могли быть либо определенного, за­
ранее известного типа, например, NOT NULL или UNIQUE, либо СНЕСК­
ограничениями, позволявшими создателю таблицы генерировать выражения значе­
ний из столбцов. Если выражение принимало значение

FALSE,

то ограничение не

удовлетворялось и предложение отвергалось.

Новый стандарт дает возможность определять утверждения

(assertions) -

огра­

ничения, которые существуют как независимые объекты в схеме, а не в таблице. Это
значит, что они могут ссылаться на множество таблиц и на выражения, содержащие
значения из этих таблиц. Их можно использовать для того, чтобы удостовериться в
том, что таблица никогда не является пустой. Утверждения позволяют формулиро­
вать основные принципы, которым должны удовлетворять данные, например, кон­

тролировать законность выполнения операций. Утверждения могут создаваться и

удаляться. Можно также размещать ограничения в домене (см. раздел "Домены" дан­
ной главы).

367

Приложение

F. SQL

сегодня

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

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

утверждения будут обозначаться одним термином ограничения

(constraitions) ,

если

явно не оговорено нечто иное). Это может привести к некоторой неоднозначности. Ог­
раничения проверяются в любом из следующих случаев:

1.

После выполнения каждого предложения, воздействующего на таблицу, на кото­
рую есть ссылка в предложении.

2.

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

3.

Всякий раз в тот момент, когда пользователь или приложение решают, что эту

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

завершения выполнения транзакции. Если выбран второй вариант, то можно уточнить,
какой режим проверки принимается по умолчанию. Затем, на протяжении выполнения

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

(constraints mode).

(Неотсроченные ограничения, по определению, должны проверять­

ся немедленно.) Можно установить способ проверки сразу для всех ограничений или
для каждого отдельно. Если установить вид ограничений в значение lmmediate, то они
будут проверяться немедленно. Это полезно делать в случаях, упомянутых в пункте 3
приведенного описания процедуры управления.

Существует ряд моментов, которые необходимо учесть в том случае, если ограни­

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

первую. Предположим, каждый внешний ключ содержит ограничение

- на
NOT NULL.

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

нения целостности, поскольку родительский ключ отсутствует в другой таблице непо­
средствен но после выполнения операции вставки. Это пример цикличности
(ciгcиlaгity). Решение должно отличаться от проверки ограничения

FOREIGN

КЕУ до

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

можно потерять сведения о действиях, которые были выполнены в процессе транзак­
ции. Если детали этого процесса неважны, то можно сохранять последовательность

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

368

SQL

Добавление и удаление объектов.

Согласно стандарту

SQL 86,

сегодня

однажды соз­

данную таблицу нельзя изменить или удалить. В реальной жизни возникают ситуа­
ции,

когда следует изменить содержимое созданной таблицы или вовсе от нее

отказаться. Поэтому предложения

AL TER ТABLE и DROP ТABLE вошли в стандарт
CREATE Т ABLE по спецификации OSI. К сожалению эти предло­
жения, из которых наиболее сложным является ALTER, не всегда выполнялись оди­
наково для различных программных продуктов. Однако теперь OSI решил сделать
AL TER и DROP частью стандарта.

де-факто, наряду с

Можно изменять не только таблицы, но и все объекты: утверждения, домены, схе­

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

ALTER TABLE позволяет

добавлять, изменять и удалять правила умолчания или ограничения, а также добав­
лять или удалять столбцы.
Отмена и использование привилегий.

Привилегии

-

это то, что дает иденти­

фикатору пользователя право выполнять действия на различных объектах базы дан­
ных. По старому стандарту нельзя было лишиться однажды полученных привилегий.
Однако разработчики программных продуктов ввели предложение REVOКE, отме­
няющее привилегии, переданные по команде

стью стандарта

SQL 92.

GRANT.

Теперь REVOКE является ча­

Оно относится к чис.1у сложных предложений, прежде всего

из-за необходимости прослеживать путь передачи привилегий от одного идентифика­
тора пользователя к другому.

Предложение

GRANT

можно применять также с привилегией

USAGE,

чтобы от­

крыть доступ к любому новому из числа возможных объектов схемы: к доменам, объе­
динениям, наборам символов, способам трансляции.

USAGE

применимо только к

этим новым объектам схемы, тогда как другие привилегии относятся только к базовым

таблицам и представлениям.
перь и со столбцами.
столбца

SELECT

ISO

INSERT же определено

по-новому: оно употребляется те­

предполагает разработать специфицированный на уровне

в следующем стандарте, именно для этого предусмотрено место в

Iпfonnation_Schema (информационной_схеме). Но в настоящее время эта заброниро­
ванная в стандарте возможность не используется.

Определенные пользователем наборы символов, сравнения и трансляции.
Возможность поддержки разных наборов символов (национальных алфавитов) де­
лает

SQL 92

действительно стандартом мирового сообщества. Новый стандарт по­

зволяет разработчикам

и

пользователям

проявлять большую гибкость

определении их собственных наборов символов.

в

Теперь символы не обязаны

иметь длину в один байт, как это было принято для символов английского языка,
они могут иметь различную длину, но обязательно должны быть упорядочиваемы­

ми. Для них должна быть определена такая последовательность сравнения (упоря­
дочения), при которой предложение типа