0% нашли этот документ полезным (0 голосов)
732 просмотров

SQL Without Assistance

Загружено:

coolaidman
Авторское право
© Attribution Non-Commercial (BY-NC)
Доступные форматы
Скачать в формате PDF, TXT или читать онлайн в Scribd
0% нашли этот документ полезным (0 голосов)
732 просмотров

SQL Without Assistance

Загружено:

coolaidman
Авторское право
© Attribution Non-Commercial (BY-NC)
Доступные форматы
Скачать в формате PDF, TXT или читать онлайн в Scribd
Вы находитесь на странице: 1/ 287

SAMS

Освой
самостоятельно

уро
SAMS

T e a c h
Y o u r s e l f

Ben Forta

THIRD EDITION

SAMS 800 East 96th Street, Indianapolis, Indiana, 462


SAMS
Освой
самостоятельно

Бен Форта

уро
3-е издание

Издательский дом "Вильяме"


Москва • Санкт-Петербург • Киев
2005
ББК 32.973.26-018.2.75
Ф80
УДК 681.3.07

Издательский дом "Вильяме"


Главный редактор С.Н. Тригуб
Зав. редакцией В.Р. Гинзбург
Перевод с английского и редакция B.C. Гусева
По общим вопросам обращайтесь в Издательский дом "Вильяме" по адресу:
[email protected], http://www.williamspublishing .com
115419, Москва, а/я 783, 03150, Киев, а/я 152.

Форта, Бен.
Ф80 Освой самостоятельно SQL. 10 минут на урок, 3-е издание. :
Пер. с англ. — М. : Издательский дом "Вильяме", 2005. —
288 с. : ил. — Парал. тит. англ.
ISBN 5-8459-0827-2 (рус.)
Данная книга поможет вам в кратчайшие сроки освоить
SQL — самый популярный язык баз данных. Начиная с простых
запросов на выборку данных, автор урок за уроком рассматрива-
ет все более сложные темы, такие как использование операций
объединения, подзапросы, хранимые процедуры, индексы, триг-
геры и ограничения. На изучение материала каждого урока вам
потребуется не более 10 минут. Благодаря этой книге вы быстро
научитесь самостоятельно составлять запросы к базам данных на
языке SQL без чьей-либо помощи.
Примеры, приведенные в книге, будут работать во всех наи-
более популярных СУБД — IBM DB2, Microsoft Access, Microsoft
SQL Server, MySQL, Oracle, PostgreSQL и Sybase Adaptive Server.
ББК 32.973.26-018.2.75
Все названия программных продуктов являются зарегистрированными торго-
выми марками соответствующих фирм.
Никакая часть настоящего издания ни в каких целях не может быть воспроиз-
ведена в какой бы то ни было форме и какими бы то ни было средствами, будь то
электронные или механические, включая фотокопирование и запись на магнитный
носитель, если на это нет письменного разрешения издательства Sams Publishing.
Authorized translation from the English language edition published by Sams
Publishing Copyright © 2004
All rights reserved. No part of this book may be reproduced or transmitted in
any form or by any means, electronic or mechanical, including photocopying,
recording or by any information storage retrieval system, without permission from
the Publisher.
Russian language edition is published by Williams Publishing House according
to the Agreement with R&I Enterprises International, Copyright © 2005

ISBN 5-8459-0827-2 (рус.) © Издательский дом "Вильяме", 2005


ISBN 0-672-32567-5 (англ.) © Sams Publishing, 2004
Оглавление
Введение 15
Урок 1. Что такое SQL 19
Урок 2. Выборка данных 29
Урок 3. Сортировка выбранных данных 35
Урок 4. Фильтрация данных 43
Урок 5. Расширенная фильтрация данных 51
Урок 6. Использование метасимволов для фильтрации 61
Урок 7. Создание вычисляемых полей 69
Урок 8. Использование функций манипулирования данными 79
Урок 9. Суммирование данных 89
Урок 10. Итоговые данные 101
Урок 11. Использование подзапросов 113
Урок 12. Объединение таблиц 121
Урок 13. Создание расширенных объединений 133
Урок 14. Комбинированные запросы 145
Урок 15. Добавление данных 153
Урок 16. Обновление и удаление данных 163
Урок 17. Создание таблиц и работа с ними 169
Урок 18. Использование представлений 181
Урок 19. Работа с хранимыми процедурами 193
Урок 20. Обработка транзакций 203
Урок 21. Использование курсоров 211
Урок 22. Расширенные возможности SQL 219
Приложение А. Сценарии демонстрационных таблиц 235
Приложение Б. Работа с популярными приложениями 243
Приложение В. Синтаксис операторов SQL 259
Приложение Г. Использование типов данных SQL 265
Приложение Д. Зарезервированные слова SQL 273
Предметный указатель 278
Содержание
Об авторе
Благодарности
Ждем ваших отзывов!
Введение
Для кого эта книга?
СУБД, используемые в этой книге
Условные обозначения
Урок 1. Что такое SQL
Основы баз данных
Что такое база данных
Таблицы
Столбцы и типы данных
Строки
Первичные ключи
Что такое SQL?
Попробуйте сами
Резюме
Урок 2. Выборка данных
Оператор SELECT
Выборка отдельных столбцов
Выборка нескольких столбцов
Выборка всех столбцов
Резюме
Урок 3. Сортировка выбранных данных
Сортировка данных
Сортировка по нескольким столбцам
Сортировка по положению столбца
Указание направления сортировки
Резюме
Урок 4. Фильтрация данных
Использование предложения WHERE
Операции в предложении WHERE
Проверка одного значения
Проверка на несовпадения
Проверка на диапазон значений
Проверка на отсутствие значения
Резюме
Содержание 7

Урок 5. Расширенная фильтрация данных 51


Комбинирование предложений WHERE 51
Использование ключевого слова AND 52
Использование ключевого слова OR 53
Порядок обработки 54
Использование ключевого слова IN 56
Использование ключевого слова NOT 57
Резюме 59
Урок 6. Использование метасимволов для фильтрации 61
Использование логического оператора LIKE 61
Метасимвол "знак процента" (%) 62
Метасимвол "символ подчеркивания" (_) 65
Метасимвол "квадратные скобки" ([ ]) 66
Советы по использованию метасимволов 68
Резюме 68
Урок 7. Создание вычисляемых полей 69
Что такое вычисляемые поля 69
Конкатенация полей 70
Использование псевдонимов 74
Выполнение математических вычислений 76
Резюме 78
Урок 8. Использование функций манипулирования данными 79
Что такое функция 79
Проблемы с функциями 79
Использование функций 81
Функции манипулирования текстом 82
Функции манипулирования датой и временем 84
Функции для манипулирования числами 87
Резюме 88
Урок 9. Суммирование данных 89
Использование статистических функций 89
Функция AVG () 90
Функция COUNT () 92
Функция МАХ () 93
Функция MIN () 94
Функция SUMO 95
Статистические вычисления для отдельных
значений 96
Комбинирование статистических функций 98
Резюме 99
8 Содержание

Урок 10. Итоговые данные 101


Получение итоговых данных 101
Создание групп 102
Фильтрующие группы 104
Группирование и сортировка 108
Упорядочение предложения SELECT 110
Резюме 111
Урок 11. Использование подзапросов 113
Что такое подзапросы 113
Фильтрация посредством подзапросов 114
Использование подзапросов в качестве
вычисляемых полей 118
Резюме 120
Урок 12. Объединение таблиц 121
Что такое объединения 121
Что такое реляционные таблицы 121
Для чего используют объединения 123
Создание объединения 124
Важность предложения WHERE 126
Внутренние объединения 128
Объединение многих таблиц 129
Резюме 132
Урок 13. Создание расширенных объединений 133
Использование псевдонимов таблиц 133
Использование объединений других типов 134
Самообъединения 135
Естественные объединения 137
Внешние объединения 138
Использование объединений со статистическими
функциями 142
Использование объединений и условий
объединения 143
Резюме 144
Урок 14. Комбинированные запросы 145
Что такое комбинированные запросы 145
Создание комбинированных запросов 146
Использование оператора UNION 146
Правила применения запросов UNION 149
Включение или исключение повторяющихся
строк 150
Содержание 9

Сортировка результатов комбинированных


запросов 151
Резюме 152
Урок 15. Добавление данных 153
Что такое добавление данных 153
Добавление полных строк 153
Добавление части строки 157
Добавление выбранных данных 158
Копирование данных из одной таблицы в другую 160
Резюме 162
Урок 16. Обновление и удаление данных 163
Обновление данных 163
Удаление данных 165
Советы по обновлению и удалению данных 167
Резюме 168
Урок 17. Создание таблиц и работа с ними 169
Создание таблиц 169
Основы создания таблиц 170
Работа со значениями NULL 172
Определение значений по умолчанию 174
Обновление таблиц 176
Удаление таблиц 178
Переименование таблиц 179
Резюме 179
Урок 18. Использование представлений 181
Что такое представления 181
Для чего используют представления 182
Представления: правила и ограничения 183
Создание представлений 185
Использование представлений для упрощения
сложных объединений 186
Использование представлений для
переформатирования выбранных данных 187
Использование представлений для фильтрации
нежелательных данных 190
Использование представлений с вычисляемыми
полями 191
Резюме 192
Урок 19. Работа с хранимыми процедурами 193
Что такое хранимые процедуры 193
Для чего используют хранимые процедуры 195
10 Содержание

Выполнение хранимых процедур 197


Создание хранимых процедур 198
Резюме 202
Урок 20. Обработка транзакций 203
Что такое обработка транзакций 203
Управляемые транзакции 206
Использование оператора ROLLBACK 207
Использование оператора COMMIT 207
Использование точек сохранения 208
Резюме 210
Урок 21. Использование курсоров 211
Что такое курсоры 211
Работа с курсорами 213
Создание курсоров 214
Использование курсоров 215
Закрытие курсоров 217
Резюме 217
Урок 22. Расширенные возможности SQL 219
Что такое ограничения 219
Первичные ключи 220
Внешние ключи 222
Ограничения уникальности 224
Ограничения на значения столбца 225
Что такое индексы 227
Что такое триггеры 229
Безопасность баз данных 231
Резюме 232
Приложение А. Сценарии демонстрационных таблиц 235
Что такое демонстрационные таблицы 235
Описания таблиц 236
Таблица Vendors 236
Таблица Products 237
Таблица Customers 237
Таблица Orders 238
Таблица Orderltems 238
Получение демонстрационных таблиц 239
Загрузка готового к работе MDB-файла для
Microsoft Access 240
Загрузка SQL-сценариев СУБД 240
Приложение Б. Работа с популярными приложениями 243
Использование Aqua Data Studio 244
Содержание 11

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


Использование Macromedia ColdFusion 245
Использование Microsoft Access 246
Использование Microsoft ASP 248
Использование Microsoft ASP.NET 249
Использование Microsoft Query 250
Использование Microsoft SQL Server 251
Использование MySQL 252
Использование Oracle 252
Использование PHP 253
Использование PostgreSQL 253
Использование Query Tool 254
Использование Sybase 255
Конфигурирование источников данных ODBC 255
Приложение В. Синтаксис операторов SQL 259
ALTER TABLE 259
COMMIT 260
CREATE INDEX 260
CREATE PROCEDURE 260
CREATE TABLE 261
CREATE VIEW 261
DELETE 261
DROP 262
INSERT 262
INSERT SELECT 262
ROLLBACK 262
SELECT 263
UPDATE 263
Приложение Г. Использование типов данных SQL 265
Строковые данные 266
Числовой тип данных 268
Типы данных даты и времени 269
Двоичные типы данных 270
Приложение Д. Зарезервированные слова SQL 273
Предметный указатель 278
Об авторе
Бен Форта — главный технический специалист компа-
нии Macromedia, за его плечами 20 лет работы в компью-
терной индустрии, включая разработку продуктов, их под-
держку и распространение, а также обучение пользованию
ими. Бен Форта — автор таких бестселлеров, как ColdFu-
sion Web Application Construction Kit и Advanced ColdFusion
Development, Sams Teach Yourself Regular Expressions in
10 Minutes (Освой самостоятельно регулярные выражения.
10 минут на урок, Издательский дом "Вильяме"), а также
книг по Flash, Java, WAP, Windows 2000 и другим техно-
логиям. У него огромный опыт в разработке баз данных, он
обеспечил их поддержку в нескольких очень популярных
программных пакетах. Он часто читает лекции и пишет
статьи для Internet, посвященные технологиям баз данных.
Бен родился в Лондоне, там же получил образование, затем
учился в Нью-Йорке и Лос-Анджелесе. Сейчас он живет в
г. Оук-Парк, штат Мичиган, со своей женой Марси и семью
детьми. Бену можно написать по адресу [email protected] и
посетить его Web-узел по адресу h t t p : //www. f o r t a. com.
Благодарности
Спасибо команде из Sams за многолетнюю поддержку.
Особую благодарность хочу выразить Майку Стивенсу (Mike
Stephens) и Марку Ренфроу (Mark Renfrow) за то, что они
провели это новое издание книги от идеи до реальности
(при этом иногда им приходилось вести и меня самого).
Спасибо читателям, которые написали отзывы по пер-
вым двум изданиям этой книги. К счастью, большинство из
этих отзывов были положительными, и все они были оце-
нены. Улучшения и изменения в этой редакции были сде-
ланы именно благодаря вашим замечаниям.
И наконец, благодарю всех, кто приобрел предыдущие
издания этой книги. Книга стала не только лично моим бест-
селлером, но и бестселлером по данной теме. Ваша постоян-
ная поддержка — наилучшая благодарность, которую заслу-
живает автор.
Ждем ваших отзывов!
Вы, читатель этой книги, и есть главный ее критик и
комментатор. Мы ценим ваше мнение и хотим знать, что
было сделано нами правильно, что можно было сделать
лучше и что еще вы хотели бы увидеть изданным нами.
Нам интересно услышать и любые другие замечания, кото-
рые вам хотелось бы высказать в наш адрес.
Мы ждем ваших комментариев и надеемся на них. Вы
можете прислать нам бумажное или электронное письмо
либо просто посетить наш Web-сервер и оставить свои заме-
чания там. Одним словом, любым удобным для вас спосо-
бом дайте нам знать, нравится вам эта книга или нет, а
также выскажите свое мнение о том, как сделать наши
книги более интересными для вас.
Посылая письмо или сообщение, не забудьте указать на-
звание книги и ее авторов, а также ваш обратный адрес.
Мы внимательно ознакомимся с вашим мнением и обяза-
тельно учтем его при отборе и подготовке к изданию после-
дующих книг. Наши координаты:
E-mail: inf o@williamspublishing. com
WWW: h t t p : //www. williamspublishing. com
Адреса для писем:
из России: 115419, Москва, а/я 783
из Украины: 03150, Киев, а/я 152
Введение
SQL является самым популярным языком баз данных.
Не важно, кто вы — разработчик приложений, админист-
ратор баз данных, Web-дизайнер или пользователь пакета
Microsoft Office, — хорошее практическое знание SQL по-
может вам взаимодействовать с базами данных.
Эта книга была написана из необходимости. Несколько
лет я вел курс по разработке Web-приложений, и студенты
постоянно просили порекомендовать им книгу по SQL. Су-
ществовало много книг, посвященных данной теме, и неко-
торые из них действительно были очень хороши. Но всем
им было присуще одно общее свойство: в них было слиш-
ком много информации для большинства пользователей.
Вместо того чтобы раскрывать тему SQL, в большинстве
книг излагалось все, от разработки баз данных до теории
реляционных баз данных и администрирования. Хотя это
очень важные темы, они не интересны большинству людей,
которые просто хотят изучить SQL.
Итак, не найдя ни одной книги, которую я бы мог поре-
комендовать, я вложил весь опыт преподавания в книгу,
которую вы держите в руках. Данная книга поможет вам
быстро освоить SQL. Начнем мы с простой выборки дан-
ных, затем перейдем к более сложным темам, таким как
использование операций объединения, подзапросы, храни-
мые процедуры, индексы, триггеры и ограничения. Обуче-
ние будет проходить методично, систематично и просто —
на каждый урок вам потребуется не более 10 минут.
Третья редакция этой книги уже помогла изучить SQL
сотням тысяч пользователей, теперь пришел ваш черед.
Переходите к первому уроку и приступайте к работе. Вы
быстро научитесь писать первоклассные SQL-запросы.

Для кого эта книга


Эта книга для вас, если вы
• новичок в SQL;
• хотите быстро научиться использовать SQL;
• хотите научиться использовать SQL в разрабатывае-
мых вами приложениях;
• хотите самостоятельно составлять запросы к базам
данных на SQL без чьей-либо помощи.
16 Введение

СУБД, используемые в этой


книге
В большинстве случаев SQL, который описывается в
этой книге, можно применять в любой системе управления
базой данных (СУБД, Database Management System —
DBMS). Однако, так как не все реализации SQL идентичны,
в книге особенно внимательно будут рассмотрены следую-
щие СУБД (при необходимости будут даваться специальные
инструкции или примечания).
• IBM DB2
• Microsoft Access
• Microsoft SQL Server
• MySQL
• Oracle
• PostgreSQL
• Sybase Adaptive Server
Примеры баз данных и SQL-сценарии будут работать во
всех этих СУБД.

Условные обозначения
В этой книге используются различные шрифты — во-
первых, для того чтобы можно было отличить код от обыч-
ного текста, во-вторых, чтобы вы не пропустили важные
понятия.
Текст, который вы вводите, и текст, который должен поя-
виться на экране, представлены моноширинным шрифтом.
Он выглядит так, как на вашем экране.
Переменные и выражения-аргументы приведены
моноширинным курсивным шрифтом. Переменный аргумент
необходимо заменять определенным значением, которое он
представляет.
Такая стрелка (*Ь) в начале строки кода означает, что
эта строка слишком длинная и не поместилась в одну стро-
ку книги. Продолжайте вводить все символы после символа
^> так, как если бы они были частью предыдущей строки.
Введение 17

В примечаниях находится интересная информация,


относящаяся к обсуждаемой теме.

ш В подсказке вы найдете полезный совет или более


быстрый способ что-либо выполнить.

В предупреждении вы узнаете о возможных пробле-


мах и научитесь избегать неприятных ситуаций.

Под данной пиктограммой вы найдете определения


новых базовых понятий.

ВВОД
Пиктограммой "Ввод" обозначен код, который вы може-
те ввести самостоятельно.
ВЫВОД
Пиктограмма "Вывод" указывает на информацию, кото-
рая выдается после запуска программы.
Анализ
Пиктограмма "Анализ" указывает на то, что далее сле-
дует пошаговый комментарий к коду.
Урок 1

Что такое SQL


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

Основы баз данных


Тот факт, что вы читаете книгу по SQL, говорит о том,
что вам так или иначе необходимо работать с базами дан-
ных. Язык SQL предназначен именно для этого, поэтому
перед тем, как перейти к его рассмотрению, очень важно,
чтобы вы познакомились с некоторыми основными поня-
тиями технологии баз данных.
Хотите вы этого или нет, но вы постоянно пользуетесь
базами данных. Каждый раз, когда вы выбираете имя в ад-
ресной книге электронной почты, вы используете базу дан-
ных. Если вы что-то ищете при помощи поискового сервера
в Internet, вы используете базу данных. Когда вы регистри-
руетесь в локальной сети на работе, вы вводите свое имя и
пароль, которые затем сравниваются со значениями, хра-
нящимися в базе данных. И даже когда вы используете
свою пластиковую карту в банкомате, вы используете базу
данных при проверке PIN-кода и остатка на счету.
Однако несмотря на то, что мы постоянно используем
базы данных, для многих остается непонятно, что же это на
самом деле такое. И происходит это отчасти потому, что
разные люди пользуются одними и теми же терминами, от-
носящимися к базам данных, для определения совершенно
разных вещей. Поэтому мы начнем наше обучение со спи-
ска определений наиболее важных терминов, относящихся
к базам данных.
20 Урок 1

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

Что такое база данных


Термин база данных используется в самых разных аспек-
тах, но мы (а тем более с точки зрения SQL) будем считать ба-
зу данных набором сведений, хранящихся некоторым упоря-
доченным способом. Проще всего рассматривать базу данных
как шкаф для хранения документов. Шкаф — это просто фи-
зическое местоположение для хранения данных, независимо от
того, что это за данные и как они упорядочены.

База данных
Контейнер (обычно файл или труппа файлов) для хра-
нения упорядоченных данных.

Неправильное использование приводит к путанице


Люди часто используют термин база данных для обо-
значения программного обеспечения базы данных.
Это неправильное использование термина часто ве-
дет к путанице. На самом деле программное обеспе-
чение баз данных называется системой управления
базами данных (СУБД). База данных— это хранили-
ще, созданное и управляемое посредством СУБД.
База данных может быть файлом, хранящимся на же-
стком диске, а может и не являться таковым. Но чаще
всего это несущественно, так как вы все равно нико-
гда не обращаетесь к базе данных напрямую, для
доступа к ней вы всегда используете СУБД.
Что такое SQL 21

Таблицы
Когда вы храните информацию в шкафу для докумен-
тов, вы стараетесь не перемешивать их. Напротив, все до-
кументы хранятся в соответствующих папках.
В мире баз данных такая папка называется таблицей.
Таблица — это структурированный файл, в котором могут
храниться данные определенного типа. В таблице может
находиться список клиентов, каталог продукции и любая
другая информация.

шг
, Таблица
• • • • • • " ' • - ' ' " " • • • . • • •

Структурированный список данных определенного


типа.

Ключевой момент заключается в том, что данные, хра-


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

Таблицы имеют характеристики и свойства, определяю-


щие, каким образом в них хранятся данные. Сюда включа-
ется информация о том, какие данные могут храниться,
как они распределены по таблицам, каким частям инфор-
мации присвоены имена и многое другое. Такой набор ин-
формации, описывающей таблицу, называется схемой. Схе-
мы используются для описания как определенных таблиц
22 Урок 1

в базе данных, так и для базы данных в целом (а также для


описания взаимосвязей (отношений) между таблицами, ес-
ли таковые имеются).
Схема
Информация о базе данных, компоновке и свойствах
таблицы.

Столбцы и типы данных


Таблицы состоят из столбцов, в которых находятся от-
дельные фрагменты информации таблицы.
Столбец
Одно поле таблицы. Все таблицы состоят из одного
или нескольких столбцов.

Чтобы лучше понять это, представьте себе таблицы базы


данных в виде сетки, наподобие электронных таблиц.
В каждом столбце этой сетки находится определенная часть
информации. Например, в таблице клиентов в одном столб-
це находится номер клиента, в другом — его имя. Адрес,
город, область, почтовый индекс — все это находится в от-
дельных столбцах.

Распределение данных
Очень важно правильно распределить данные по не-
скольким столбцам. Например, название города, об-
ласти (штата) и почтовый индекс (для США это ZIP-
код) всегда должны быть в отдельных столбцах. Это
позволяет отсортировать или отфильтровать данные
по определенным столбцам (например, чтобы найти
всех клиентов из определенной области или города).
Если названия города и области хранятся в одном
столбце, будет очень сложно отсортировать или от-
фильтровать данные по области.

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


ный тип данных, который определяет, какие данные могут
Что такое SQL 23

содержаться в этом столбце. Например, если в столбце со-


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

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

Типы данных ограничивают характер информации, ко-


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

Совместимость типов данных


Типы данных и их названия являются одним из основ-
ных источников несовместимости в SQL. Основные
типы данных обычно поддерживаются всеми СУБД, в
отличие от некоторых расширенных типов. Более то-
го, иногда вы будете сталкиваться с тем фактом, что
один и тот же тип данных в разных СУБД называется
по-разному. К сожалению, с этим ничего нельзя по-
делать, но помнить об этом при создании схем таблиц
необходимо.

Строки
Данные в таблице хранятся в строках; каждая запись
хранится в своей строке. Возвращаясь к сравнению с сет-
кой, можно сказать, что ее вертикальные столбцы являют-
ся столбцами таблицы, а горизонтальные строки — строка-
ми таблицы.
24 Урок 1

Например, в таблице клиентов информация о каждом


клиенте хранится в отдельной строке. Число строк в табли-
це равно числу записей о клиентах.
Строка
Запись в таблице.

Записи или строки?


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

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

Этот столбец (или набор столбцов), уникально иденти-


фицирующий каждую строку таблицы, называется первич-
ный ключ. Первичный ключ используется для определения
конкретной строки. Без него выполнять обновление или
удаление строк таблицы было бы очень затруднительно, так
как не было бы никакой гарантии, что мы изменяем нуж-
ные строки.
Что такое SQL 25

Всегда определяйте первичные ключи


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

Любой столбец таблицы может быть использован в каче-


стве первичного ключа, если выполняются следующие ус-
ловия.
• Две разные строки не могут иметь одно и то же зна-
чение первичного ключа.
• Каждая строка должна иметь определенное значение
первичного ключа (столбцы первичного ключа не мо-
гут иметь значения NULL).
• Значения в столбце первичного ключа не могут быть
изменены.
• Значения первичного ключа нельзя использовать
дважды. (Если строка удалена из таблицы, ее пер-
вичный ключ нельзя в дальнейшем назначать другим
строкам.)
В качестве первичного ключа обычно используется толь-
ко один столбец таблицы. Но это требование не обязательно
и в качестве первичного ключа можно использовать не-
сколько столбцов. При этом правила, приведенные выше,
должны выполняться для всех столбцов, используемых в
качестве первичного ключа, а все их значения должны
быть уникальными (в обычных столбцах значения могут
повторяться).
Существует еще один важный тип ключа, который на-
зывается внешний ключ, но к нему мы вернемся в уро-
ке 12, "Объединение таблиц".

Что такое SQL?


SQL — это аббревиатура выражения Structured Query
Language (язык структурированных запросов). SQL был спе-
циально разработан для взаимодействия с базами данных.
В отличие от других языков (разговорных, таких как
английский, или языков программирования, например Java
26 Урок 1

или Visual Basic), SQL состоит всего из нескольких слов. И


сделано это умышленно. SQL был создан для решения од-
ной задачи, с которой он вполне справляется, — предостав-
лять простой и эффективный способ считывания и записи
информации в базу данных.
Каковы же преимущества SQL?
• SQL не относится к числу патентованных языков, ис-
пользуемых разработчиками определенных баз дан-
ных. Почти все большие СУБД поддерживают SQL,
поэтому знание этого языка позволит вам взаимодей-
ствовать практически с любой базой данных.
• SQL легко изучить. Его немногочисленные операторы
состоят из простых английских слов.
• Несмотря на кажущуюся простоту, SQL является
очень мощным языком; разумно пользуясь его эле-
ментами, можно выполнять очень сложные операции
с базами данных.
Именно поэтому стоит изучить SQL.

Расширения SQL
Многие разработчики СУБД расширили возможности
SQL, введя в язык дополнительные операторы или
инструкции. Эти расширения необходимы для выпол-
нения дополнительных функций или для упрощения
выполнения определенных операций. И хотя часто
они очень полезны, эти расширения привязаны к оп-
ределенной СУБД и редко поддерживаются более
чем одним разработчиком.
Стандартный SQL поддерживается комитетом стан-
дартов ANSI, и соответственно называется ANSI SQL.
Все крупные СУБД и даже те, у которых есть собст-
венные расширения, поддерживают ANSI SQL. От-
дельные же реализации носят собственные имена
(PL-SQL, Transact-SQL и т.д.).
Чаще всего в этой книге упоминается именно ANSI
SQL. В редких случаях, когда используется SQL, отно-
сящийся к определенной СУБД, об этом говорится
отдельно,
Что такое SQL 27

Попробуйте сами
Подобно изучению любого другого языка, чтобы изучить
SQL, лучше всего попробовать его использовать на практи-
ке. Для этого вам понадобится база данных и приложение,
из которого можно выполнять SQL-запросы.
Во всех уроках этой книги используются настоящие SQL-
операторы и настоящие таблицы базы данных. В приложе-
нии А, "Сценарии демонстрационных таблиц", описываются
примеры таблиц и приводятся советы по их получению (или
созданию), чтобы можно было выполнять инструкции каж-
дого урока. В приложении Б, "Работа с популярными при-
ложениями", описываются действия, необходимые для за-
пуска SQL в различных приложениях. Перед тем как перей-
ти к следующему уроку, прочитайте эти два приложения,
чтобы подготовиться к дальнейшим действиям.

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

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

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

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

Чтобы при помощи оператора SELECT извлечь данные из


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

Рассматриваемые примеры
В примерах SQL-операторов (а также полученных с их
помощью результатов) в этой книге используются
файлы данных, описанные в приложении А, "Сцена-
рии демонстрационных таблиц". Если вы хотите са-
мостоятельно выполнить действия, указанные в при-
мерах (очень рекомендуем это делать), обратитесь к
30 Урок 2

приложению А, в котором вы найдете инструкции по


загрузке или созданию этих файлов.
Очень важно понимать, что SQL— это язык, а не при-
ложение. Метод ввода SQL-операторов и вывод ре-
зультатов их выполнения различен для разных прило-
жений. Чтобы помочь вам приспособить примеры к
вашей СУБД, в приложении Б, "Работа с популярными
приложениями" объясняется, как выполнять команды,
приведенные в этой книге, в нескольких популярных
программах и средах разработки. А если вам нужно
приложение, которое поможет вам выполнять приме-
ры, там же вы найдете рекомендации по его выбору.

Выборка отдельных столбцов


Начнем с простого SQL-оператора SELECT:

ВВОД
SELECT prod_name
FROM Products;

Анализ
В приведенном выше операторе используется оператор
SELECT для выборки одного столбца под названием
prod_name из таблицы Products. Искомое имя столбца
указывается сразу после ключевого слова SELECT, а ключе-
вое слово FROM указывает на имя таблицы, из которой вы-
бираются данные. Результат выполнения этого оператора
будет следующий:
ВЫВОД
prod_name
Fish bean bag toy
Bird bean bag toy
Rabbit bean bag toy
8 inch teddy bear
12 inch teddy bear
18 inch teddy bear
Raggedy Ann
King doll
Queen doll
Выборка данных 31

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

Простой оператор SELECT, который использовался в пре-


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

Завершение операторов
Несколько SQL-операторов должны быть разделены
точкой с запятой (символом ,-). В большинстве СУБД
не требуется вставлять точку с запятой после единст-
венного оператора, но если в вашем конкретном слу-
чае СУБД выдает ошибку, вам придется это делать.
Несомненно, при желании можно всегда добавлять
точку с запятой, она никому не будет мешать, даже
если этот символ не обязателен. Исключением явля-
ется СУБД Sybase Adaptive Server, которая "не любит"
SQL-операторы, заканчивающиеся символом ;.
32 Урок 2

SQL-операторы и регистр
Важно отметить, что SQL-операторы нечувствитель-
ны к регистру, поэтому операторы SELECT, s e l e c t и
S e l e c t эквивалентны. Многие SQL-разработчики ис-
пользуют верхний регистр для всех ключевых слов
SQL и нижний регистр для имен столбцов и таблиц,
чтобы код легче читался. Однако будьте внимательны:
SQL-операторы не зависят от регистра, в отличие от
имен таблиц, столбцов и значений (которые зависят
от СУБД и ее конфигурации).

Выборка нескольких столбцов


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

Будьте внимательны с запятыми


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

В следующем операторе SELECT из таблицы Products


выбираются три столбца:
ВВОД
SELECT prod_id, prod_name, prod_price
FROM Products;

Анализ
Как и в предыдущем примере, в этом операторе для вы-
борки данных из таблицы Products используется оператор
SELECT. В этом примере перечислены три имени столбца,
разделенные запятыми. Результат обработки этого операто-
ра показан ниже:
Выборка данных 33

вывод
prod id
1 prod_name prod_price

BNBG01 Fish bean bag toy- 3.4900


BNBG02 Bird bean bag toy 3 .4900
BNBG03 Rabbit bean bag toy 3 .4900
BR01 8 inch teddy bear 5.9900
BR02 12 inch teddy bear 8.9900
BR03 18 inch teddy bear 11.9900
RGAN01 Raggedy Ann 4.9900
RYL01 King doll 9.4900
RYL02 Queen doll 9.4900

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

Выборка всех столбцов


Помимо возможности осуществлять выборку определен-
ных столбцов (одного или нескольких), при помощи опера-
тора SELECT можно запросить все столбцы, не перечисляя
каждый из них. Для этого вместо имен столбцов вставляет-
ся групповой символ "звездочка" (*). Это делается следую-
щим образом.
ВВОД
SELECT *
FROM Products;
34 Урок 2

Анализ
При указании группового символа (*) возвращаются все
столбцы. Столбцы обычно (но не всегда) возвращаются в
том порядке, в котором они находились при создании таб-
лицы. Однако SQL-данные редко выводятся в том виде, в
каком они хранятся в базе данных. (Обычно они возвраща-
ются в приложение, которое необходимым образом их фор-
матирует.)

Использование групповых символов


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

Выборка неизвестных столбцов


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

Резюме
В этом уроке мы рассмотрели порядок использования
SQL-оператора SELECT для выборки одного, нескольких и
всех столбцов таблицы. Далее мы научимся сортировать
данные, полученные в результате выборки.
УрокЗ

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

Сортировка данных
Из последнего урока вы узнали, что следующий SQL-
оператор возвращает один столбец из таблицы базы дан-
ных. Но взгляните на результат: данные выводятся в пол-
ном беспорядке.
ВВОД
SELECT prod_name
FROM Products;

вывод
prod_name
Fish bean bag toy
Bird bean bag toy
Rabbit bean bag toy
8 inch teddy bear
12 inch teddy bear
18 inch teddy bear
Raggedy Ann
King doll
Queen doll
Вообще-то выбранные данные отображаются не в полном
беспорядке. При отсутствии сортировки данные обычно вы-
водятся в том порядке, в котором они находятся в таблице.
Это может быть порядок, в котором они изначально добав-
36 Урок 3

лялись в таблицу. Однако если данные впоследствии обнов-


лялись или удалялись, порядок будет зависеть от того, как
СУБД будет использовать оставшееся свободное место. В
результате вы не можете (и не должны) полагаться на по-
рядок сортировки, если вы не контролируете его. В теории
реляционных баз данных говорится, что последователь-
ность выбранных данных не имеет смысла, если не был
специально указан порядок сортировки.

Предложение
SQL-операторы завершаются предложениями, одни
из которых обязательны, другие — нет. Предложение
обычно состоит из ключевого слова и предоставляе-
мых данных. Примером может служить предложение
FROM оператора S E L E C T , которое мы использовали в
предыдущем уроке.

Для точной сортировки выбранных при помощи опера-


тора SELECT данных используется предложение ORDER BY.
В этом предложении указывается имя одного или несколь-
ких столбцов, по которым и сортируются результаты.
Взгляните на следующий пример:
ВВОД
SELECT prod_name
FROM Products
ORDER BY prod_name;

Анализ
Это выражение идентично предыдущему, за исключени-
ем предложения ORDER BY, которое указывает системе
управления базой данных отсортировать данные в алфавит-
ном порядке по столбцу prod_name. Результат применения
этого выражения будет следующим:
ВЫВОД
prod_name
12 inch teddy bear
18 inch teddy bear
8 inch teddy bear
Bird bean bag toy
Сортировка выбранных данных 37

Fish bean bag toy-


King doll
Queen doll
Rabbit bean bag toy
Raggedy Ann

Местоположение предложения ORDER B Y

При использовании предложения O R D E R B Y убеди-


тесь, что оно указано п о с л е д н и м в операторе S E L E C T .
Использование предложений в неправильном поряд-
ке ведет к появлению сообщений об ошибках.

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


Чаще всего столбцы, используемые в предложении
ORDER B Y , отображаются на экране. Но это не всегда
бывает так, данные могут сортироваться и по столб-
цу, который не выбирается этим запросом.

Сортировка по нескольким
столбцам
Часто бывает необходимо отсортировать данные по не-
скольким столбцам. Например, если вы выводите список
служащих, вам может понадобиться отсортировать его по
имени и фамилии сотрудника (сначала по фамилии, а затем
с каждой фамилией по имени). Это может быть полезным,
если в компании есть несколько служащих с одинаковыми
фамилиями.
Чтобы осуществить сортировку по нескольким столбцам,
просто укажите их имена через запятую (так, как вы дела-
ли при простом перечислении столбцов).
В следующем коде выбираются три столбца, а результат
сортируется по двум из них — сначала по цене, а потом по
названию.
ВВОД
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price, prod_name;
38 Урок 3

ВЫВОД Щ
prod_id prod_price prod_name

BNBG02 3.4900 Bird bean bag toy


BNBG01 3.4900 Fish bean bag toy
BNBG03 3.4900 Rabbit bean bag toy
RGAN01 4.9900 Raggedy Ann
BR01 5.9900 8 inch teddy bear
BR02 8.9900 12 inch teddy bear
RYL01 9.4900 King doll
RYL02 9.4900 Queen doll
BR03 11.9900 18 inch teddv bear
Важно понимать, что при сортировке по нескольким
столбцам порядок сортировки будет таким, который указан
в запросе. Другими словами, в примере, приведенном выше,
продукция сортируется по столбцу prod_name, только если
существует несколько строк с одинаковыми значениями
prod_price. Если никакие значения столбца prod_jprice не
совпадают, данные по столбцу prod_name сортироваться не
будут.

Сортировка по положению
столбца
Порядок сортировки можно указать не только по име-
нам столбцов, но и по относительному положению столбца
(проще говоря — по номеру столбца). Чтобы лучше понять
это, рассмотрим пример:
ВВОД
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY 2, 3;

ВЫВОД
prod_id prod_price prod_name

BNBG02 3 .4900 Bird bean bag toy


BNBG01 3.4900 Fish bean bag toy
BNBG03 3.4900 Rabbit bean bag toy
RGAN01 4.9900 Raggedy Ann
BR01 5.9900 8 inch teddy bear
BR02 8.9900 12 inch teddy bear
Сортировка выбранных данных 39

RYL01 9. 4900 King d o l l


RYL02 9. 4900 Queen d o l l
BR03 11 .9900 18 inch teddy bear

| Анализ
Как видите, результат выполнения запроса идентичен
предыдущему примеру. Разница только в предложении
ORDER BY. Здесь мы не указывали имена столбцов, вместо
этого было оговорено их относительное положение в ука-
занном списке SELECT. Предложение ORDER BY 2 означает
сортировку по второму столбцу списка SELECT, а именно по
столбцу prod_price. Предложение ORDER BY 2, 3 означа-
ет сортировку по столбцу prod_price, а затем по столбцу
prod_name.
Основное преимущество данного метода заключается в
том, что не нужно несколько раз набирать в запросе имена
столбцов. Однако имеются и недостатки. Во-первых, некон-
кретное перечисление столбцов повышает вероятность того,
что вы случайно укажете не тот столбец. Во-вторых, можно
случайно сменить порядок данных при изменении списка
SELECT (при этом забыв внести соответствующие изменения
в предложение ORDER BY). И наконец, очевидно, нельзя ис-
пользовать этот метод для сортировки по столбцам, не ука-
занным в списке SELECT.
Сортировка по невыбранным столбцам
Очевидно, что этот метод нельзя использовать при
сортировке по столбцам, не указанным в списке
SELECT. Однако при необходимости можно в одном
операторе указывать реальные имена столбцов и их
относительные положения.

Указание направления
сортировки
Сортировка данных не ограничена порядком по возрас-
танию (от А до Я). Несмотря на то что этот порядок явля-
ется порядком по умолчанию, в предложении ORDER BY
также можно использовать порядок по убыванию (от Я до
А). Для этого необходимо указать ключевое слово DESC.
40 Урок 3

В следующем примере продукция сортируется по цене в


убывающем порядке (вначале идут самые дорогие товары).
ВВОД
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price DESC;

ВЫВОД
prod_id prod_price prod_name
BR03 11.9900 18 i n c h t e d d y b e a r
RYL01 9.4900 King d o l l
RYL02 9.4900 Queen d o l l
BR02 8.9900 12 i n c h t e d d y b e a r
BR01 5.9900 8 inch teddy bear
RGAN01 4.9900 Raggedy Ann
BNBG01 3.4900 F i s h bean bag t o y
BNBG02 3.4900 B i r d bean bag t o y
BNBG03 3.4900 R a b b i t bean bag t o y

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


столбцам? В следующем примере продукция сортируется по
цене в убывающем порядке (вначале самые дорогие), плюс
по названию продукта:
ВВОД
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price DESC, prod_name;

ВЫВОД
prod_xd prod_price prod_name
BR03 11.9900 18 inch teddy bear
RYL01 9.4900 King doll
RYL02 9.4900 Queen doll
BR02 8.9900 12 inch teddy bear
BR01 5.9900 8 inch teddy bear
RGAN01 4.9900 Raggedy Ann
BNBG02 3.4900 Bird bean bag toy
BNBG01 3.4900 Fish bean bag toy
BNBG03 3.4900 Rabbit bean bag toy
Сортировка выбранных данных 41

Анализ
Ключевое слово DESC применяется только к тому столбцу,
после которого оно указано. В предыдущем примере ключе-
вое слово DESC было указано для столбца prodjprice, но не
для prod_name. Таким образом, столбец prod_price отсор-
тирован в порядке убывания, а столбец prod_name в обыч-
ном, возрастающем порядке.

Сортировка по убыванию по нескольким столбцам


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

Следует упомянуть, что DESC — это сокращение от


DESCENDING, можно использовать оба ключевых слова. Про-
тивоположным словом для DESC является ASC (ASCENDING),
которое можно указывать для сортировки по возрастанию.
Однако на практике слово AS С обычно не применяется, по-
скольку такой порядок используется по умолчанию (он пред-
полагается, если не указано ни ASC, ни DESC).

Чувствительность к регистру и порядок сорти-


ровки
При сортировке текстовых данных А ЭТО то же самое,
что и а? И а идет перед Б ИЛИ после я? Это не теоре-
тические вопросы, ответ на них зависит от настройки
базыданных.
При лексикографическом порядке сортировки А счи-
тается идентичным а, и такое поведение является
обычным для большинства систем управления база-
ми данных. Однако в некоторых СУБД администратор
может при необходимости это поведение изменить.
(Это может оказаться полезным, если в вашей базе
данных содержится много символов из другого языка.)
Суть в том, что если вам понадобится альтернативный
порядок сортировки, его нельзя будет достичь по-
средством обычного предложения ORDER BY. Вам
придется обратиться к администратору базы данных.
42 УрокЗ

Резюме
Этот урок был посвящен сортировке выбранных данных
при помощи предложения ORDER BY оператора SELECT. Это
предложение, которое должно быть последним в операторе
SELECT, можно использовать для сортировки данных по од-
ному или нескольким столбцам.
Урок 4

Фильтрация данных
На этом уроке вы узнаете, как использовать предложение
WHERE оператора SELECT для указания предложений поиска.

Использование предложения
WHERE
В таблицах баз данных обычно содержится очень много
информации и довольно редко возникает необходимость
выбирать все строки таблицы. Гораздо чаще бывает нужно
извлечь какую-то часть данных таблицы для каких-либо
действий или отчетов. Выборка только необходимых дан-
ных включает в себя критерий поиска, также известный
под названием предложение фильтрации.
В операторе SELECT данные фильтруются путем указа-
ния критерия поиска в предложении WHERE. Предложение
WHERE указывается сразу после названия таблицы (предло-
жения FROM) следующим образом:
ВВОД
SELECT prod_name, prod_price
FROM Products
WHERE prod_price = 3.49;

Анализ
Этот оператор извлекает два столбца из таблицы това-
ров, но показывает не все строки, а только те, значение в
столбце prod_price которых равно 3.49:
ВЫВОД
prod_name prod_j?rice

Fish bean bag toy 3.4 900


44 Урок 4

Bird bean bag toy 3.4900


Rabbit bean bag toy 3.4 900
В этом примере используется простая проверка на ра-
венство: сначала проверяется, существует ли в столбце ука-
занное значение, а затем данные фильтруются соответст-
вующим образом. Однако SQL позволяет использовать не
только проверку на равенство.

Требовательная PostgreSQL
СУБД PostgreSQL имеет строгие правила, управляю-
щие значениями, передающимися в SQL-операторы,
особенно это касается чисел с десятичными дробя-
ми. Таким образом, предыдущий пример может и не
работать в PostgreSQL. Чтобы он заработал, необхо-
димо точно указать, что 3 . 4 9 — это "правильное"
число, включив в предложение WHERE его ТИП. Д Л Я
этого замените ~ з . 4 9 н а = d e c i m a l ' 3 . 4 9 ' .

Фильтрация в SQL и в приложении


Данные также могут быть отфильтрованы на уровне
приложения. Для этого посредством оператора
SELECT осуществляется выборка большего количест-
ва данных, чем на самом деле необходимо для кли-
ентского приложения, а затем клиентский код обра-
батывает полученные данные для извлечения только
нужных строк.
Как правило, этот метод не приветствуется. Базы
данных оптимизированы для быстрой и эффективной
фильтрации. Заставляя клиентское приложение вы-
полнять работу базы данных, вы значительно ухуд-
шаете его производительность, а также затрудняете
его корректное масштабирование. Кроме того, если
данные фильтруются у клиента, сервер отправляет
ненужные данные по сети, тем самым занимая лиш-
нюю полосу канала.
Фильтрация данных 45

П о л о ж е н и е п р е д л о ж е н и я WHERE

При использовании обоих предложений, ORDER BY И


WHERE, убедитесь, что предложение O R D E R B Y следу-
ет з а п р е д л о ж е н и е м WHERE, иначе возникнет о ш и б к а .
(Более п о д р о б н о п р е д л о ж е н и е O R E D E R B Y описыва-
ется в уроке 3.)

Операции в предложении
WHERE
В первом предложении WHERE, которое мы рассмотрели,
проводилась проверка на равенство, т.е. определялось, со-
держится ли в столбце указанное значение. SQL поддержи-
вает весь спектр условных (логических) операций, которые
приведены в табл. 4.1.
Т а б л и ц а 4 . 1 . О п е р а ц и и в п р е д л о ж е н и и WHERE

Операция Описание
= Равенство
о Неравенство
!= Неравенство
< Меньше
<= Меньше или равно
!< Не меньше
> Больше
>= Больше или равно
!> Не больше
BETWEEN Между двумя указанными значениями
I S NULL Значение NULL

Совместимость операций
Некоторые из операций, приведенных в табл. 4.1, по-
вторяются (например, <> — это то же самое, что и ! =).
Выполнение операции ! < (не меньше Чём) дает такой
46 Урок 4

же результат, что и >= (больше или равно). Однако


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

Проверка одного значения


Мы рассмотрели пример проверки на равенство. Теперь
рассмотрим примеры использования других операций.
В первом примере выводятся названия товаров, стои-
мость которых не превышает $10:
ВВОД
SELECT prod_name, prod_price
FROM Products
WHERE prod_price < 10;

ВЫВОД
prod name prod__price

Fish bean bag toy 3.4900


Bird bean bag toy 3.4900
Rabbit bean bag toy 3.4900
8 inch teddy bear 5.9900
12 inch teddy bear 8.9900
Raggedy Ann 4.9900
King doll 9.4900
Queen doll 9.4900
В следующем выражении выбираются все товары, кото-
рые стоят $10 и меньше (результат будет такой же, как и в
первом примере, так как в базе данных нет товаров, кото-
рые бы стоили ровно $10):
ВВОД
SELECT prod_name, prod_price
FROM Products
WHERE prod_price <= 10;

Проверка на несовпадения
В этом примере выводятся товары, не изготовленные
фирмой DLL01.
Фильтрация данных 47

ВВОД
SELECT vend_id, p r o d _ p r i c e
FROM Products
1
WHERE vend i d о 'DLL01 ;

ВЫВОД
vend_id prod_name

BRS01 8 inch teddy bear


BRS01 12 inch teddy bear
BRS01 18 inch teddy bear
FNG01 King doll
FNG01 Queen doll

Когда использовать кавычки


Если вы внимательно рассмотрите выражения в пре-
дыдущих предложениях WHERE, то заметите, что неко-
торые значения заключены в одинарные кавычки, а
некоторые — нет. Одинарные кавычки используются
для определения границ строки. При сравнении зна-
чения со столбцом, содержащим строковые данные,
необходимы отделяющие строку кавычки. При ис-
пользовании числовых столбцов кавычки не исполь-
зуются.

Ниже приведен тот же пример, только здесь уже исполь-


зуется операция !=, вместо <>:
ВВОД
SELECT vend_id, prod_price
FROM Products
WHERE vend id != 'DLL011;

Операция ! = или <>


Операции •= и <> обычно взаимозаменяемы. Однако
не во всех СУБД поддерживаются обе формы опера-
ции неравенства. Например, в Microsoft Access
поддерживается операция <> и не поддерживается !=.
Если у вас возникли сомнения по поводу своей СУБД,
обратитесь к ее документации.
48 Урок 4

Проверка на диапазон значений


Для поиска диапазона значений можно использовать
операцию BETWEEN. Ее синтаксис немного отличается от
других операций предложения WHERE, так как для нее тре-
буются два значения: начальное и конечное. Например,
операцию BETWEEN можно использовать для поиска това-
ров, цена которых находится в промежутке между $5 и
$10, или всех дней, которые попадают в диапазон между
указанными начальным и конечным числами.
В следующем примере демонстрируется использование
операции BETWEEN для выборки всех товаров, цена которых
выше $5 и ниже $10:
ВВОД
SELECT prod_name, prod_price
FROM Products
WHERE prod_price BETWEEN 5 AND 10;

ВЫВОД
prod_name prod_price

8 inch teddy bear 5.9900


12 inch teddy bear 8.9900
King doll 9.4900
Queen doll 9.4900

Анализ
Как видно из этого примера, при использовании опера-
ции BETWEEN нужно указывать два значения — меньшее и
большее из выбранного диапазона. Эти два значения долж-
ны быть разделены ключевым словом AND. При этом выби-
раются все значения из диапазона, включая указанные на-
чальное и конечное значения.

Проверка на отсутствие значения


После создания таблицы разработчик может указать,
допустимо ли, чтобы в отдельных ее столбцах не содержа-
лись никакие значения. Когда в столбце не содержится ни-
какого значения, это значит, что в нем содержится значе-
ние NULL.
Фильтрация данных 49

NULL

Отсутствие какого-либо значения, в отличие от поля,


содержащего или о, или пустую строку, или просто
несколько пробелов.

Для оператора SELECT предусмотрена специальная фор-


ма предложения WHERE, которая используется для проверки
значений NULL в столбцах и содержит проверку IS NULL.
Синтаксис выглядит следующим образом:
ВВОД
SELECT prod_name
FROM Products
WHERE prod_jprice IS NULL;
Это выражение возвращает список товаров без цены (по-
ле prodjprice пустое, а не с ценой 0), а поскольку тако-
вых нет, никаких данных мы не получим. Однако в табли-
це Vendors есть столбцы со значениями NULL — в столбце
vend_state будет содержаться NULL, если не указан ника-
кой штат (в случае, когда адресат находится за пределами
Соединенных Штатов):
ВВОД
SELECT vend_id
FROM Vendors
WHERE vend state IS NULL;

ВЫВОД
vend id

FNG1
JTS01

Особые операции СУБД


Во многих СУБД набор операций расширен дополни-
тельными фильтрами. Обратитесь к документации
вашей СУБД за дополнительной информацией.
50 Урок 4

Резюме
В этом уроке рассказывалось о том, как отфильтровы-
вать возвращаемые данные при помощи предложения
WHERE оператора SELECT. Теперь вы знаете, как можно про-
верить данные на равенство, неравенство, наличие значений
больше чем и меньше чем, диапазон значений, а также на
значение NULL.
Урок 5

Расширенная
фильтрация данных
В этом уроке вы узнаете, как можно комбинировать пред-
ложения WHERE для создания мощных и сложных условий
поиска. Вы также узнаете, как следует использовать клю-
чевые слова NOT и IN.

Комбинирование предложений
WHERE
Все предложения WHERE, представленные в уроке 4,
"Фильтрация данных", отфильтровывают данные с исполь-
зованием одного критерия. Чтобы увеличить уровень кон-
троля над фильтром в SQL, можно использовать несколько
предложений WHERE. Эти предложения допустимо использо-
вать двумя способами: в виде предложений AND или OR.

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

1
Термин statement в русскоязычной литературе по языку SQL
принято переводить как оператор (и мы следовали этой традиции во
всех предыдущих уроках), хотя точнее его следовало бы переводить
как инструкция. В данном случае речь идет именно об операторах
(operator). — Прим. ред.
52 Урок 5

Использование ключевого слова AND


Чтобы отфильтровать данные по более чем одному
столбцу, необходимо воспользоваться ключевым словом AND
для добавления предложений в предложение WHERE. Вот
как это делается:
ВВОД
SELECT prod_id, prod_price, prod_name
FROM Products
WHERE vend_id = 'DLL01' AND prod_price <=4;

Анализ
Посредством данного оператора извлекается название
продукции и цена для всех товаров, изготовленных произ-
водителем DLL01, с ценой $4 и меньше. Предложение
WHERE в операторе SELECT состоит из двух предложений, а
ключевое слово AND используется для их объединения.
Ключевое слово AND указывает системе управления базой
данных возвращать только те строки, которые удовлетво-
ряют всем перечисленным предложениям. Если продукт
изготовлен производителем DLL01, но стоит больше $4, он
не попадет в результаты. Аналогично, товары, которые
стоят меньше $4 и изготовлены отличными от указанного
производителями, также не будут выведены. Данные,
выданные в результате выполнения этой SQL-инструкции,
будут выглядеть так:
ВЫВОД
Prod id
Iprod_price prod_name

BNBG02 3.4900 Bird bean bag toy-


BNBGO1 3.4900 Fish bean bag toy
BNBG03 3.4900 Rabbit bean bag toy

AND

Ключевое слово, используемое в предложении WHERE


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

Использование ключевого слова OR


Действие ключевого слова OR противоположно действию
ключевого слова AND. Ключевое слово OR указывает системе
управления базой данных выбирать только те строки, кото-
рые удовлетворяют хотя бы одному предложению. На са-
мом деле в большинстве лучших СУБД второе предложение
даже не рассматривается в предложении OR WHERE, если
удовлетворено первое предложение. (Если первое предло-
жение выполнено, строка будет выведена независимо от
второго предложения.)
Взгляните на следующий оператор SELECT:
ВВОД
SELECT prod_name, prod_price
FROM Products
1
WHERE vend id = 'DLL01 OR vend id = 'BRS01

Анализ
Посредством этого SQL-оператора выбираются названия
товаров и их цены для всех продуктов, изготовленных од-
ним из указанных производителей. Ключевое слово OR ука-
зывает СУБД использовать какое-то одно предложение, а не
сразу два. Если бы здесь использовалось ключевое слово
AND, мы бы не получили никаких данных. После выполне-
ния этого SQL-запроса мы получим следующие данные:
ВЫВОД ^ ^ ^ В
prod name prod_price

Fish bean bag toy 3.4900


Bird bean bag toy 3.4900
Rabbit bean bag toy 3.4900
8 inch teddy bear 5.9900
12 inch teddy bear 8.9900
18 inch teddy bear 11.9900
Raggedy Ann 4.9900

OR

Ключевое слово, п р и м е н я е м о е в предложении WHERE


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

Порядок обработки
Предложения WHERE могут содержать любое количество
логических операторов AND и OR. Комбинируя их, можно
создавать сложные фильтры.
Однако при комбинировании ключевых слов AND и OR
возникает одна проблема. Рассмотрим следующий пример.
Необходимо вывести список всех изготовленных производи-
телями DLL01 и BRS01 товаров, цена которых $10 и выше.
В следующей инструкции SELECT используется комбинация
ключевых слов AND и OR для формулирования предложе-
ния WHERE:
ВВОД
SELECT prod_name, prod_j?rice
FROM P r o d u c t s
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01
AND p r o d _ p r i c e >= 10;

ВЫВОД
prod name prod_price
Fish bean bag toy- 3.4900
Bird bean bag toy- 3.4900
Rabbit bean bag toy 3.4900
18 inch teddy bear 11.9900
Raggedy Ann 4.9900

Анализ
Взгляните на результат. В четырех возвращенных стро-
ках значатся цены ниже $10 — очевидно, строки не были
отфильтрованы так, как надо. Что же произошло? Причина
в порядке обработки. SQL (как и большинство других язы-
ков) вначале обрабатывает логические операторы AND, а по-
том уже логические операторы OR. Когда SQL "видит" такое
предложение WHERE, он его считывает так: выбрать все
продукты, которые стоят $10 и больше, изготовленные
производителем BRS01, и все продукты, изготовленные
производителем DLL01 независимо от их цены. Другими
словами, так как приоритет у логического оператора AND
выше, были объединены "не те" операторы.
Решение этой проблемы состоит в использовании скобок
для точного группирования необходимых логических one-
Расширенная фильтрация данных 55

раторов. Взгляните на следующий оператор SELECT и его


выходные данные:
ВВОД
SELECT prod_name, prod_price
FROM Products
1
WHERE (vend_id = 'DLL01 OR vend_id = 'BRS01')
AND prod_j?rice >= 10;

ВЫВОД
prod_name prod_price

18 inch teddy bear 11.9900

Анализ
Единственным отличием между предыдущим выражени-
ем и этим являются скобки, в которые заключены первые
два предложения оператора WHERE. Поскольку скобки име-
ют еще больший приоритет, чем логические операторы AND
и OR, СУБД вначале обрабатывает условие OR внутри ско-
бок. Соответственно, SQL-оператор будет пониматься так:
выбрать все продукты, изготовленные либо производите-
лем DLL01, либо производителем BRS01, которые стоят
$10 и больше, а это именно то, что нужно.

Использование с к о б о к в п р е д л о ж е н и я х WHERE

Когда бы вы ни использовали предложения WHERE С


ключевыми словами AND и OR, всегда вставляйте
скобки, чтобы точно сгруппировать логические опе-
раторы. Не полагайтесь на порядок обработки по
умолчанию, даже если он подразумевает необходи-
мый вам результат. Нет никаких недостатков в ис-
пользовании скобок, кроме того, вы всегда будете за-
страхованы от неопределенностей.
56 Урок 5

Использование ключевого
слова IN
Ключевое слово IN используется для указания диапазона
условий, любое из которых может быть выполнено. При
этом значения, заключенные в скобки, перечисляются через
запятую. Рассмотрим следующий пример:
ВВОД
SELECT prod_name, prodjprice
FROM Products
WHERE vend_id IN ('DLL011, 'BRS01!
ORDER BY prod_name

ВЫВОД
prod name prod_price
12 inch teddy bear 8.9900
18 inch teddy bear 11.9900
8 inch teddy bear 5.9900
Bird bean bag toy 3.4900
Fish bean bag toy 3.4900
Rabbit bean bag toy 3.4900
Raggedy Ann 4.9900

Анализ f ^ T H L 5
Инструкция SELECT осуществляет выборку всех товаров,
изготовленных производителями DLL01 и BRS01. После
ключевого слова IN следует список значений через запятую,
а весь список заключен в скобки.
Если вы подумаете, что ключевое слово IN выполняет ту
же функцию, что и OR, то будете совершенно правы. Сле-
дующий SQL-запрос выполняет ту же функцию, что и пре-
дыдущий:
ВВОД
SELECT prod_name, prod_price
FROM Products
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01
ORDER BY prod_name;
Расширенная фильтрация данных 57

ВЫВОД
prod_name prod_price

12 inch teddy bear 8.9900


18 inch teddy bear 11.9900
8 inch teddy bear 5.9900
Bird bean bag toy 3.4900
Fish bean bag toy 3.4900
Rabbit bean bag toy 3.4900
Raggedy Ann 4.9900
Зачем же нужно ключевое слово IN? Его преимущества
следующие.
• При работе с длинными списками необходимых зна-
чений синтаксис логического оператора IN гораздо
легче читать.
• При использовании ключевого слова IN гораздо легче
управлять порядком обработки (так как используется
меньшее количество операторов).
• Логические операторы IN почти всегда быстрее обра-
батываются, чем списки логических операторов OR.
• Самое большое преимущество логического оператора
IN в том, что в данном операторе может содержаться
еще одна инструкция SELECT, а это позволяет созда-
вать очень динамичные предложения WHERE. Более
подробно вы об этом узнаете в уроке 11, "Использо-
вание подзапросов".

IN

Ключевое слово, используемое в предложении WHERE


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

Использование ключевого
слова NOT
Логический оператор NOT предложения WHERE служит
для выполнения только одной функции — отрицать все
58 Урок 5

предложения, следующие за ним. Поскольку NOT никогда


не используется сам по себе (а только вместе с другими ло-
гическими операторами), его синтаксис немного отличается
от синтаксиса остальных операторов. В отличие от них, NOT
вставляется перед названием столбца, значения которого
нужно отфильтровать, а не после.
;
N O T • • ;-,- . • • ; '• • . - • :'•• ••:• • ':'•:

Ключевое слово, применяемое в предложении WHERE


для отрицания какого-то условия.

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


логического оператора NOT. Чтобы извлечь список продук-
тов, изготовленных всеми производителями, кроме DLL01,
можно потребовать выполнить следующее:
ВВОД
SELECT prod_name
FROM Products
WHERE NOT vend_id = 'DLL01 1
ORDER BY prod_name;

ВЫВОД
prod_name

12 inch teddy bear


18 inch teddy bear
8 inch teddy bear
King doll
Queen doll

Анализ
Здесь логический оператор NOT отрицает предложение,
следующее за ним. Поэтому СУБД извлекает не те значения
vend_id, которые совпадают с DLL01, а все остальные.
Предыдущий запрос можно было также выполнить при
помощи операции <>:
ВВОД
SELECT prod_name
FROM Products
WHERE vend_id о 'DLL01'
ORDER BY prod_name;
Расширенная фильтрация данных 59

ВЫВОД
prod_name
12 inch teddy bear
18 inch teddy bear
8 inch teddy bear
King doll
Queen doll

Анализ
Зачем же использовать логический оператор NOT? Ко-
нечно, для таких простых предложений WHERE, какие мы
здесь рассматриваем, этот оператор не обязателен. Он поле-
зен в более сложных предложениях. Например, для нахож-
дения всех строк, которые не совпадают со списком крите-
риев, можно использовать логический оператор NOT в паре
с ключевым словом IN.
NOT в MySQL
Форма логического оператора NOT, который здесь
описывается, не поддерживается в СУБД MySQL
В MySQL NOT используется только для отрицания
в х о ж д е н и й E X I S T S (т.е. к а к N O T E X I S T S ) .

Резюме
В этом уроке вы узнали, как нужно комбинировать
предложения WHERE с логическими операторами AND и OR.
Вы также узнали, как следует управлять порядком обра-
ботки и как использовать ключевые слова IN и NOT.
Урок 6

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

Использование логического
оператора LIKE
Все предыдущие операторы, которые мы рассмотрели,
производили фильтрацию по известным значениям. Они
искали совпадения по одному или нескольким значениям,
более чем и менее чем известное значение или диапазон
значений. При этом везде искалось известное значение. Од-
нако фильтрация данных таким способом не всегда работа-
ет. Например, как бы вы искали продукты, в названии ко-
торых содержатся слова bean bag? Этого нельзя сделать при
помощи простых операций сравнения, здесь на помощь
приходит поиск с использованием метасимволов. При по-
мощи метасимволов можно создавать условия поиска дан-
ных. В этом примере, для того чтобы найти все продукты, в
названии которых содержатся слова bean bag, необходимо
составить шаблон поиска, позволяющий найти текст bean
bag в любом месте названия продукта.
62 Урок 6

:ji~~?JU: Метасимволы
^^З^ Специальные символы, применяемые для поиска
части значения.

Шаблон поиска
Условие поиска, состоящее из текста, метасимволов
и любой их комбинаций.

Метасимволы сами по себе являются символами, кото-


рые имеют в условии WHERE специальное значение. В SQL
поддерживаются метасимволы нескольких типов. Чтобы
применять метасимволы в условиях поиска, необходимо
использовать ключевое слово LIKE. Оно сообщает СУБД,
что следующий шаблон для поиска необходимо сравнивать
с использованием метасимволов, а не искать точные совпа-
дения.

Предикат
Когда оператор не является оператором? Тогда,
когда он является предикатом. Технически, L I K E —
это предикат, а не оператор. Конечный результат
остается тем же, просто не пугайтесь этого термина,
если вы встретите его в документации по SQL.

Поиск с использованием метасимволов может осуществ-


ляться только в текстовых полях (строках), нельзя исполь-
зовать метасимволы при поиске полей с нетекстовым типом
данных.

Метасимвол "знак процента" (%)


Наиболее часто используемый метасимвол — знак про-
цента (%). В строке поиска % означает найти все вхождения
любого символа. Например, чтобы найти все продукты, на-
звания которых начинаются со слова Fish, можно выпол-
нить следующий запрос:
Использование метасимволов для фильтрации 63

ВВОД
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE 'Fish%';

ВЫВОД
prod_id prod_narae

BNBG01 Fish bean bag toy

Анализ
В этом примере используется шаблон поиска 'Fish%'.
При выполнении этого условия возвращаются все значения,
которые начинаются с символов Fish. Знак % указывает
СУБД принимать все символы после слова Fish независимо
от их количества.
Метасимволы Microsoft Access
Если вы работаете в Microsoft Access, необходимо
использовать символ * вместо символа %.

Зависимость от регистра
Ваша СУБД и ее конфигурация могут влиять на то, что
поиск будет зависеть от регистра. В этом случае по
строке • f ish%' значение F i s h bean bag t o y не бу-
дет найдено.

Метасимволы можно использовать в любом месте шаб-


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

ВВОД
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE •%bean bag%';
64 Урок 6

ВЫВОД
prod_id prod_name

BNBG01 Fish bean bag toy


BNBG02 Bird bean bag toy
BNBG03 Rabbit bean bag toy

Анализ 1
Шаблон поиска ' %bean bag%' означает найти все зна-
чения, содержащие bean bag в любом месте названия, не-
зависимо от количества символов перед или после указан-
ного текста.
Метасимвол можно также использовать внутри шаблона
поиска, хотя это редко бывает полезным. В следующем
примере производится поиск всех продуктов, которые на-
чинаются на F и заканчиваются на у:
ВВОД
SELECT prod_name
FROM Products
WHERE prod_name LIKE 'F%yT;
Важно отметить, что помимо поиска одного или не-
скольких символов, знак % также означает и отсутствие
символов в указанном месте шаблона поиска.

Следите за замыкающими пробелами


Многие СУБД, включая Microsoft Access, заполняют
содержимое поля пробелами. Например, если стол-
бец рассчитан на 50 символов, а в нем вставлен текст
F i s h bean bag t o y (17 символов), то, чтобы запол-
нить столбец, в него может быть добавлено еще 33
пробела. Обычно это не влияет на данные или их ис-
пользование, но может негативно отразиться на пре-
дыдущем SQL-выражении. По условию WHERE
prod_name LIKE ' F l y ' будут найдены только те
значения prod_name, которые начинаются на F и за-
канчиваются на у. Если значение заполнено пробе-
лами, оно не будет заканчиваться на у, и значение
F i s h bean bag t o y не будет извлечено. Одним из
простых решений может быть добавление второго
Использование метасимволов для фильтрации 65

символа % в шаблон поиска: • F%y%', после чего будут


учитываться символы (пробелы) после буквы у. Но
лучше "отрезать" пробелы при помощи функций, ко-
торые обсуждаются в уроке 8, "Использование функ-
ций манипулирования данными".

Метасимвол "символ подчеркивания" (_)


Еще одним полезным метасимволом является символ
подчеркивания (_). Символ подчеркивания используется
так же, как и %, но при этом учитывается не много симво-
лов, а только один.
Метасимволы в Microsoft Access
Если вы работаете в Microsoft Access, вам нужно ис-
пользовать знак ? вместо символа .

Взгляните на этот пример.


ВВОД
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE ' inch teddy bear';

Следите з а замыкающими пробелами


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

ВЫВОД
prod_id prod_name
BNBG02 12 inch teddy bear
BNBG03 18 inch teddy bear

Анализ
В шаблоне поиска этого предложения WHERE использова-
ны два метасимвола, затем следует текст. В результате бы-
ли выбраны только те строки, которые удовлетворяли шаб-
66 Урок 6

лону поиска: по двум символам подчеркивания было най-


дено число 12 в первой строке и 18 во второй. Продукт 8
inch teddy bear не был найден, так как в шаблоне поис-
ка требуется два совпадения, а не одно. Для сравнения, в
следующем выражении SELECT используется метасимвол %,
вследствие чего извлекаются три названия товара:
ВВОД
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE '% inch teddy bear•

ВЫВОД
prod_id prod_name
BNBG01 8 inch teddy bear
BNBG02 12 inch teddy bear
BNBG03 18 inch teddy bear
В отличие от знака %, который подразумевает также от-
сутствие символов, знак _ всегда означает один символ —
не более и не менее.

Метасимвол "квадратные скобки" ([ ])


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

Наборы не всегда поддерживаются


В отличие от метасимволов, описанных ранее, ис-
пользование квадратных скобок для создания набо-
ров многими СУБД не поддерживается. Наборы под-
держиваются в СУБД Microsoft Access, Microsoft SQL
Server и Sybase Adaptive Server. Обратитесь к доку-
ментации по вашей СУБД, чтобы определить, под-
держиваются ли в ней наборы.

Например, чтобы найти все контакты людей, имена ко-


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

ВВОД
SELECT prod_id, prod_name
FROM Customers
WHERE cust_contact LIKE •[JM]
ORDER BY cust contact

ВЫВОД
cust_contact

Jim Jones
John Smith
Michelle Green

Анализ
Условие WHERE в этом выражении выглядит как
1
[ JM] %'. В этом шаблоне поиска используются два разных
метасимвола. По метасимволам [JM] производится поиск
всех контактных лиц, имена которых начинаются на одну
из указанных в скобках букв, но при этом учитывается
только один символ. Поэтому все имена длиннее одного
символа не будут извлечены. По метасимволу %, следующе-
му после [ JM], производится поиск любого количества сим-
волов после первой буквы, что и приводит к требуемому ре-
зультату.
Можно использовать метасимвол, выполняющий проти-
воположное действие, добавив перед ним символ Л . Напри-
мер, в следующем примере выбираются все имена, которые
не начинаются с буквы J или М (в отличие от предыдущего
примера):
ВВОД
SELECT prod_id, prod_name
FROM Customers
WHERE cust_contact LIKE ' [AJM] %
ORDER BY cust contact

Противоположные наборы в Microsoft Access


Если вы работаете в Microsoft Access и требуется
создать противоположный набор, необходимо ис-
пользовать символ г вместо А , поэтому указывайте
68 Урок 6

Конечно, можно достичь того же результата, воспользо-


вавшись логическим оператором NOT. Единственным пре-
имуществом символа Л является более простой синтаксис
при выполнении нескольких предложений WHERE.

Внимание!
Метасимвол ( [ ] ) поддерживается не всеми СУБД.
Обратитесь к документации по вашей СУБД, чтобы
определить, поддерживается ли этот метасимвол.

Советы по использованию
метасимволов
Как видите, метасимволы в SQL — это очень мощный
механизм. Но за эту мощь приходится платить: поиск с ис-
пользованием метасимволов требует больше времени на об-
работку, чем любые другие виды поиска, которые мы обсу-
ждали ранее. Ниже приведены несколько советов по ис-
пользованию метасимволов.
• Не злоупотребляйте метасимволами. Если можно ис-
пользовать другой оператор поиска, воспользуйтесь им.
• При использовании метасимволов старайтесь по воз-
можности не вставлять их в начало шаблона поиска.
Шаблоны поиска, начинающиеся с метасимволов, об-
рабатываются медленнее всего.
• Внимательно следите за местоположением метасим-
волов. Если они находятся не на своем месте, будут
извлечены не те данные.
Исходя из всего вышесказанного, можно заключить, что
метасимволы очень важны и очень полезны при поиске —
вы часто будете ими пользоваться.

Резюме
В этом уроке рассказывалось о том, что такое метасим-
волы и как их использовать в условиях WHERE. Теперь вы
знаете, что метасимволы нужно использовать осторожно, не
следует злоупотреблять ими.
Урок 7

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

Что такое вычисляемые поля


Данные, хранимые в таблицах базы данных, обычно бы-
вают представлены не в таком виде, который необходим
для ваших приложений. Вот несколько примеров.
• Вам необходимо отобразить поле, содержащее имя
компании с ее адресом, но эта информация располо-
жена в разных столбцах таблицы.
• Город, штат и ZIP-код хранятся в отдельных столб-
цах (как и должно быть), но для программы печати
почтовых наклеек необходима эта информация в од-
ном, корректно сформированном поле.
• Данные в столбце введены с заглавными и строчными
буквами, но в вашем отчете необходимо использовать
только заглавные буквы.
• В таблице с предметами заказа хранятся цены про-
дуктов и их количество, но не полная цена (цена од-
ного продукта, умноженная на его количество) каж-
дого продукта. Чтобы распечатать счет, необходимы
полные цены.
• Вам необходимы общая сумма, среднее значение или
результаты других расчетов, основанные на данных,
имеющихся в таблице.
В каждом из этих примеров данные хранятся не в том
виде, в котором их необходимо предоставить приложению.
70 Урок7

Вместо того чтобы извлекать эти данные, а затем изменять


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

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

Важно отметить, что только база данных "знает", какие


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

Клиентское или серверное форматирование?


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

Конкатенация полей
Чтобы продемонстрировать работу вычисляемых полей,
рассмотрим простой пример — создание заголовка, состоя-
щего из двух столбцов.
Создание вычисляемых полей 71

В таблице Vendors содержится название поставщика и


его адрес. Предположим, что вам необходимо создать отчет
по поставщику и указать его адрес как часть его имени в
виде имя {адрес) .
В отчете должно быть одно значение, а данные в таблице
хранятся в двух столбцах: vend_name и vend_country.
Кроме того, значение vend__country необходимо заключить
в скобки, которых нет в таблице базы данных. Выражение
SELECT, которое возвращает имена поставщиков и адреса,
довольно простое, но как создать комбинированное значение?

Конкатенация
Комбинирование значений (путем присоединения их
друг к другу) для получения одного "длинного" значения.

Для этого необходимо соединить два значения. В SQL-


выражении SELECT можно выполнить конкатенацию двух
столбцов при помощи специального оператора. В зависимо-
сти от СУБД это может быть знак "плюс" (+) или две вер-
тикальные черточки ( | | ) .

Оператор + или | |
В СУБД Access, SQL Server и Sybase для конкатенации
используется знак +. В СУБД DB2, Oracle, PostgreSQL
и Sybase используется знак | |. Более подробную ин-
формацию ищите в документации по вашей СУБД.
Вообще-то | | — более предпочтительный оператор
конкатенации, так что он поддерживается все боль-
шим и большим количеством СУБД.

Ниже приведен пример использования знака "плюс'


(применяется синтаксис, принятый в большинстве СУБД):
ВВОД
SELECT vend_name + (' + vend_country + ')
FROM Vendors
ORDER BY vend_name;

ВЫВОД
Bear Emporium (USA
72 Урок7

Beras R Us (USA )
Doll House Inc. (USA )
Fun and Games (England )
Furball Inc. (USA )
Jouets et ours (France )
Ниже приведена та же инструкция, но с использованием
оператора I I:

ВВОД
SELECT vend_name || • (' || vend_country
FROM Vendors
ORDER BY vend name;

ВЫВОД
Bear Emporium (USA
Beras R Us (USA
Doll House Inc. (USA
Fun and Games (England
Furball Inc. (USA
Jouets et ours (France

Анализ
В предыдущих операторах SELECT была выполнена кон-
катенация следующих элементов:
• имя, хранящееся в столбце vend_name;
• строка, содержащая пробел и открывающую круглую
скобку;
• название штата, хранящееся в столбце vend_country;
• строка, содержащая закрывающую круглую скобку.
Как видно из приведенного выше результата, выражение
SELECT возвращает один столбец (вычисляемое поле), со-
держащий все четыре элемента как одно целое.
Конкатенация в MySQL
В MySQL не поддерживается конкатенация при по-
мощи оператора + или | | .Здесь необходимо исполь-
зовать функцию CONCAT'{), в которой указывается
список элементов, по отношению к которым необхо-
димо выполнить конкатенацию. При использовании
функции CONCAT () первая строка примера выглядела
бы так:
Создание вычисляемых полей 73

SELECT GONCAT (vend__name, ' С , f


vend_country, ')')
В MySQL поддерживается использование оператора
|, но не для конкатенации. В MySQL || является эк-
вивалентом логического оператора OR, a &&— экви-
валентом логического оператора AND.

Взгляните еще раз на результат, полученный после при-


менения оператора SELECT. Два столбца, объединенные в
вычисляемое поле, заполнены пробелами. Во многих базах
данных (но не во всех) сохраненный текст дополняется про-
белами до ширины столбца. Чтобы выбрать правильно от-
форматированные данные, необходимо убрать добавленные
пробелы. Это можно сделать при помощи SQL-функции
RTRIMO следующим образом:
ВВОД
SELECT RTRIM(vend_name) (' + RTRIM(vend_country) + ')
FROM Vendors
ORDER BY vend name;

ВЫВОД
Bear Emporium (USA)
Beras R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)
Ниже приведено это же выражение, но с использованием
оператора I | :
ВВОД
SELECT RTRIM(vend_name) RTRIM(vend_country) ])
FROM V e n d o r s
ORDER BY v e n d name;

ВЫВОД
Bear Emporium (USA)
Beras R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)
74 Урок 7

Анализ
Функция RTRIMO отбрасывает все пробелы справа от
указанного значения. При использовании функции RTRIM ()
каждый отдельный столбец обрабатывается корректно. Го-
род, штат указываются через запятую и пробел, а штат и
ZIP-код — через пробел.
Функции TRIM

В большинстве СУБД поддерживаются как функция


R T R I M () (которая, как мы увидели, "обрезает" правую
часть строки), так и L T R I M () (которая удаляет левую
часть строки), а т а к ж е T R I M О (которая "обрезает"
строку слева и справа).

Использование псевдонимов
Оператор SELECT, который использовался для конкате-
нации полей имени и адреса, как видите, справился со сво-
ей задачей. Но как же называется новый вычисляемый
столбец? По правде говоря — никак, это просто значение.
Этого может быть достаточно, если вы просматриваете ре-
зультаты в программе тестирования SQL-запросов, однако
столбец без названия нельзя использовать в клиентском
приложении, так как клиент не сможет к нему обратиться.
Для решения этой проблемы в SQL была включена под-
держка псевдонимов. Псевдоним — это альтернативное имя
для поля или значения. Псевдонимы присваиваются при
помощи ключевого слова AS. Взгляните на следующий опе-
ратор SELECT:
ВВОД
SELECT RTRIM(vend_name) (' + RTRIM(vend_country) + ')
^AS v e n d _ t i t l e
FROM Vendors
ORDER BY vend name;

ВЫВОД
vend_title
Bear Emporium (USA)
Создание вычисляемых полей 75

Beras R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)
Ниже приведена эта же инструкция, но с использовани-
ем оператора | | :
ВВОД
SELECT RTRIM(vend_name) RTRIM(vend_country)
^AS v e n d _ t i t l e
FROM Vendors
ORDER BY vend name;

ВЫВОД
vend title
Bear Emporium (USA)
Beras R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)

Анализ
Сам по себе этот оператор SELECT ничем не отличается от
предыдущего, за исключением того, что вычисляемое поле
указывается после текста AS v e n d _ t i t l e . Таким образом,
SQL создает вычисляемое поле, содержащее результат вы-
числений, под названием v e n d _ t i t l e . Как видите, результат
остается тем же, но столбец теперь носит имя v e n d _ t i t l e и
любое клиентское приложение может обращаться к нему по
имени, как если бы это был реальный столбец таблицы.
Другое использование псевдонимов
Псевдонимы можно использовать и по-другому. Час-
то псевдонимы используются для переименования
столбца, если в реальном названии присутствуют не-
допустимые символы (например, пробелы) или если
название сложное и трудночитаемое.
76 Урок 7

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

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

Выполнение математических
вычислений
Еще одним способом использования вычисляемых полей
является выполнение математических операций над вы-
бранными данными. Рассмотрим пример. В таблице Orders
хранятся все полученные заказы, а в таблице Order Items
содержатся наименования продуктов для каждого заказа.
Следующий SQL-оператор осуществляет выборку всех про-
дуктов в заказе номер 2 0008:
ВВОД
SELECT prod_id, quantity, item_price
FROM Orderltems
WHERE order nam = 20008;

ВЫВОД
prod id quantity item_price

RGAN01 5 4.9900
BR03 5 11.9900
BNBG01 10 3.4900
Создание вычисляемых полей 77

BNBG02 10 3.4900
BNBG03 10 3 .4900
В столбце item_price содержится цена на продукт для
каждой записи, имеющейся в заказе. Чтобы узнать полную
цену (цена за один продукт, умноженная на количество
продуктов в заказе), необходимо сделать следующее:
ВВОД
SELECT prod_id,
quantity,
item_price
quantity*item_j?rice AS expanded_price
FROM OrderItems
WHERE order nam = 20008;

ВЫВОД
prod_id quantity item_price
expanded_price

RGAN01 5 4.9900 24.9500


BR03 5 11.9900 59.9500
BNBG01 10 3.4900 34.9000
BNBG02 10 3.4900 34.9000
BNBG03 10 3.4900 34.9000

Анализ
Столбец expanded_price, показанный в предыдущем
результате, является вычисляемым полем; вычисление бы-
ло простым: quantity* itera_price. Теперь клиентское
приложение может использовать этот новый вычисляемый
столбец, как и любой другой в таблице.
В SQL поддерживаются основные математические опера-
ции, перечисленные в табл. 7.1. Кроме того, для управле-
ния порядком обработки можно использовать круглые
скобки. В уроке 5, "Расширенная фильтрация данных",
рассказывается о порядке обработки.
Таблица 7 . 1 . Математические операции в SQL
Операция Описание
Сложение
Вычитание
Умножение
Деление
78 Урок7

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

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

Что такое функция


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

Проблемы с функциями
Перед тем как начать урок и рассмотреть примеры, об-
ращаю ваше внимание на то, что использование SQL-
функций может быть проблематичным.
В отличие от SQL-операторов (например, SELECT), кото-
рые в основном поддерживаются всеми СУБД одинаково, в
разных СУБД могут применяться различные функции.
Только некоторые функции в различных СУБД выполняют-
ся одинаково. И хотя все типы функций обычно доступны в
80 Урок 8

каждой СУБД, реализация этих функций может значитель-


но отличаться. Чтобы стало понятно, насколько это может
быть проблематичным, в табл. 8.1 перечислены три наибо-
лее часто используемые функции и их синтаксис в различ-
ных СУБД.
Таблица 8 . 1 . Различия в функциях СУБД
Функция Синтаксис
Выборка части строки В Access используется функция
MID ( ) . В DB2, Oracle и PostgreSQL ис-
пользуется функция SUBSTR () .
В MySQL, SQL Server и Sybase —
SUBSTRING()
Преобразование типа В Access и Oracle используются не-
данных сколько функций, по одной на каждый
тип преобразования. В DB2 и
PostgreSQL используется функция
CAST ( ) . В MySQL, SQL Server и Sybase
используется функция CONVERT ()
Получение текущей В Access используется функция NOW ( ) .
даты В DB2 и PostgreSQL — CURRENT_DATE.
В MySQL используется функция
CURDATE () . В Oracle — SYSDATE.
В SQL Server и Sybase — GETDATE ()

Как видите, в отличие от SQL-операторов, SQL-функции


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

,. Переносимый код
Код, который может работать в разных системах.

Учитывая переносимость кода, многие SQL-програм-


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

Стоит ли использовать функции?


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

Использование функций
В большинстве реализаций SQL поддерживаются сле-
дующие типы функций.
• Текстовые функции; используются для управления
текстовыми строками (например, для обрезания или
заполнения значений и преобразования значений в
верхний или нижний регистр).
• Числовые функции; используются для выполнения
математических операций над числовыми данными
(например, для вычисления абсолютных значений и
выполнения алгебраических вычислений).
• Функции даты и времени; используются для управ-
ления значениями даты и времени и для выборки от-
дельных частей этих значений (например, для воз-
вращения разницы между датами и проверки даты на
корректность).
• Системные функции; возвращают информацию, спе-
цифичную для используемой СУБД (например, воз-
вращают регистрационную информацию пользователя).
В предыдущем уроке встречалась функция, которая ис-
пользовалась в списке столбцов выражения SELECT, но это
допустимо не для всех функций. Функции можно использо-
вать как в других частях оператора SELECT (например, в
условии WHERE), так и в других SQL-операторах (об этом вы
узнаете в дальнейших уроках).
82 Урок 8

Функции манипулирования текстом


В примере функций манипулирования текстом в седь-
мом уроке функция RTRIM () использовалась для удаления
пробелов в конце значения столбца. Ниже приведен еще
один пример, в котором используется функция UPPER ():
ВВОД
SELECT vend_name UPPER(vend_name) AS vend_name_upcase
FROM Vendors
ORDER BY vend name;

ВЫВОД
vend name vend_name_upcase

Bear Emporium BEAR EMPORIUM


Beras R Us BERAS R US
Doll House Inc. DOLL HOUSE INC.
Fun and Games FUN AND GAMES
Furball Inc. FURBALL INC.
Jouets et ours JOUETS ET OURS

Анализ
Функция UPPER () преобразует текст в верхний регистр
и, таким образом, в этом примере имя каждого изготовите-
ля перечислено дважды: первый раз в таком виде, в каком
оно хранится в таблице Vendors, а второй раз — будучи
преобразованным в верхний регистр, в виде столбца
vend_name_upсase.
В табл. 8.2 перечислены наиболее часто используемые
функции манипулирования текстом.
Один элемент из табл. 8.2 требует более подробного объ-
яснения. SOUNDEX — это алгоритм, преобразующий тексто-
вую строку в буквенно-цифровой шаблон, описывающий
фонетическое представление данного текста. Функция
SOUNDEX берет в расчет похожие по звучанию буквы и сло-
ги, позволяя сравнивать строки не по тому, как они пишут-
ся, а по тому, как они звучат. Хотя SOUNDEX не подпадает
под основные концепции SQL, большинство СУБД осущест-
вляют поддержку этой функции.
Использование функций манипулирования данными 83

Таблица 8.2. Наиболее часто используемые функции


манипулирования текстом

Функция Описание
LEFT () (или функция под- Возвращает символы из левой час-
строки) ти строки
LENGTH (а т а к ж е Возвращает длину строки
DATALENGTH () и л и LEN () )
LOWER () Преобразует строку в нижний ре-
гистр
LTRIM () (LCASE () в Access) Удаляет пробелы в левой части
строки
RIGHT () ( и л и ф у н к ц и я Возвращает символы из правой
подстроки) части строки
Удаляет пробелы в правой части
RTRIM() строки
Возвращает значение SOUNDEX
SOUNDEX () строки
Преобразует текст строки в верх-
UPPER () (UCASE в Access) ний регистр

Поддержка SOUNDEX
Функция S O U N D E X (). не поддерживается Microsoft
Access или PostgreSQL, поэтому следующий пример
не будет работать в этих СУБД.

Ниже приведен пример использования функции


SOUNDEX (). Клиент Kids Place находится в таблице
Customers и имеет контактное лицо Michelle Green. Но
что, если это опечатка и на самом деле контактное лицо
пишется как Michael Green? Очевидно, поиск по коррект-
ному имени ничего не даст, это показано ниже:

ВВОД
SELECT cust_name cust_contract
FROM Customers
WHERE cust contract = 'Michael Green1
84 Урок 8

ВЫВОД
cust name cust contract

А теперь попробуйте выполнить поиск при помощи


функции SOUNDEX (), чтобы найти все имена контактных
лиц, которые звучат как Michael Green:
ВВОД
SELECT cust_name cust_contract
FROM Customers
WHERE SOUNDEX(cust_contract) = SOUNDEX('Michael
1
OGreen ) ;

ВЫВОД
cust_name cust_contract

Kids Place Michelle Green

Анализ
В этом примере в предложении WHERE используется
функция SOUNDEX () для преобразования значения столбца
cust_contact и искомой строки в их SOUNDEX-значения.
Так как Michael Green и Michelle Green звучат одина-
ково, их SOUNDEX-значения совпадут и предложение WHERE
корректно отфильтрует необходимые данные.

Функции манипулирования датой


и временем
Дата и время хранятся в таблицах с использованием со-
ответствующих типов данных, каждая СУБД использует
свои собственные типы. Значения даты и времени хранятся
в специальном формате, поэтому их можно быстро и эф-
фективно сохранить или отфильтровать, а также сохранить
физическое пространство на диске.
Формат, в котором хранятся дата и время, обычно нель-
зя использовать в приложениях, поэтому почти всегда ис-
пользуются функции даты и времени для чтения, расшире-
ния и манипулирования этими значениями. Функции ма-
нипулирования датой и временем являются одними из
наиболее важных функций в SQL. К сожалению, они мень-
Использование функций манипулирования данными 85

ше всего поддаются переносу на другие платформы и реа-


лизации SQL.
Чтобы продемонстрировать процедуру использования
функции манипулирования датой и временем, приведем
простой пример. В таблице Orders все заказы хранятся с
датой заказа. Чтобы извлечь список всех заказов, сделан-
ных в 2 004 году, в SQL Server и Sybase необходимо выпол-
нить следующее:

ВВОД
SELECT order_num
FROM Orders
WHERE DATEPART(yy, order_date) = 2004;

ВЫВОД
order num

20005
20006
20007
20008
20009
В Access используйте следующую версию примера:
ВВОД
SELECT order_num
FROM Orders
WHERE DATEPART('yyyy*, order_date) = 2004;

Анализ
В этом примере (в версиях для SQL Server и Sybase и в
Access) используется функция DATE PART (), которая, как
видно из названия, возвращает только часть даты. В функ-
ции DATE PART () используются два параметра: часть, подле-
жащая возвращению, и дата, из которой эта часть возвраща-
ется. В рассматриваемом примере функция DATEPARTO из
столбца order_column возвращает только год. Путем срав-
нения полученного значения со значением 2 004 предложе-
ние WHERE выбирает только те заказы, которые были сдела-
ны в этом году.
Ниже приведена версия данного примера для PostgreSQL,
в которой используется похожая функция DATE_PART ():
86 Урок 8

ВВОД
SELECT order_num
FROM Orders
WHERE DATE_PART('year• , order_date) = 2004;
В MySQL, помимо DATEPARTO, есть множество других
функций, предназначенных для манипулирования значе-
ниями дат. Пользователи MySQL могут использовать функ-
цию YEAR () для выборки из даты значения года:

ВВОД
SELECT order_num
FROM Orders
WHERE YEAR(order_date) = 2004;
В Oracle также нет функции DATE PART (), но существуют
несколько других функций манипулирования датой, кото-
рые можно использовать с этой же целью. Рассмотрим
пример:

ВВОД
SELECT order_num
FROM Orders
WHERE t o number(to c h a r ( o r d e r date, •YY 1 )) = 2004;

Анализ
В этом примере функция to_char () используется для
извлечения части даты, а функция to_number() — для
преобразования этой части в числовое значение, чтобы его
можно было сравнить со значением 2 004.
Тех же результатов можно добиться при помощи опера-
тора BETWEEN:

ВВОД
SELECT order_num
FROM Orders
WHERE o r d e r _ d a t e BETWEEN to_date('01-JAN-2004
AND t o d a t e ( ' 3 1 - D E C - 2 0 0 4 ' ) ;

Анализ
В этом примере функция Oracle to_date () используется
для преобразования двух строк в даты. В одной содержится
дата 1 января 2004, а в другой — 31 декабря 2004. Стан-
Использование функций манипулирования данными 87

дартный оператор BETWEEN используется для поиска всех


заказов, сделанных в период между этими двумя датами.
Этот код не будет работать в SQL Server, так как в этой
СУБД не поддерживается функция to_date (). Однако если
заменить функцию to_date () функцией DATAPART (), этот
оператор можно будет использовать.

Даты в Oracle
Даты в формате ДД-МММ-ГГГГ (как в предыдущих
примерах) системой Oracle обычно обрабатываются,
даже если они не приведены к тому виду, как при ис-
пользовании функции to_date.•(•)... Однако для надеж-
ности лучше всегда использовать эту функцию.

В приведенных примерах выбиралась и использовалась


только часть даты (год). Чтобы выбрать заказы по месяцу,
необходимо сделать то же самое, указав ключевое слово AND
для сравнения месяца и года.
СУБД обычно могут выполнять гораздо больше дейст-
вий, чем просто выборка части даты. В большинстве из них
присутствуют функции для сравнения дат, выполнения
простых арифметических операций с датами, опции форма-
тирования дат и многое другое. Но, как вы уже заметили,
функции манипулирования датой и временем различны для
разных СУБД. Обратитесь к документации по своей СУБД и
уточните, какие функции манипулирования датой и време-
нем в ней поддерживаются.

Функции для манипулирования


числами
Числовые функции предназначены для манипулирова-
ния числовыми данными. Эти функции используются толь-
ко для алгебраических, тригонометрических и геометриче-
ских вычислений, поэтому они используются не так часто,
как функции манипулирования датой и временем.
По иронии судьбы среди всех функций в большинстве
СУБД именно числовые функции наиболее стандартизиро-
ваны. В табл. 8.3 перечислены наиболее часто используе-
мые функции манипулирования числовыми данными.
88 Урок 8

Таблица 8.3. Наиболее часто используемые функции


манипулирования числами
Функция Описание
ABS () Возвращает абсолютное значение числа
COS () Возвращает косинус указанного угла
ЕХР () Возвращает экспоненту указанного числа
PI () Возвращает значение числа пи
SIN () Возвращает синус указанного угла
SQRT () Возвращает квадратный корень указанного числа
TAN () Возвращает тангенс указанного угла

Обратитесь к документации по вашей СУБД, чтобы оп-


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

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

Суммирование данных
В этом уроке вы узнаете, что такое статистические SQL-
функции и как их можно использовать для суммирования
данных таблицы

Использование статистических
функций
Часто бывает необходимо просуммировать данные без их
выборки, и в SQL предусмотрены для этого специальные
функции. SQL-запросы с этими функциями часто исполь-
зуются с целью выборки данных для анализа и создания
отчетов. Примерами таких выборок могут послужить:
• определение числа строк в таблице (либо числа строк,
которые удовлетворяют какому-то условию или со-
держат определенное значение);
• получение суммы по набору строк в таблице;
• поиск наибольшего, наименьшего и среднего значе-
ний из столбца таблицы (из всех или из каких-то
конкретных строк).
В каждом из этих примеров необходимы какие-то итого-
вые данные по таблице, а не сами данные. Поэтому воз-
вращение реальных данных таблицы было бы пустой тра-
той времени и ресурсов (не говоря о пропускной способно-
сти сети). Итак, все, что вам нужно, — это только итоговая
информация.
Чтобы облегчить такой способ извлечения информации,
в SQL предусмотрен набор из пяти статистических функ-
ций, которые перечислены в табл. 9.1. Эти функции позво-
ляют выполнять все варианты выборки, которые были пе-
речислены выше. В отличие от функций манипулирования
данными из предыдущего урока, статистические SQL-
90 Урок 9

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


шинстве реализаций SQL.
Статистические (итоговые) функции
Функции, обрабатывающие набор строк для подсчета
и возвращения одного значения.

Таблица 9 . 1 . Статистические SQL-функции


Функция Описание
AVG () Возвращает среднее значение столбца
COUNT () Возвращает число строк в столбце
МАХ () Возвращает самое большое значение в столбце
MIN () Возвращает самое маленькое значение в столбце
SUM () Возвращает сумму значений столбца

Способы использования каждой из этих функций рас-


сматриваются в следующих разделах.

Функция AVG ()
Функция AVG () используется для возвращения среднего
значения определенного столбца путем подсчета числа строк
в таблице и суммирования их значений. Эту функцию можно
использовать для возвращения среднего значения всех
столбцов или определенных столбцов или строк.
В первом примере функция AVG () исользуется для возвра-
щения средней цены для всех продуктов таблицы Products:
ВВОД
SELECT AVG(prod_price) AS avg_jprice
FROM P r o d u c t s ;

ВЫВОД
avg_price
6.823333
Суммирование данных 91

Анализ
Выражение SELECT, приведенное выше, возвращает одно
значение, avg_price, в котором содержится средняя цена
всех продуктов таблицы Products. Здесь avg_price — это
псевдоним, описанный в уроке 7, "Создание вычисляемых
полей."
Функцию AVG () можно также использовать для нахож-
дения среднего значения определенных столбцов или строк.
В следущем примере возвращается средняя цена продуктов,
предлагаемых определенным поставщиком:
ВВОД
SELECT AVG(prod_price) AS avg_j>rice
FROM Products
WHERE v e n d i d = ' D L L 0 1 1 ;

ВЫВОД
avg_price
6.8650

Анализ
Этот оператор SELECT отличается от предыдущего толь-
ко тем, что в нем содержится предложение WHERE. В соот-
ветствии с предложением WHERE выбираются только те на-
именования продуктов, значение vend_id для которых
равно DLL01, поэтому значение, возвращенное в столбце с
псевдонимом avg_price, является средним только для
продуктов этого изготовителя.
Только отдел ьн ые столбцы
Функцию AVGO можно использовать только для
вычисления среднего значения определенного
числового столбца, имя этого столбца должно быть
указано в качестве параметра функции. Чтобы
получить среднее значение нескольких столбцов,
необходимо использовать несколько функций AVG ( ) .
92 Урок 9

Значения NULL
Строки столбца, с о д е р ж а щ и е значения N U L L , игнори-
руются функцией A V G ( ) .

Функция COUNT ()
Функция COUNT () подсчитывает число строк. При по-
мощи функции COUNT () можно узнать общее число строк в
таблице или число строк, удовлетворяющих определенному
критерию.
Эту функцию можно использовать двумя способами:
• В виде COUNT {*) для подсчета числа строк в таблице
независимо от того, содержат столбцы значения NULL
или нет.
• В виде COUNT (column) для подсчета числа строк, ко-
торые имеют значения в указанных столбцах, причем
значения NULL игнорируются.
В первом примере возвращается общее число имен кли-
ентов, содержащихся в таблице Customers:
ВВОД
SELECT COUNT(*) AS num_cust
FROM Cu s t ome r s;

ВЫВОД
num_cust

Анализ
В этом примере функция COUNT (*) используется для
подсчета всех строк независимо от их значений. Сумма воз-
вращается в переменную num_cust.
В следующем примере подсчитываются только клиенты,
имеющие адреса электронной почты:
ВВОД
SELECT COUNT(cust_email) AS num_cust
FROM Customers;
Суммирование данных 93

ВЫВОД
num_cust
3

Анализ
В этом выражении SELECT используется функция
COUNT (cust_email) для подсчета только строк, имеющих
ненулевое значение в столбце cust_email. В этом примере
значение cust_email равно 3 (это означает, что только 3 из
5 клиентов имеют адрес электронной почты).

Значения NULL
Строки столбцов со значениями N U L L игнорируются
функцией C O U N T ( ) , если указано и м я с т о л б ц а м и
учитываются, если используется звездочка (*).

Функция МАХ ()
Функция МАХ () возвращает самое большое значение из
указанного столбца. Для этой функции необходимо указы-
вать имя столбца, как это показано ниже:
ВВОД
SELECT MAX(prod_price) AS max_price
FROM Products;

ВЫВОД
max_price

11.9900

Анализ
Здесь функция MAX () возвращает цену наиболее дорого-
го продукта в таблице Products.
94 Урок 9

Использование функции М А Х ( ) С нечисловыми


данными
Несмотря на то что функция МАХ {) обычно использу-
ется для поиска наибольшего числового значения или
даты, многие (но не все) СУБД позволяют использо-
вать ее для возвращения наибольшего значения из
всех столбцов, включая текстовые. При использова-
нии с текстовыми данными функция МАХ (} возвраща-
ет строку, которая была бы последней, если бы дан-
ные были отсортированы по этой строке.

Значения NULL
Строки столбцов с о значениями N U L L игнорируются
функцией МАХ ( ) .

Функция MIN ()
Функция MIN () производит противоположное по отно-
шению к МАХ () действие — она возвращает наименьшее
значение в указанном столбце. Так же, как и для функции
МАХ ( ) , для MIN () требуется указать имя столбца, как пока-
зано ниже:

ВВОД
SELECT MIN(prod_price) AS min_price
FROM Products;

ВЫВОД
min_pnce

3.4900

Анализ
Здесь MIN () возвращает цену самого дешевого продукта
в таблице P r o d u c t s .
Суммирование данных 95

Использование функции M I N ( ) С нечисловыми


данными
Несмотря на то что функция W I N О обычно использу-
ется для поиска наименьшего числового значения
или даты, многие (но не все) СУБД позволяют исполь-
зовать ее для возвращения наименьшего значения из
всех столбцов, включая текстовые. При использова-
нии с текстовыми данными функция M I N () возвраща-
ет строку, которая была бы первой, если бы данные
были отсортированы по этой строке.

З н а ч е н и я N U L L

Строки столбцов со значениями N U L L игнорируются


функцией мш О.

Функция SUMO
Функция SUM() возвращает сумму (общую) значений в
определенном столбце.
Ниже приведен пример, демонстрирующий это действие.
В таблице Orderltems содержатся предметы заказа, при-
чем каждому предмету соответствует определенное количе-
ство заказов. Общее число заказанных продуктов (сумма
всех значений переменной quantity) может быть выбрана
следующим образом:
ВВОД
SELECT SUM(quantity) AS item_ordered
FROM Orderltems
WHERE order item = 20005;

ВЫВОД
item_ordered

200
96 Урок 9

Анализ
Функция SUM (quantity) возвращает сумму всех пред-
метов заказа, а предложение WHERE гарантирует, что учи-
тываться будут только необходимые продукты.
ВВОД
SELECT SUM(item_price*quantity) AS total_price
FROM OrderIterns
WHERE order item = 20005;

ВЫВОД
total_price

1648.0000
Функция SUM(item_price*quantity) возвращает сум-
му всех цен в заказе, а предложение WHERE гарантирует,
что учитываться будут только необходимые продукты.

Вычисления с несколькими столбцами


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

З н а ч е н и я N U L L

Строки столбцов с о значениями N U L L и г н о р и р у ю т с я


функцией SUM ( ) .

Статистические вычисления
для отдельных значений
Все пять статистических функций могут быть использо-
ваны двумя способами:
• для вычисления во всех строках при указании аргу-
мента ALL или без указания какого-либо аргумента
(так как ALL является аргументом по умолчанию);
Суммирование данных 97

для указания отдельных значении при помощи аргу-


мента DISTINCT.

ALL по умолчанию

Аргумент A L L не обязательно указывать, так как он


является аргументом по умолчанию. Если не указан
аргумент D I S T I N C T , TO подразумевается аргумент
A L L . • .. . .-•/" ' •• :• • ' - . - • •'

Не в Access
Microsoft Access не поддерживает использование
аргумента D I S T I N C T В статистических функциях,
поэтому следующий пример не будет работать в
Access.

В следующем примере используется функция AVG () для


возвращения средней цены продуктов, предлагаемых опре-
деленным поставщиком. Это такой же оператор SELECT,
как и предыдущий, но с использованием ключевого слова
DISTINCT — при вычислении среднего значения учитыва-
ются только определенные цены.
ВВОД
SELECT AVG(DISTINCT prod_price) AS avg_price
FROM Products
WHERE v e n d i d = ' L L 0 1 ' ;

ВЫВОД
avg_price

4.2400

Анализ
В этом примере вследствие использования ключевого
слова DISTINCT значение avg_j?rice получается более вы-
соким, так как в таблице есть несколько предметов с оди-
наково низкой ценой. Не учитывая их, мы получаем более
высокую среднюю стоимость.
98 Урок 9

Внимание
Ключевое слово D I S T I N C T МОЖНО использовать С
функцией COUNT (} только в том случае, если указано
имя столбца. Его нельзя использовать с функцией
C O U N T ( * ) . Аналогично, D I S T I N C T нужно использо-
вать С именем столбца, но не с выражением.

Использование ключевого слова DISTINCT с


функциями M I N () и МАХ ()
Несмотря на то что ключевое слово D I S T I N C T техни-
чески можно использовать с функциями MIN{) и
М А Х ( ) , реальной необходимости в этом нет. Мини-
мальные и максимальные значения в столбце будут
теми же, независимо от того, указаны определенные
значения или нет.

Предикаты
Помимо ключевых слов D I S T I N C T И A L L , некоторые
СУБД поддерживают предикаты, такие как ТОР И ТОР
PERCENT, позволяющие выполнять действия над
подмножествами результатов запроса. Обратитесь к
документации вашей СУБД, чтобы точно узнать, какие
предикаты вы можете использовать.

Комбинирование
статистических функций
Во всех примерах применения статистических функций,
приведенных до сих пор, указывалась только одна функ-
ция. Но на самом деле операторы SELECT могут содержать
столько статистических функций, сколько нужно. Рассмот-
рим пример:
Суммирование данных 99

ВВОД
SELECT COUNT(*) AS num_items,
MIN(prodjprice) AS price_min,
1У1АХ (prod_price) AS price_max,
AVG(prod_price) AS proce_avg
FROM Products;

ВЫВОД
num items price_min price__max price_avg
3.4900 11.9900 6.823333

Анализ
В одном операторе SELECT используются сразу четыре
статистические функции и возвращаются четыре значения
(число элементов в таблице Products, самая высокая, са-
мая низкая и средняя их стоимость).
Псевдонимы
При указании псевдонимов для хранения результатов
статистической функции старайтесь не использовать
реальных названии столбцов в таблице, поскольку во
многих реализациях SQL такое поведение не привет-
ствуется — вы получите сообщение об ошибке.

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

Итоговые данные
В этом уроке вы узнаете, как получать итоговые данные
таким образом, чтобы можно было суммировать подмножест-
ва из содержимого таблицы. Для этого используются два но-
вых предложения оператора SELECT, предложение GROUP BY
и предложение HAVING.

Получение итоговых данных


Из предыдущего урока вы узнали, что статистические
функции SQL можно использовать для суммирования дан-
ных. Это позволяет подсчитывать число строк, вычислять
суммы и средние значения, а также получать наибольшее и
наименьшее значения, не прибегая к выборке всех данных.
Все эти вычисления до сих пор выполнялись над всеми
данными таблицы или над данными, которые соответство-
вали указанному предложению WHERE. В качестве напоми-
нания приведем пример, в котором возвращается количест-
во продуктов, предлагаемых поставщиком DLL01:
ВВОД
SELECT COUNT(*) AS num_prods
FROM Products
WHERE v e n d i d = ' D L L O l ' ;

ВЫВОД
num_j?rods

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


предлагаемых каждым поставщиком? Или выяснить, какие
поставщики предлагают только один продукт, или, наобо-
рот, несколько продуктов?
102 Урок 10

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


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

Создание групп
Группы создаются с помощью предложения GROUP BY
оператора SELECT.
Лучше всего это можно объяснить на примере:
ВВОД
SELECT vend_id, COUNT(*) AS numjprods
FROM Products
GROUP BY vend id;

ВЫВОД
vend id num_prods

BRS01
DLL01
FNG01

Анализ
Вышеприведенный оператор SELECT предписывает вы-
вести два столбца —vend_id, содержащий идентификатор
поставщика продукта, и num_prods, содержащий вычис-
ляемые поля (он создается с помощью функции COUNT (*)).
Предложение GROUP BY указывает СУБД сортировать дан-
ные и группировать их по столбцу vend_id. В результате
значение num_prods будет вычисляться по одному разу для
каждой группы записей vend_id, а не один раз для всей
таблицы products. Как видите, в результатах указывается,
что поставщик BRS01 предлагает три продукта, поставщик
DLL01 — четыре продукта, а поставщик FNG01 — 2 продукта.
Поскольку было использовано предложение GROUP BY,
не потребовалось указывать каждую группу, для которой
должны быть произведены вычисления. Это было сделано
автоматически. Предложение GROUP BY указывает СУБД
группировать данные и затем выполнять вычисление по
каждой группе, а не по всему набору результатов.
Итоговые данные 103

Прежде чем использовать предложение GROUP BY, озна-


комьтесь с важными правилами, которыми необходимо ру-
ководствоваться .
• В предложениях GROUP BY можно указывать столько
столбцов, сколько вам необходимо. Это позволяет
вкладывать группы одна в другую, благодаря чему
обеспечивается тщательный контроль за тем, какие
данные подлежат группированию.
• Если вы используете вложенные группы в предложе-
нии GROUP BY, данные суммируются для последней
указанной вами группы. Другими словами, если вве-
дено группирование, вычисления осуществляются для
всех указанных столбцов (вы не сможете вернуть
данные для каждого отдельного столбца).
• Каждый столбец, указанный в предложении
GROUP BY, должен быть столбцом выборки или вы-
ражением (но не функцией группирования). Если в
операторе SELECT используется какое-то выражение,
то же самое выражение должно быть указано в пред-
ложении GROUP BY. Псевдонимы применять нельзя.
• В большинстве реализаций SQL нельзя указывать в
предложении GROUP BY столбцы, в которых содер-
жатся данные переменной длины (т.е. столбцы, со-
держащие текстовые поля или поля комментариев).
• За исключением операторов статистических вычисле-
ний, каждый столбец, упомянутый в операторе
SELECT, должен быть представлен в предложении
GROUP BY.
• Если столбец, подлежащий группированию, содержит
строку со значением NULL, оно будет возвращено в
качестве группы. Если имеется несколько строк со
значениями NULL, они будут сгруппированы вместе.
• Предложение GROUP BY должно следовать после пред-
ложения WHERE и до какого-либо предложения
ORDER BY.

ПредложениеA L L

В некоторых реализациях SQL (например, в Microsoft


SQL Server) опционально поддерживается предложе-
104 Урок 10

ние A L L в предложении GROUP BY. Это предложение


можно использовать для возвращения всех групп,
даже тех, которые не имеют соответствующих строк
(в этом случае функция группирования возвращает
значение NULL). Обратитесь к документации своей
СУБД, чтобы узнать, поддерживает ли она предложе-
:
ние A L L . V- •.. / [•• - . : ..-.;:

Указание столбцов по их относительному поло-


жению
Некоторые реализации SQL позволяют указывать
столбцы в п р е д л о ж е н и и GROUP B Y по их п о л о ж е н и ю в
списке SELECT. Например, выражение GROUP BY 2,1
может означать группирование по выбранному вто-
рому столбцу и затем по первому/Хотя этот "стено-
графический" синтаксис удобен, он поддерживается
не всеми реализациями SQL. Его применение также
является рискованным в том смысле, что весьма вы-
сока вероятность появления ошибок при редактиро-
вании операторов SQL.

Фильтрующие группы
В дополнение к способности группировать данные с по-
мощью предложения GROUP BY, SQL также позволяет осу-
ществлять фильтрацию — указывать, какие группы долж-
ны быть включены в результат, а какие исключены из не-
го. Например, вам может понадобиться список клиентов,
которые сделали хотя бы два заказа. Чтобы получить такие
данные, необходим фильтр, относящийся к целой группе, а
не к отдельным строкам.
Вы уже знаете, как действует предложение WHERE (его
мы рассматривали ранее, в уроке 4, "Фильтрация данных").
Однако в данном случае предложение WHERE использовать
нельзя, поскольку фильтры WHERE указывают строки, а не
группы. Собственно говоря, WHERE "не знает", что такое
группы.
Итоговые данные 105

Но тогда что можно использовать вместо предложения


WHERE? SQL предлагает другое предложение, подходящее
для этих целей: предложение HAVING. Предложение HAVING
очень похоже на предложение WHERE. И действительно, все
типы выражений в предложении WHERE, с которыми вы
уже знакомы, могут быть также использованы с предложе-
нием HAVING. Единственная разница состоит в том, что
WHERE фильтрует строки, a HAVING — группы.

Предложение HAVING МОЖНО использовать со


всеми операторами
Из уроков 4 и 5 вы знаете, как можно применять
предложение WHERE (включая использование мета-
символов и логических операций). Все эти методы и
опции могут быть применены и по отношению к
HAVING. Синтаксис такой же, отличаются только клю-
чевые слова.

Вспомним, как фильтруются строки. Посмотрите на сле-


дующий пример.

ввод
SELECT cust_id, COUNT(*) AS orders
FROM Orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;

ВЫВОД
cust_id orders

1000000001 2

Анализ
Первые три строки этого оператора SELECT аналогичны
оператору, рассмотренному ранее. Последняя строка добав-
ляет к нему предложение HAVING, которое фильтрует эти
группы с помощью функции COUNT (*) >= 2 — два или
больше заказов.
Как видите, предложение WHERE здесь не работает, по-
скольку фильтрация основана на итоговом значении груп-
пы, а не на значениях указанных строк.
106 Урок 10

Разница между HAVING и WHERE


Вот как это м о ж н о рассматривать: WHERE фильтрует
д о того, как данные будут с г р у п п и р о в а н ы , a H A V I N G
фильтрует после того, как данные были сгруппирова-
ны. Это— важное различие; строки, которые были
выброшены по предложению WHERE, не будут включе-
ны в группу, иначе это могло бы изменить вычисляе-
мые значения, которые, в свою очередь, могли бы по-
влиять на фильтрацию групп в предложении HAVING.

А теперь подумаем: возникает ли необходимость в ис-


пользовании как предложения WHERE, так и предложения
HAVING в одном операторе?
Конечно, возникает. Предположим, вы хотите усовер-
шенствовать фильтр предыдущего оператора таким обра-
зом, чтобы он возвращал имена всех клиентов, которые
сделали два или больше заказов за последние 12 месяцев.
Чтобы добиться этого, вы можете добавить предложение
WHERE, которое берет во внимание только заказы, сделан-
ные в последние 12 месяцев. Затем вы добавляете предло-
жение HAVING, чтобы отфильтровать только те группы, в
которых имеются две или больше строк.
Чтобы лучше разобраться в этом, рассмотрим следую-
щий пример, где перечисляются все поставщики, которые
предлагают несколько продуктов по цене 4 и более за еди-
ницу:
ВВОД
SELECT vend_id, COUNT(*) AS num_prods
FROM Products
WHERE prod_price >= 4
GROUP BY vend_id
HAVING COUNT(*) >= 2;

ВЫВОД
vend id num_jprods

BRS01 3
FNG01 2
Итоговые д а н н ы е 107

Анализ
Этот пример нуждается в пояснении. Первая строка
представляет собой основной оператор SELECT, использую-
щий статистическую функцию, — точно так же, как в пре-
дыдущих примерах. Предложение WHERE фильтрует все
строки со значениями в столбце prod_price не менее 4.
Затем данные группируются по столбцу vend_id, а потом
предложение HAVING фильтрует только группы, содержа-
щие не менее двух членов. При отсутствии предложения
WHERE была бы получена лишняя строка (поставщик, пред-
лагающий 4 продукта, каждый из которых дешевле 4), как
показано ниже.
ВВОД
SELECT vend_id, COUNT(*) AS num_prods
FROM Products
GROUP BY vend_id
HAVING COUNT(*) >= 2;

ВЫВОД
vend id num_prods

BRS01
DLL01
FNG01

Использование п р е д л о ж е н и й H A V I N G И WHERE

Предложение H A V I N G так похоже на предложение


WHERE, что в большинстве СУБД оно трактуется точно
так ж е , если только не указано никакое предложение
GROUP B Y . И все ж е вы д о л ж н ы знать, что между н и м и
существует разница. Используйте предложение
H A V I N G только вместе с предложениями GROUP BY, a
предложение W H E R E — для стандартной фильтрации
на уровне строк.
108 Урок 10

Группирование и сортировка
Важно понимать, что предложения GROUP BY и ORDER
BY весьма различны, хотя с их помощью иногда можно до-
биться одинаковых результатов. Разобраться в этом вам
поможет табл. 10.1.
Таблица 1 0 . 1 . Сравнение предложений ORDER BY И
GROUP BY

ORDER BY GROUP BY
Сортирует полученные ре- Группирует строки. Однако ото-
зультаты бражаемый результат может не
соответствовать порядку группи-
рования
Могут быть использованы Могут быть использованы только
любые столбцы (даже не выбранные столбцы или выраже-
выбранные в предложении ния; должно быть использовано
SELECT) выражение для каждого выбран-
ного столбца
Не является необходимым Требуется, если используются
столбцы (или выражения) со ста-
тистическими функциями

Первое из отличий, перечисленных в табл. 10.1, являет-


ся очень важным. Чаще всего вы обнаружите, что данные,
сгруппированные с помощью предложения GROUP BY, будут
отображаться в порядке группирования. Но так будет не
всегда, и в действительности это не требуется в специфика-
циях SQL. Более того, даже если ваша СУБД сортирует
данные так, как указано в предложении GROUP BY, вам
вдруг может понадобиться отсортировать их по-другому.
То, что вы группируете данные одним способом (чтобы по-
лучить для группы указанные итоговые значения), не озна-
чает, что желанный для вас результат должен быть отсор-
тирован именно так. Следует использовать явным образом
предложение ORDER BY, даже если результат его примене-
ния будет совпадать с результатом использования предло-
жения GROUP BY.
Итоговые данные 109

Не забывайте использовать предложение ORDER BY


Как правило, каждый раз, когда вы используете пред-
ложение GROUP BY, приходится указывать и предло-
жение ORDER BY. Это — единственный способ, гаран-
тирующий, что данные будут отсортированы правиль-
но. Не следует надеяться на то, что ваши данные
отсортирует предложение GROUP B Y .

Чтобы вы могли понять, как следует использовать совме-


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

ВВОД
SELECT order_num, COUNT(*] AS items
FROM OrderIterns
GROUP BY order_num
HAVING COUNT(*) >= 3;

ВЫВОД
order num items
20006
20007
20008
20009
Чтобы отсортировать результат по количеству заказан-
ных предметов, все, что вам необходимо сделать, — это до-
бавить предложение ORDER BY, как показано ниже:

ВВОД
SELECT order_num, COUNT(*) AS items
FROM OrderIterns
GROUP BY order_num
HAVING COUNT(*) >= 3;
ORDER BY items, order num;
110 Урок 10

Несовместимость с Access
f f СУБД Microsoft Access не позволяет осуществлять
сортировку по псевдонимам, и для нее этот пример
неприменим. Выход состоит в замене столбца items
(в предложении ORDER BY) вычисляемым выражени-
ем или номером поля. По существу, будут работать
оба предложения, ORDER B Y C O U N T (*}', o r d e r _ n u m

И ORDER BY 1 , o r d e r num.

ВЫВОД
order num items
20006
20009
20007
20008

Анализ
В этом примере предложение GROUP BY используется
для группирования данных по номеру заказа (столбец
order_num), так что функция COUNT (*) может возвратить
количество предметов в каждом заказе. Предложение
HAVING фильтрует данные таким образом, что возвращают-
ся только заказы с тремя и более предметами. Наконец, ре-
зультат сортируется за счет использования предложения
ORDER BY.

Упорядочение предложения
SELECT
Предложения оператора SELECT указываются в опреде-
ленном порядке. В табл. 10.2 перечислены все предложе-
ния, которые мы изучили о сих пор, в порядке, в котором
они должны использоваться.
Итоговые данные 111

Таблица 1 0 . 2 .Предложения оператора S E L E C T


и последовательность их использования

Предложение Описание Необходимость


SELECT Столбцы и л и выра- Да
жения, которые
д о л ж н ы быть воз-
вращены
FROM Т а б л и ц а д л я возвра- Т о л ь к о если выбирают-
щения данных из... с я д а н н ы е из т а б л и ц ы
WHERE Ф и л ь т р а ц и я н а уров- Нет
не строк
GROUP BY Определение г р у п п ы Т о л ь к о если осуществ-
ляются статистические
в ы ч и с л е н и я по группе
HAVING Ф и л ь т р а ц и я н а уров-
не групп Нет

ORDER BY У п о р я д о ч и в а н и е ре-
зультатов с о р т и р о в к и Нет

Резюме
В уроке 9, "Суммирование данных," вы узнали, как ис-
пользовать статистические функции SQL для выполнения
операций суммирования над данными. В этом уроке расска-
зывалось о том, как нужно использовать предложение
GROUP BY для выполнения вычислений по отношению к
группам данных, возвращения результатов для каждой
группы. Было описано, как можно использовать предложе-
ние HAVING для фильтрации указанных групп, в уроке
также пояснялось, какова разница между ORDER BY и
GROUP BY и между предложениями WHERE и HAVING.
Урок 11

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

Что такое подзапросы


Операторы SELECT представляют собой запросы SQL. Все
операторы SELECT, с которыми мы имели дело до сих пор,
представляли собой простые запросы: посредством отдель-
ных операторов извлекались данные из отдельных таблиц
базы данных.

Запрос
Какой-либо оператор SQL. Однако этот термин обыч-
но используется по отношению к операторам SELECT.

Язык SQL позволяет также создавать подзапросы: запро-


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

Поддержка в MySQL
Если вы используете MySQL, знайте, что подзапросы
поддерживаются этой СУБД начиная с версии 4.1.
Более ранние версии MySQL запросы не поддержи-
вают.
114 Урок 11

Фильтрация посредством
подзапросов
Таблицы баз данных, используемые во всех уроках этой
книги, являются реляционными таблицами (см. приложе-
ние А, в котором описана каждая из таблиц и отношения
между ними). Заказы хранятся в двух таблицах. Таблица
O r d e r s (заказы) содержит по одной строке для каждого за-
каза; в ней указываются номер заказа, идентификатор кли-
ента и дата заказа. Предметы отдельного заказа хранятся в
соответствующей таблице O r d e r l t e m s . Таблица O r d e r s не
содержит информацию о клиентах. Она хранит только
идентификатор клиента. Информация о клиентах хранится
в таблице Customers (клиенты).
Теперь предположим, что вы хотите получить перечень
всех клиентов, которые заказали продукт RGAN01. Что
нужно сделать, чтобы получить эту информацию? Для это-
го нужно сделать следующее.
1. Выбрать номера всех заказов, в которых содержится
продукт RGAN01.
2. Выбрать идентификатор клиента для всех клиентов,
которые имеют заказы, перечисленные среди номеров
заказов, возвращенных на предыдущем шаге.
3. Выбрать информацию о клиенте для всех клиентов,
идентификаторы которых были возвращены на пре-
дыдущем шаге.
Каждый из этих шагов можно выполнить в виде отдель-
ного запроса. Делая это, вы используете результаты, воз-
вращенные одним оператором SELECT, чтобы заполнить
предложение WHERE для следующего оператора SELECT.
Вы можете также использовать подзапросы для того,
чтобы объединить все три запроса в один-единственный
оператор.
Первый оператор SELECT выбирает столбец order_num
для всех продуктов заказа, у которых в столбце p r o d _ i d
значится RGAN01. Результат представляет собой номера
двух заказов, содержащих этот предмет:
Использование подзапросов 115

ВВОД
SELECT order_num
FROM OrderIterns
1
WHERE prod_id = 'RGAN01

ВЫВОД
order_num

20007
20008
Следующий шаг состоит в выборке идентификаторов
клиентов, связанных с заказами 20007 и 20008. Используя
предложение IN, о котором говорилось в уроке 5, "Расши-
ренная фильтрация данных", вы можете создать такой опе-
ратор SELECT:
ВВОД
SELECT cust_id
FROM Orders
WHERE order num IN (20007,20008);

ВЫВОД
cust_id

1000000004
1000000005
Теперь объединим эти два запроса путем превращения
первого из них (того, который возвращает номера заказов)
в подзапрос. Посмотрите на следующий оператор SELECT:
ВВОД
SELECT c u s t _ i d
FROM O r d e r s
WHERE o r d e r _ n u m IN (SELECT o r d e r _ n u m
FROM O r d e r l t e m s
WHERE p r o d _ i d = 'RGAN01');

ВЫВОД
cust_id

1000000004
1000000005
116 Урок 11

Анализ
Подзапросы всегда обрабатываются, начиная с самого
внутреннего оператора SELECT в направлении "изнутри на-
ружу". При обработке предыдущего оператора СУБД в дей-
ствительности выполняет две операции.
Вначале она выполняет подзапрос:
SELECT order_nura FROM o r d e r i t e m s WHERE p r o d _ i d = ' R G A N 0 1 '
В результате выполнения этого запроса возвращается
два номера заказа, 20007 и 20008. Эти два значения затем
передаются в предложение WHERE внешнего запроса в фор-
мате с разделителем в виде запятой, необходимом для опе-
ратора IN. Теперь внешний запрос становится таким:
SELECT c u s t _ i d FROM o r d e r s WHERE order_num IN (20007,20008)
Как видите, результат корректен и точно такой же, как
полученный путем жесткого кодирования предложения
WHERE в предыдущем примере.

Форматируйте ваши SQL-запросы


Операторы S E L E C T , с о д е р ж а щ и е п о д з а п р о с ы , могут
оказаться трудными для чтения и устранения ошибок,
особенно если их сложность возрастает. Разбиение
запросов на многие строки и соответствующее обо-
значение строк, как показано ниже, значительно об-
легчит вашу работу с подзапросами.

Теперь у нас есть идентификаторы всех клиентов, зака-


завших продукт RG7AN01. Следующий шаг состоит в получе-
нии клиентской информации для каждого из этих иденти-
фикаторов клиентов. Оператор SQL, осуществляющий вы-
борку двух столбцов, таков:
ВВОД
SELECT cust_name, cust_contact
FROM Customers
WHERE cust_id IN ('1000000004', 4000000005');
Вместо жесткого указания идентификаторов клиентов
вы можете превратить данное предложение WHERE в подза-
прос:
Использование подзапросов 117

ВВОД
SELECT cust_name, cust_contact
FROM Customers
WHERE cust_id IN (SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
FROM Orderltems
WHERE prod_id = 'RGAN01'));

ВЫВОД
cust name cust contact

Fun4All Denise L. Stephens


The Toy Store Kim Howard
Чтобы выполнить вышеприведенное выражение SELECT,
СУБД должна в действительности выполнить три оператора
SELECT. Самый внутренний подзапрос возвращает перечень
номеров заказов, который затем используется как предло-
жение WHERE для подзапроса, внешнего по отношению к
данному. Этот подзапрос возвращает перечень идентифика-
торов клиентов, которые используются в предложении
WHERE запроса более высокого уровня. Запрос верхнего
уровня возвращает искомые данные.
Как видите, за счет использования подзапросов можно
создавать очень мощные и гибкие SQL-операторы. Не суще-
ствует ограничений на число подчиненных запросов, хотя
на практике вы можете столкнуться с тем, что снижение
производительности подскажет вам, что было использовано
слишком много уровней подзапросов.
Только один столбец
Операторы SELECT подзапроса могут выбирать толь-
ко один столбец. Попытка произвести выборку не-
скольких столбцов приведет к появлению сообщения
об ошибке.

Подзапросы и производительность
Представленные нами коды работают и приводят к
получению необходимых результатов. Однако подза-
118 Урок 11

просы — не всегда наиболее эффективный способ


выборки данных такого типа. Более подробно об этом
рассказано в уроке 12, "Объединение таблиц", в ко-
тором повторно будет рассмотрен этот же самый
пример.

Использование подзапросов
в качестве вычисляемых полей
Другой способ использования подзапросов состоит в ис-
пользовании вычисляемых полей. Предположим, вы хотите
вывести общее количество заказов, размещенных каждым
клиентом в таблице Customers (клиенты). Заказы хранятся
в таблице Orders вместе с соответствующими идентифика-
торами клиентов.
Чтобы выполнить эту операцию, необходимо сделать
следующее.
1. Выбрать перечень клиентов из таблицы Customers.
2. Для каждого выбранного клиента посчитать число его
заказов в таблице Orders.
Как следует из предыдущих двух уроков, вы можете ис-
пользовать оператор SELECT COUNT (*) для подсчета строк в
таблице, а используя предложение WHERE для фильтрации
идентификатора конкретного клиента, вы можете подсчи-
тать заказы только этого клиента. Например, посредством
следующего кода можно подсчитать количество заказов,
сделанных клиентом 1000000001:
ВВОД
SELECT COUNT(*) AS orders
FROM Orders
WHERE cust_id = '1000000001';
Чтобы получить итоговую информацию посредством
функции COUNT (*) для каждого клиента, используйте
COUNT* как подзапрос. Посмотрите на следующий код:
ВВОД
SELECT cust_name,
cust state,
Использование подзапросов 119

(SELECT COUNT(*)
FROM Orders
WHERE Orders.cust_id = Customers.cust_id) AS orders
FROM Customers
ORDER BY cust name;

ВЫВОД
cust name cust state orders

Fun4All IN 1
Fun4All AZ 1
Kids Place OH 0
The Toy Store IL
Village Toys MI 2

Анализ
Этот оператор SELECT возвращает три столбца для каж-
дого клиента из таблицы Customers: cust_name,
c u s t _ s t a t e и orders. Поле Orders является вычисляе-
мым; оно формируется в результате выполнения подзапро-
са, который заключен в круглые скобки. Этот подзапрос
выполняется один раз для каждого выбранного клиента.
В приведенном примере подзапрос выполняется пять раз,
потому что были выбраны имена пяти клиентов.
Предложение WHERE в подзапросе несколько отличается
от предложений WHERE, с которыми мы работали ранее, по-
тому что в нем используются полные имена столбцов. Сле-
дующее предложение требует от SQL, чтобы было проведено
сравнение значения cust_id в таблице Orders с тем, кото-
рое в данный момент выбирается из таблицы Customers:
WHERE Orders.cust_id = Customers.cust_id
Этот синтаксис — имя таблицы и имя столбца разделя-
ются точкой — должен использоваться всякий раз, когда
может возникнуть неопределенность в именах столбцов.
В данном примере имеется два столбца cust_id, один в
таблице Customers и один в таблице Orders. Без использо-
вания полностью определенных имен столбцов СУБД будет
считать, что вы сравниваете cust_id в таблице Orders с
самим собой. Поэтому запрос
SELECT COUNT(*) FROM O r d e r s WHERE c u s t _ i d = c u s t _ i d
будет всегда возвращать общее число заказов в таблице
Orders, но это не тот результат, который вам нужен:
120 Урок 11

ВВОД
SELECT cust_name,
cust_state,
(SELECT COUNT(*)
FROM Orders
WHERE cust_id = cust_id) AS orders
FROM Customers
ORDER BY cust name;

ВЫВОД
cust name cust state orders
Fun4All IN 5
Fun4All AZ 5
Kids Place OH 5
The Toy Store IL 5
Village Toys MI 5
Подзапросы чрезвычайно полезны при подготовке опера-
тора SELECT такого типа, однако внимательно следите ЗЕ
тем, чтобы были правильно указаны неоднозначные именг
столбцов.
Всегда есть несколько решений
Хотя простой код, представленный в этом уроке, и
работоспособен, зачастую он оказывается не самым
эффективным способом выборки данных такого типа.
Мы еще раз рассмотрим этот пример в одном из сле-
дующих уроков.

Резюме
В этом уроке вы узнали, что такое подзапросы и как и?
можно использовать. Чаще всего подзапросы используют i
операторах IN предложения WHERE и для заполнения вы
числяемых столбцов. Были представлены примеры опера
ций обоих названных типов.
Урок 12

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

Что такое объединения


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

Что такое реляционные таблицы


Понять, что представляют собой реляционные таблицы,
поможет пример из реальной жизни.
Предположим, что некоторая таблица базы данных со-
держит каталог продуктов, в котором для каждого предме-
та, включенного в каталог, выделена одна строка. Инфор-
мация, которая хранится о каждом предмете, должна
включать описание продукта и его цену, а также сведения о
поставщике и компании, выпустившей данный продукт.
Теперь предположим, что вы получили обширный каталог
от одного из поставщиков. Где вы должны хранить инфор-
122 Урок 12

мацию о поставщике (такую как имя, адрес и контактная


информация)? Не рекомендуется хранить эти данные вместе
с данными о его продуктах по нескольким причинам.
• Потому что информация о поставщике одна и та же
для всех его продуктов; повторение этой информации
для каждого продукта приведет к напрасной потере
времени и места на диске.
• Если информация о поставщике изменяется (напри-
мер, если он переезжает или изменяется его почто-
вый код), вам придется обновлять информацию каж-
дый раз, когда вы будете вносить данные об этом по-
ставщике.
• Когда данные повторяются (а так происходит, когда
информация о поставщике указывается для каждого
продукта), высока вероятность того, что данные не
будут каждый раз вводиться одним и тем же образом.
Несовместимые данные очень трудно использовать
при создании отчетов.
Отсюда можно сделать вывод, что хранить множество
экземпляров одних и тех же данных крайне нежелательно,
именно этот принцип и лежит в основе создания реляцион-
ных баз данных.
Реляционные таблицы разрабатываются таким образом,
что вся информация распределяется по множеству таблиц,
причем для данных каждого типа создается отдельная таб-
лица. Эти таблицы соотносятся (связываются) между собой
через общие значения (и таким образом являются реляци-
онными (относительными) в реляционной конструкции).
В нашем примере вы можете создать две таблицы: одну
для хранения информации о поставщике, вторую — о его
продуктах. Таблица Vendors содержит информацию о по-
ставщиках, по одной строке для каждого поставщика, где
обязательно значится его уникальный идентификатор. Это
значение, называемое первичный ключ, может быть или
идентификатором поставщика, или каким-то другим уни-
кальным (неповторяющимся) значением.
В таблице Products хранится только информация о
продуктах, и никакой конкретной информации о постав-
щиках, за исключением их идентификаторов (первичного
ключа таблицы Vendors). Этот ключ связывает таблицу
Vendors с таблицей Products. Благодаря применению это-
Объединение таблиц 123

го идентификатора поставщика вы можете использовать


таблицу Vendors для поиска информации о соответствую-
щем поставщике.
Что это дает? Давайте рассмотрим следующие моменты.
• Информация о поставщике никогда не повторяется,
благодаря чему экономится время и место на диске.
• Если информация о поставщике изменяется, бывает
достаточно обновить только одну запись о нем, един-
ственную в таблице Vendors. Данные в связанных с
нею таблицах изменять не нужно.
• Поскольку никакие данные не повторяются, они,
очевидно, оказываются непротиворечивыми, благода-
ря чему составление отчетов и манипулирование дан-
ными значительно упрощаются.
Таким образом, реляционные данные можно эффективно
хранить и ими можно легко манипулировать. Благодаря
этому реляционные базы данных используются намного
чаще, чем другие.

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

Для чего используют объединения


Распределение данных по многим таблицам обеспечивает
их более эффективное хранение, упрощает манипулирование
данными и повышает масштабируемость. Однако эти пре-
имущества не получаются даром — за все нужно платить.
Если данные хранятся во многих таблицах, как их мож-
но извлечь с помощью одного оператора SELECT? Ответ та-
ков: посредством объединения данных. Проще говоря, объ-
единение представляет собой механизм, используемый для
объединения таблиц внутри оператора (отсюда термин
"объединение"). Используя особый синтаксис, можно объе-
динить несколько таблиц таким образом, что будет возвра-
щаться один результат, и это объединение будет "на лету"
связывать нужные строки из каждой таблицы.
124 Урок 12

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


СУБД
Важно понимать, что объединение не является "фи-
зическим объектом" — другими словами, оно не су-
ществует как реальная таблица в базе данных. Объе-
динение создается СУБД в случае необходимости и
сохраняется только на время выполнения запроса.
Многие СУБД предлагают графический интерфейс,
который может быть использован для интерактивного
определения отношений таблицы. Эти инструменты
могут оказаться чрезвычайно полезными для под-
держания целостности ссылочных данных. При ис-
пользовании реляционных таблиц важно, чтобы толь-
ко достоверные данные содержались в реляционных
столбцах. Вернемся к нашему примеру: если в табли-
це Products хранится недостоверный идентифика-
тор поставщика, его продукты окажутся недоступны-
ми, поскольку они не будут относиться ни к одному
поставщику. Во избежание этого база данных должна
разрешать пользователю вводить только достовер-
ные значения (т.е. такие, которые представлены в
таблице Vendors) в столбце идентификаторов по-
ставщика таблицы Products. Целостность на уровне
ссылок (целостность ссылочных данных) означает,
что СУБД обязывает пользователя соблюдать прави-
ла, обеспечивающие целостность данных. И соблю-
дение этих правил часто обеспечивается при посред-
стве интерфейсов СУБД.

Создание объединения
Создание объединения — очень простая процедура.
Нужно указать все таблицы, которые должны быть вклю-
чены в объединение, а также "объяснить" СУБД, как они
должны быть соотнесены между собой. Посмотрите на сле-
дующий пример.
Объединение таблиц 125

ВВОД
SELECT vend_name, prod_name, p r o d _ p r i c e
FROM Vendors, Products
WHERE Vendors.vend i d = Products.vend i d ;

ВЫВОД
vend name
I prod_name prod_j?rice

Doll House Inc. Fish bean bag toy 3.4900


Doll House Inc. Bird bean bag toy- 3.4900
Doll House Inc. Rabbit bean bag toy 3.4900
Bears R Us 8 inch teddy bear 5.9900
Bears R Us 12 inch teddy bear 8.9900
Bears R Us 18 inch teddy bear 11.9900
Doll House Inc. Raggedy Ann 4.9900
Fun and Games King doll 9.4900
Fun and Games Queen doll 9.4900

Анализ I
Рассмотрим представленный выше код. Оператор SELECT
начинается точно так же, как все операторы, которые мы
до сих пор рассматривали, — с указания столбцов, которые
должны быть выбраны. Существенная разница состоит в
том, что два из указанных столбцов (prod_name и
p r o d _ p r i c e ) находятся в одной таблице, а третий
(vend_name) — в другой.
Теперь посмотрим на предложение FROM. В отличие от
предыдущих операторов SELECT, этот содержит две табли-
цы, указанные в предложении FROM, Vendors и P r o d u c t s .
Это имена двух таблиц, которые должны быть объединены
в данном операторе SELECT.
Таблицы корректно объединяются в предложении
WHERE, которое указывает СУБД связывать идентификатор
поставщика v e n d _ i d из таблицы Vendors со значением
vend_id таблицы P r o d u c t s .
Обратите внимание на то, что эти столбцы указаны как
V e n d o r s . v e n d _ i d и P r o d u c t s . v e n d _ i d . Такие полностью
определенные имена необходимы здесь потому, что, если
вы укажете только vend_id, СУБД не сможет понять, на
какие именно столбцы v e n d _ i d вы ссылаетесь. (Их два, по
одному в каждой таблице). Как можно видеть из представ-
ленного результата, один оператор SELECT возвращает дан-
ные из двух разных таблиц.
126 Урок 12

Полностью определенные имена столбцов


Используйте полностью определенные имена столб-
цов (таблицы и столбцы разделяются точкой) всякий
раз, когда может возникнуть неоднозначность отно-
сительно того, на какой столбец вы ссылаетесь.
В большинстве СУБД будет возвращено сообщение
об ошибке, если вы укажете неоднозначное имя
столбца, не определив его полностью путем указания
имени таблицы.

Важность предложения WHERE


Может показаться странным использование предложе-
ния WHERE для установления отношения в объединении, но
на это есть существенная причина. Вспомните: когда таб-
лицы объединяются в операторе SELECT, это отношение
создается "на лету".
В определениях таблиц базы данных ничего не говорит-
ся о том, как СУБД должна объединять таблицы. Вы
должны указать это сами. Когда вы объединяете две табли-
цы, то, что вы в действительности делаете, — это создаете
пары, состоящие из каждой строки первой таблицы и каж-
дой строки второй таблицы. Предложение WHERE действует
как фильтр, позволяющий включать в результат только
строки, которые соответствуют указанному предложению
фильтрации — в данном случае предложению объединения.
Без предложения WHERE каждая строка в первой таблице
будет образовывать пару с каждой строкой второй таблицы
независимо от того, есть логика в их объединении или нет.
Декартово произведение
Результаты, возвращаемые при умножении таблиц
без указания условия объединения. Количество вы-
бранных строк будет равно числу строк в первой таб-
лице, умноженному на число строк во второй таблице.

Для того чтобы разобраться в этом, посмотрите на сле-


дующий оператор SELECT и результат его применения.
Объединение таблиц 127

ВВОД
SELECT vend_name, prod_name, prod_price
FROM Vendors, Products;

ВЫВОД
vend name prod_name prod_price

Bears R Us 8 inch teddy bear 5.99


Bears R Us 12 inch teddy bear 8.99
Bears R Us 18 inch teddy bear 11.99
Bears R Us Fish bean bag toy 3.49
Bears R Us Bird bean bag toy 3.49
Bears R Us Rabbit bean bag toy 3.49
Bears R Us Raggedy Ann 4.99
Bears R Us King doll 9.49
Bears R Us Queen doll 9.49
Bear Emporium 8 inch teddy bear 5.99
Bear Emporium 12 inch teddy bear 8.99
Bear Emporium 18 inch teddy bear 11.99
Bear Emporium Fish bean bag toy 3.49
Bear Emporium Bird bean bag toy 3.49
Bear Emporium Rabbit bean bag toy 3.49
Bear Emporium Raggedy Ann 4.99
Bear Emporium King doll 9.49
Bear Emporium Queen doll 9.49
Doll House Inc. 8 inch teddy bear 5.99
Doll House Inc. 12 inch teddy bear 8.99
Doll House Inc. 18 inch teddy bear 11.99
Doll House Inc. Fish bean bag toy 3.49
Doll House Inc. Bird bean bag toy 3.49
Doll House Inc. Rabbit bean bag toy 3.49
Doll House Inc. Raggedy Ann 4.99
Doll House Inc. King doll 9.49
Doll House Inc. Queen doll 9.49
Furball Inc. 8 inch teddy bear 5.99
Furball Inc. 12 inch teddy bear 8.99
Furball Inc. 18 inch teddy bear 11.99
Furball Inc. Fish bean bag toy 3.49
Furball Inc. Bird bean bag toy 3.49
Furball Inc. Rabbit bean bag toy 3.49
Furball Inc. Raggedy Ann 4.99
Furball Inc. King doll 9.49
Furball Inc. Queen doll 9.49
Fun and Games 8 inch teddy bear 5.99
Fun and Games 12 inch teddy bear 8.99
Fun and Games 18 inch teddy bear 11.99
Fun and Games Fish bean bag toy 3.49
Fun and Games Bird bean bag toy 3.49
Fun and Games Rabbit bean bag toy 3.49
Fun and Games Raggedy Ann 4.99
128 Урок 12

Fun and Games King doll 9.49


Fun and Games Queen doll 9.49
Jouets et ours 8 inch teddy bear 5.99
Jouets et ours 12 inch teddy bear 8.99
Jouets et ours 18 inch teddy bear 11.99
Jouets et ours Fish bean bag toy 3.49
Jouets et ours Bird bean bag toy 3.49
Jouets et ours Rabbit bean bag toy 3.49
Jouets et ours Raggedy Ann 4.99
Jouets et ours King d o l l 9.49
Jouets et ours Queen d o l l 9.49

Анализ
Как видно из представленного результата, декартово
произведение вы, скорее всего, будете использовать очень
редко. Данные, возвращенные таким образом, ставят в со-
ответствие каждому продукту каждого поставщика, вклю-
чая продукты с указанием "не того" поставщика (и даже
поставщиков, которые вообще не предлагают продуктов).
Н е з а б у д ь т е у к а з а т ь п р е д л о ж е н и е WHERE
Проверьте, включили ли вы в оператор предложение
WHERE, иначе СУБД возвратит намного больше дан-
ных, чем вам нужно. Кроме того, убедитесь в том, что
предложение WHERE сформулировано правильно. Не-
корректное предложение фильтрования приведет к
тому, что СУБД выдаст вам неверные данные.

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

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

ВВОД
SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend id = Products.vend id;

Анализ
Оператор SELECT здесь точно такой же, как и предыду-
щий, но предложение FROM другое. Здесь отношение между
двумя таблицами является частью предложения FROM, ука-
занного как INNER JOIN. При использовании такого син-
таксиса предложение объединения указывается с использо-
ванием специального предложения ON вместо предложения
WHERE. Фактическое предложение, передаваемое в ON, то же
самое, которое передавалось бы в предложение WHERE.
Обратитесь к документации своей СУБД чтобы узнать,
какой синтаксис предпочтительнее использовать.
"Правильный" синтаксис
Согласно с п е ц и ф и к а ц и и ANSI на SQL, предпочти-
тельнее использование синтаксиса I N N E R J O I N .

Объединение многих таблиц


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

SELECT prod_name, vend_name, prod_price, quantity


FROM Orderltems, Products, Vendors
WHERE Products.vend_id = Vendors.vend_id
AND Orderltems .prod_id = Products .prod__id
AND order num = 20007;

ВЫВОД
prod_name vend name prod_price quantity

18 inch teddy bear Bears R Us 11.9900 50


Fish bean bag toy Doll House Inc. 3.4900 100
130 Урок 12

B i r d b e a n bag t o y D o l l House I n c . 3.4900 100


Rabbit bean bag t o y D o l l House I n c . 3.4900 100
Raggedy Ann D o l l House I n c . 4 . 9 9 0 0 50

Анализ
В этом примере выводятся предметы заказа номер
20 007. Предметы заказа хранятся в таблице Order Items.
Каждый продукт хранится в соответствии с идентификато-
ром продукта, который ссылается на продукт в таблице
Products. Эти продукты связаны с соответствующими по-
ставщиками в таблице Vendors по идентификатору постав-
щика, который хранится вместе с каждой записью о про-
дукте. В предложении FROM этого примера перечисляются
три таблицы, а предложение WHERE определяет оба назван-
ных предложения объединения. Дополнительное предложе-
ние WHERE используется затем для фильтрации только
предметов заказа 2 0 007.
К вопросу о производительности
СУБД обрабатывают объединения, тратя время на
обработку каждой указанной таблицы. Этот процесс
может оказаться очень ресурсоемким, поэтому не
следует использовать объединения таблиц без осо-
бой на то необходимости. Чем больше таблиц вы объ-
единяете, тем ниже производительность.

Максимальное число таблиц в объединении


Хотя SQL не накладывает каких-либо ограничений на
число таблиц в объединении, многие СУБД на самом
деле имеют такие ограничения. Обратитесь к доку-
ментации своей СУБД чтобы узнать, какие ограниче-
ния такого рода она налагает (если они есть).

Теперь самое время пересмотреть следующий пример из


урока 11, "Использование подзапросов", где оператор
SELECT возвращает список клиентов, заказавших продукт
RGAN01:
Объединение таблиц 131

ВВОД
SELECT cust_name, cust_contact
FROM Customers, Orders, Orderltems
WHERE Customers . cust__id = Orders . cust_id
AND Orderltems.order_num = Orders.order_num
1
AND prod_id • 'RGANOl ;

ВЫВОД
cust name cust contact

Fun4All Denise L. Stephens


The Toy Store Kim Howard

Анализ
Как уже говорилось в уроке 11, возвращение необходи-
мых для этого запроса данных требует использования трех
таблиц. Однако вместо использования подчиненных подза-
просов здесь были применены два объединения для связи
таблиц. Здесь были также указаны три предложения
WHERE. Первые два связывают таблицы в объединение, по-
следнее фильтрует данные по продукту RGANOl.

Только экспериментально
Как видите, часто существует несколько способов для
выполнения одной и той же операции SQL. И редко
удается определить, какой способ правильный, а ка-
кой нет. Производительность может зависеть от типа
выполняемой операции, используемой СУБД, коли-
чества данных в таблицах, присутствия либо отсутст-
вия индексов и ключей, а также целого ряда других
критериев. Следовательно, зачастую бывает целесо-
образно поэкспериментировать с различными меха-
низмами выборки для выяснения того, какой из них
работает быстрее.
132 Урок 12

Резюме
Объединения — одна из самых важных и востребован-
ных особенностей SQL, их эффективное использование воз-
можно только на основе знаний о "конструкции" реляцион-
ной базы данных. В этом уроке вы познакомились с осно-
вами построения баз данных, а также узнали, как следует
создавать объединение по эквивалентности (называемое
также внутреннее объединение), которое чаще всего ис-
пользуют при создании объединения. В следующем уроке
вы научитесь создавать объединения других типов.
Урок 13

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

Использование псевдонимов
таблиц
Ранее, в уроке 7, "Создание вычисляемых полей" вы уз-
нали, как можно использовать псевдонимы в качестве ссы-
лок на выбираемые столбцы таблицы. Синтаксис псевдони-
мов столбцов выглядит следующим образом:
ВВОД
SELECT RTRIM(vend_name) + ' (' + RTRIM(vend_country)
%+ ' ) ' AS vend_title
FROM Vendors
ORDER BY vend_name;
Помимо возможности применения псевдонимов для имен
столбцов и вычисляемых полей, SQL позволяет также ис-
пользовать псевдонимы вместо имен таблиц. На то есть две
основных причины:
• более короткий синтаксис SQL;
• это позволяет много раз использовать одну и ту же
таблицу в операторе SELECT.
Обратите внимание на следующий оператор SELECT.
В основном он такой же, как в примерах предыдущего уро-
134 Урок 13

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


зования псевдонимов:
ВВОД
SELECT cust_name, cust_contact
FROM Customers AS C, Orders AS O, Orderltems AS 01
WHERE C.cust_id = O.cust_id
AND OI.order_num = O.order_num
AND prod_id = 'RGAN011;

Анализ
Заметьте, что все три таблицы в предложениях FROM
имеют псевдонимы. Выражение Customers AS С задает С в
качестве псевдонима для таблицы Customers и т.д., что по-
зволяет использовать сокращение С вместо полного слова
Customers. В этом примере псевдонимы таблиц были ис-
пользованы только в предложении WHERE, но псевдонимы
можно применять и в других случаях. Их можно использо-
вать в списке SELECT, предложении ORDER BY, а также в
любой другой части этого оператора.
Никаких AS в Oracle

СУБД Oracle не поддерживает ключевое слово A S .

Для того чтобы использовать псевдонимы в СУБД


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

Использование объединений
других типов
До сих пор вы использовали только простые объедине-
ния, которые называют внутренние объединения или объе-
динения по эквивалентности. Теперь мы рассмотрим три
дополнительных типа объединения: самообъединение, есте-
ственное объединение и внешнее объединение.
Создание расширенных объединений 135

Самообъединения
Одна из основных причин для использования псевдони-
мов таблиц состоит в возможности обращения к одной и
той таблице несколько раз в одном операторе SELECT. По-
кажем это на примере.
Предположим, вы хотите послать письма по всем кон-
тактным адресам клиентов, которые работают с той же
компанией, с которой работает Джим Джонс. Такой запрос
требует, чтобы вначале вы выяснили, с какой компанией
работает Джим Джонс, а затем — какие клиенты работают
с этой же компанией. Вот один из способов решения этой
задачи.

ВВОД
SELECT cust_id, cust_name, cust_contact
FROM Customers
WHERE cust_name • (SELECT cust_name
FROM Customers
WHERE cust contact = 'Jim Jones');

ВЫВОД
cust id cust name cust contact

1000000003 Fun4All Jim Jones


1000000004 Fun4All Denise L. Stephens

Анализ
В первом решении используются подзапросы. Внутрен-
ний оператор SELECT выполняет простую выборку, чтобы
возвратить имя компании (cust_name), с которой работает
Джим Джонс. Только это имя используется в предложении
WHERE внешнего запроса, так что выбираются имена всех
служащих, работающих с этой компанией. (Все о подзапро-
сах читайте в уроке 11, "Использование подзапросов".
Теперь рассмотрим тот же самый запрос, в котором ис-
пользуется объединение.
ВВОД
SELECT cl.cust_id, cl.cust_name, cl.cust_contact
FROM Customers AS cl, Customers AS c2
WHERE cl.cust_name = c2.cust_name
AND c2.cust contact = 'Jim Jones';
136 Урок 13

ВЫВОД
cust id cust name cust contact

1000000003 Fun4All Jim Jones


1000000004 Fun4All Denise L. Stephens

Никаких AS в СУБД Oracle


Пользователи Oracle, не забывайте убирать из своих
операторов ключевое слово AS.

Анализ
Две таблицы, необходимые для выполнения запроса, на
самом деле — одна и та же таблица, поэтому таблица
Customers появляется в предложении FROM дважды. Хотя
это совершенно законно, некоторые ссылки на таблицу
Customers могли бы оказаться неоднозначными, потому
что СУБД "не знает", на какую именно таблицу Customers
вы ссылаетесь.
Для решения этой проблемы используются псевдонимы.
Первый раз для таблицы Customers назначается псевдоним
С1, второй — псевдоним С2. Теперь эти псевдонимы можно
применять в качестве имен таблиц. Например, оператор
SELECT использует префикс С1 для однозначного указания
полного имени нужного столбца. Если этого не сделать,
СУБД возвратит сообщение об ошибке, потому что имеется
по два столбца с именами cust_id, cust_name и
cust_contact. СУБД не может знать, какой именно стол-
бец вы имеете в виду (даже если в действительности это
один и тот же столбец). Первое предложение WHERE объеди-
няет эти таблицы, а затем оно фильтрует данные второй
таблицы по столбцу cust_contact, чтобы возвратить толь-
ко нужные данные.
Самообъединения вместо подзапросов
Самообъединения часто используют для замены опе-
раторов, применяющих подзапросы, которые выби-
рают данные из той же таблицы, что и внешний опе-
ратор. Хотя конечный результат получается тем же
самым, многие СУБД обрабатывают объединения на-
Создание расширенных объединений 137

много быстрее* чем подзапросы. Стоит поэкспери-


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

Естественные объединения
Всякий раз, когда объединяются таблицы, по крайней
мере один столбец будет появляться более чем в одной таб-
лице (т.е. столбцы, которые объединялись). Обычные объе-
динения (внутренние объединения, которые мы рассмотре-
ли в предыдущем уроке) возвращают все данные, даже
многократные вхождения одного и того же столбца. Естест-
венное объединение просто уничтожает эти многократные
вхождения, так что в результате возвращается только один
столбец.
Естественное объединение — это объединение, в котором
вы выбираете только не повторяющиеся столбцы. Обычно
это делается при помощи метасимвола (SELECT *) для од-
ной таблицы и указания явного подмножества столбцов для
всех остальных таблиц. Вот пример:
ВВОД
SELECT С.*, О.order_num, O.order_date, OI.prod_id,
Ч>01 .quantity, OI. item_j?rice
FROM Customers AS C, Orders AS O, Orderltems AS OI
WHERE C.cust_id = O.cust_id
AND OI.order_num = О.order_num
1
AND prod_id = 'RGAN01 ;

Никаких A S в Oracle

Пользователи Oracle, не забывайте выбрасывать из


кода ключевое слово AS.

Анализ
В этом примере метасимвол используется только для
первой таблицы. Все остальные столбцы указаны явно, по-
этому никакие дубликаты столбцов не выбираются.
Несомненно, каждое внутреннее объединение, которое
вы использовали до сих пор, представляло собой в действи-
тельности естественное объединение и, возможно, вам ни-
138 Урок 13

когда не понадобится внутреннее объединение, не являю-


щееся естественным.

Внешние объединения
Большинство объединений связывают строки одной таб-
лицы со строками другой, но в некоторых случаях вам мо-
жет понадобиться включать в результат строки, не имею-
щие связанных. Например, вы можете использовать объе-
динения для решения следующих задач:
• подсчета количества заказов каждого клиента, вклю-
чая клиентов, которые еще не сделали заказ;
• составления перечня продуктов с указанием количе-
ства заказов на них, включая продукты, которые ни-
кто из клиентов не захотел заказывать;
• вычисления средних объемов продаж с учетом клиен-
тов, которые еще не сделали заказ.
В каждом из этих случаев объединение должно вклю-
чать строки, не имеющие ассоциирующихся с ними строк в
связанной таблице. Объединение такого типа называется
внешним.

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

Следующий оператор SELECT позволяет выполнить про-


стое внутреннее объединение. С его помощью выбирается
список всех клиентов и их заказы:
ВВОД
SELECT Customers.cust_id, Orders.order_num
FROM Customers INNER JOIN Orders
ON Customers.cust id = Orders.cust id;
Создание расширенных объединений 139

Синтаксис внешнего объединения похож на этот. Для


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

ВВОД
SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders
ON Customers.cust id = Orders.cust id;

ВЫВОД
cust id order num

1000000001 20005
1000000002 NULL
1000000003 20006
1000000004 20007
1000000005 20008

Анализ
Аналогично внутреннему объединению, которое мы рас-
сматривали на прошлом уроке, в этом операторе SELECT
используются ключевые слова OUTER JOIN для указания
типа объединения (вместо указания его в предложении
WHERE). Но, в отличие от внутренних объединений, которые
связывают строки двух таблиц, внешние объединения
включают в результат также строки, не имеющие связан-
ных с ними строк. При использовании синтаксиса OUTER
JOIN вы должны использовать ключевое слово RIGHT или
LEFT, чтобы указать таблицу, все строки которой будут
включены в результат (RIGHT для таблицы, имя которой
стоит справа от OUTER JOIN, LEFT — для той, имя которой
значится слева).
В предыдущем примере используются ключевые слова
LEFT OUTER JOIN для выборки всех строк таблицы, ука-
занной в левой части предложения FROM (таблицы
Customers). Чтобы выбрать все строки из таблицы, ука-
занной справа, используйте правое внешнее объединение
(RIGHT OUTER JOIN), как показано в следующем примере.

ВВОД
SELECT Customers.cust_id, Orders.order_num
FROM Customers RIGHT OUTER JOIN Orders
ON Orders.cust id = Customers.cust id;
140 Урок 13

SQL Server дополнительно поддерживает упрощенный


синтаксис внешнего объединения. Чтобы выбрать перечень
всех клиентов, включая тех, которые не разместили ни од-
ного заказа, можно сделать следующее.
ВВОД
SELECT Customers.cust_id, Orders.order_num
FROM Customers, Orders
WHERE Customers.cust id *= Orders.cust id;

cust id order_num

1000000001 20005
1000000001 20009
1000000002 NULL
1000000003 20006
1000000004 20007
1000000005 20008

Анализ
Здесь предложение объединения указано в предложении
WHERE. Вместо проверки на равенство с помощью
оператора = используется оператор *= для указания того,
что в результат должна быть включена каждая строка таб-
лицы Customers. Оператор *= представляет собой оператор
левого внешнего объединения. С его помощью выбираются
все строки левой таблицы.
Противоположностью описанного левого внешнего объе-
динения является правое внешнее объединение, его опера-
тор таков: =*. Это объединение можно использовать для
возвращения всех строк таблицы, имя которой находится
справа от данного оператора, как показано в следующем
примере.
ВВОД
SELECT Customers.cust_id, Orders.order_num
FROM Customers, Orders
WHERE Orders.cust_id =* Customers.cust_id;
Еще одна форма внешнего объединения (используемая
только в СУБД Oracle) требует использования оператора
( + ) после имени таблицы, как показано ниже.
Создание расширенных объединений 141

ВВОД
SELECT Customers.cust_id, Orders.order_num
FROM Customers, Orders
WHERE Customers.cust id (+) = Orders.cust id

Типы внешнего объединения


Независимо от формы используемого внешнего объ-
единения всегда существуют только две его основ-
ные формы— левое внешнее объединение и правое
внешнее объединение. Единственная разница между
ними состоит в порядке указания таблиц, которые
связываются. Другими словами, левое внешнее объ-
единение может быть превращено в правое внешнее
объединение просто за счет изменения порядка ука-
зания имен таблиц в предложении FROM или WHERE.
А раз так, то эти два типа внешнего объединения мо-
гут заменять друг друга, и решение о том, какое
именно из них нужно использовать, определяется су-
губо удобством выполнения операции.

Существует и другой вариант внешнего объединения — это


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

ВВОД
SELECT Customers.cust_id, Orders.order_num
FROM Orders FULL OUTER JOIN Customers
ON Orders.cust id = Customers.cust id;

Поддержка полного внешнего объединения


Синтаксис полного внешнего объединения не под-
держивается в СУБД Access, MySQL, SQL Server и
Sybase.
142 Урок 13

Использование объединений со
статистическими функциями
Как вы узнали из урока 9, "Суммирование данных", ста-
тистические функции применяют для получения статисти-
ческих сведений о данных. Хотя во всех до сих пор рас-
смотренных примерах посредством статистических функций
получались данные только для одной таблицы, эти функ-
ции можно использовать также по отношению к объедине-
ниям.
Рассмотрим пример. Допустим, вы хотите выбрать спи-
сок всех клиентов и число сделанных ими заказов. Чтобы
получить искомое, в следующем коде применяется функция
COUNT() .
ВВОД
SELECT Customers.cust_id, COUNT(Orders.order_num) AS

FROM Customers INNER JOIN Orders


ON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust id;

ВЫВОД
cust_id num_ord

1000000001 2
1000000003 1
1000000004 1
1000000005 1

Анализ
В этом операторе SELECT используются ключевые слова
INNER JOIN для связи таблиц Customers и Orders между
собой. Предложение GROUP BY служит для получения ито-
говых данных по клиентам, и, таким образом, обращение к
функции COUNT (Orders.order_num) позволяет подсчитать
количество заказов каждого клиента и возвратить резуль-
тат в виде столбца num_ord.
Статистические функции можно использовать с объеди-
нениями других типов:
Создание расширенных объединений 143

ВВОД
SELECT Customers.cust_id, COUNT(Orders.order_num) AS

FROM Customers LEFT OUTER JOIN Orders


ON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust id;

Никаких AS в Oracle

Еще раз напоминаем пользователям Oracle о необхо-


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

ВЫВОД
cust id num ord

1000000001
1000000002
1000000003
1000000004
1000000005

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

Использование объединений
и условий объединения
Прежде чем завершить обсуждение объединений, кото-
рое заняло два урока, есть смысл напомнить о некоторых
ключевых моментах, относящихся к объединениям и их
использованию.
• Будьте внимательны при выборе типа объединения,
которое собираетесь использовать. Возможно, что ча-
ще вы будете использовать внутреннее объединение,
хотя в зависимости от ситуации это можно также
сказать и о внешнем объединении.
144 Урок 13

Посмотрите в документации СУБД, какой именно


синтаксис объединений она поддерживает. (Многие
СУБД поддерживают одну из форм синтаксиса, опи-
санных в этих двух уроках).
Проверьте, правильно ли вы указали условие объеди-
нения (независимо от используемого синтаксиса),
иначе будут возвращены неверные данные.
Не забывайте указывать предложение объединения, в
противном случае вы получите декартово произведение.
Можно включать в объединение много таблиц и даже
применять для каждой из них свой тип объединения.
Хотя это допустимо и часто оказывается полезным,
рекомендуем проверить каждое объединение отдель-
но, прежде чем применять их вместе. Это намного
упростит поиск ошибок.

Резюме
Этот урок был продолжением предыдущего урока, по-
священного объединениям. Начали мы с того, что рассказа-
ли, как и для чего используют псевдонимы, а затем про-
должили рассмотрение объединений различных типов и
различных вариантов синтаксиса, применяемых для каждо-
го из них. Теперь вы знаете, как с объединениями можно
использовать статистические функции, а также какие пра-
вила важно соблюдать при использовании объединений.
Урок 14

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

Что такое комбинированные


запросы
В большинстве SQL-запросов используется один опера-
тор, посредством которого возвращаются данные из одной
или нескольких таблиц. SQL позволяет также выполнять
множественные запросы (за счет многократного использо-
вания оператора SELECT) и возвращать результаты в виде
одного набора результатов запроса. Эти комбинированные
запросы обычно называют соединениями или сложными за-
просами.
Можно назвать два основных сценария, для выполнения
которых вам понадобятся сложные запросы:
• для возвращения одинаковым образом структуриро-
ванных данных из различных таблиц посредством
одного запроса;
• для выполнения многократных запросов к одной таб-
лице и возвращения данных в виде результата одного
запроса.
146 Урок 14

Комбинированные запросы и многократные ус-


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

Создание комбинированных
запросов
Запросы в языке SQL комбинируются с помощью опера-
тора UNION. Оператор UNION позволяет многократно указы-
вать оператор SELECT, и по завершении их работы может
быть выведен один набор результатов.

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


Использовать оператор UNION довольно просто. Все, что
вы должны сделать, — это указать каждый необходимый
вам оператор SELECT и разместить ключевое слово UNION
между ними.
Рассмотрим пример. Допустим, вам необходим отчет, со-
держащий сведения обо всех клиентах из штатов Иллинойс,
Индиана и Мичиган. Вы также хотите включить в него дан-
ные о клиенте Fun4All независимо от штата. Конечно, мож-
но создать условие WHERE, благодаря которому будет выпол-
нено требуемое, но в данном случае гораздо удобнее исполь-
зовать оператор UNION.
Как уже говорилось, применение оператора UNION под-
разумевает многократное использование операторов SELECT.
Вначале рассмотрим отдельные операторы:
Комбинированные запросы 147

ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
1 1
WHERE cust state IN (•IL ,'IN ,"MI');

EH
cust_name cust_contact cust email

Village Toys John Smith [email protected]


Fun4All Jim Jones j j [email protected]
The Toy Store Kim Howard NULL

ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust name = 'Fun4All';

ВЫВОД
cust name cust_contact cust_email

Fun4All Jim Jones j j onesOfun4all.com


Fun4All Denise L. Stephens [email protected]

Анализ
Первый оператор SELECT выбирает все строки, относя-
щиеся к штатам Иллинойс, Индиана и Мичиган, передавая
аббревиатуры этих штатов в условие IN. Второй оператор
SELECT использует простую проверку на равенство, чтобы
найти все местонахождения в таблицах клиента Fun4All.
Чтобы скомбинировать эти два запроса, выполните сле-
дующее.
ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust name = 'Fun4All';
148 Урок 14

ВЫВОД
cust_name cust_contact cust_email

Fun4All Denise L.Stephens [email protected]


Fun4All Jim Jones j jonesOfun4all.com
Village Toys John Smith [email protected]
The Toy Store Kim Howard NULL

Анализ
Операторы предыдущего примера состоят из обоих
предшествующих операторов SELECT, разделенных ключе-
вым словом UNION. Оператор UNION указывает СУБД вы-
полнить оба оператора SELECT и вывести результаты в виде
одного набора результатов запроса.
Для сравнения приводим тот же самый запрос, исполь-
зующий не оператор UNION, а несколько предложений
WHERE:

ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL1,'IN1,'MI')
OR cust_name = •Fun4All';
В нашем простом примере применение оператора UNION
может оказаться более сложным, чем использование пред-
ложения WHERE. Однако если условие фильтрации окажется
более сложным или если понадобится выбирать данные из
многих таблиц (а не только из одной), то оператор UNION
может значительно упростить процесс.

Ограничения оператора U N I O N

В стандартном SQL не существует о г р а н и ч е н и й на


число операторов S E L E C T , которые могут быть с к о м -
бинированы п о с р е д с т в о м операторов U N I O N . Однако
лучше все же обратиться к документации СУБД и убе-
диться в том, что она не накладывает каких-либо ог-
раничений на максимально допустимое число опера-
торов.
Комбинированные запросы 149

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


В большинстве хороших СУБД используется внутрен-
ний оптимизатор запросов, комбинирующий опера-
торы SELECT, прежде чем СУБД начинает их обработ--
ку. Теоретически это означает, что, с точки зрения
производительности, нет реальной разницы между
использованием многих предложений WHERE и опера-
тора UNION. Мы говорим "теоретически", потому что
на практике многие оптимизаторы запросов не все-
гда выполняют свою работу так хорошо, как следова-
ло бы. Лучшим вариантом было бы протестировать
оба метода и посмотреть, какой из них вам лучше
подходит.

Правила применения запросов UNION


Как видите, запросы UNION очень просты в использова-
нии. Но существует несколько правил, четко указывающих,
что именно может быть объединено.
• Запрос UNION должен включать два или более опера-
торов SELECT, отделенных один от другого ключевым
словом UNION (таким образом, если в запросе исполь-
зуется четыре оператора SELECT, должно быть ис-
пользовано три ключевых слова UNION).
• Каждый запрос в операторе UNION должен содержать
одни и те же столбцы, выражения или статистиче-
ские функции (кроме того, столбцы должны быть пе-
речислены в одном и том же порядке).
• Типы данных столбцов должны быть совместимыми.
Они не обязательно должны быть одного типа, но они
должны быть того типа, который СУБД сможет одно-
значно преобразовать (например, это могут быть раз-
личные числовые типы данных или различные типы
даты).
При соблюдении этих основных правил и ограничений,
запросы на соединение можно использовать для решения
любых задач по возвращению данных.
150 Урок 14

Включение или исключение


повторяющихся строк
Возвратимся к одному из предыдущих разделов "Ис-
пользование оператора UNION" и рассмотрим использован-
ные в нем простые операторы SELECT. Вы можете заметить,
что, когда они выполняются отдельно, первый оператор
SELECT возвращает три строки, второй — две. Однако когда
эти два оператора SELECT комбинируются с UNION, возвра-
щаются только четыре строки, а не пять.
Запрос UNION автоматически удаляет все повторяющиеся
строки из набора результатов запроса (иными словами, он
ведет себя точно так же, как вели бы себя несколько пред-
ложений WHERE в одном операторе SELECT). Поэтому здесь
присутствует запись о клиенте Fun4All из штата Индиа-
на — эта строка была возвращена обоими операторами
SELECT. Когда же использовался запрос UNION, повторяю-
щаяся строка была удалена.
Таково поведение запроса UNION по умолчанию, но при
желании вы можете изменить его. Если бы требовалось,
чтобы возвращались все вхождения соответствий, вам сле-
довало бы использовать UNION ALL вместо оператора UNION.
Рассмотрим следующий пример:

ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN1,'MI')
UNION ALL
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust name = 'Fun4All';

ВЫВОД
cust_name cust_contact cust_email

Village Toys John Smith [email protected]


Fun4All Jim Jones [email protected]
The Toy Store Kim Howard NULL
Fun4All Jim Jones [email protected]
Fun4All Denise L.Stephens [email protected]
Комбинированные запросы 151

Анализ
При использовании запроса UNION ALL СУБД не удаляет
дубликаты. Поэтому в предыдущем примере возвращено
пять строк, одна из них повторяется дважды.

U N I O N ИЛИ WHERE

В начале этого урока мы говорили, что оператор


U N I O N выполняет то ж е с а м о е , что и несколько усло-
вий WHERE. Оператор U N I O N A L L является ф о р м о й
запроса U N I O N , которая делает т о , что не с п о с о б н ы
выполнить предложения WHERE. Если вы хотите полу-
чить все вхождения соответствий для каждого уело -
вия (включая дубликаты), вам следует использовать
о п е р а т о р U N I O N A L L , а н е W H E R E .

Сортировка результатов
комбинированных запросов
Результат применения оператора SELECT сортируется с
помощью предложения ORDER BY. При комбинировании за-
просов посредством UNION только одно предложение ORDER
может быть использовано, и оно должно появиться после
заключительного оператора SELECT. Практически не имеет
смысла сортировать часть набора результатов одним спосо-
бом, а часть — другим, поэтому несколько предложений
ORDER BY применять не разрешается.
В следующем примере сортируются результаты, полу-
ченные предыдущим запросом UNION:

ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL1,•IN1,'MI•)
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = cFun4All'
ORDER BY cust name, cust contact;
152 Урок 14

ВЫВОД
cust_name cust_contact cust_email

Fun4All Denise L.Stephens [email protected]


Fun4All Jim Jones [email protected]
The Toy Store Kim Howard NULL
Village Toys John Smith salesOvillagetoys.cor

Анализ
Этот запрос UNION использует одно предложение ORDEI
BY после заключительного оператора SELECT.
Несмотря на то что ORDER BY является частью толькс
последнего оператора SELECT, на самом деле СУБД буде!
использовать его для сортировки всех результатов, возвра
щенных всеми операторами SELECT.

Другие типы запроса на соединение


Некоторые СУБД поддерживают два дополнительных
з а п р о с а типа U N I O N . Оператор E X C E P T (иногда назы-
ваемый M I N U S ) м о ж е т быть использован только для
чтения строк, которые существуют в первой таблице,
но не во второй, а оператор I N T E R S E C T МОЖНО ис-
пользовать ДЛЯ чтения строк, которые имеются в обе-
их таблицах. Однако на практике такие запросы
UNION используются редко, поскольку те же самые
результаты могут быть получены посредством объе-
динений.

Резюме
В этом уроке вы узнали, как можно комбинировать за-
просы SELECT посредством оператора UNION. Используя
оператор UNION, вы можете вернуть результаты нескольких
запросов в виде одного комбинированного запроса, вклю-
чающего или исключающего дубликаты. За счет использо-
вания оператора UNION можно значительно упростить
сложные предложения WHERE и одновременно выбирать
данные из многих таблиц.
Урок 15

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

Что такое добавление данных


Несомненно, SELECT является наиболее часто исполь-
зуемым оператором языка SQL (именно поэтому мы посвя-
тили его рассмотрению 14 уроков). Но помимо него в SQL
часто применяются еще три оператора, которыми вам необ-
ходимо уметь пользоваться. Первый из них — оператор
INSERT. (О двух других мы расскажем в следующем уроке.)
Как следует из названия, оператор INSERT используется
для ввода (добавления) строк в таблицу базы данных. До-
бавление можно осуществить несколькими способами:
• добавить одну полную строку;
• добавить часть одной строки;
• добавить результаты запроса.
Далее мы рассмотрим все эти варианты.
Оператор INSERT И безопасность системы
Для использования оператора INSERT могут потре-
боваться особые права на доступ в СУБД со структу-
рой клиент-сервер. Прежде чем применять оператор
I N S E R T , убедитесь в т о м , что у вас есть на это право.

Добавление полных строк


Простейший способ добавления данных в таблицу может
быть реализован при использовании основного синтаксиса
оператора INSERT. Для этого нужно указать имя таблицы и
154 Урок 15

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


Вот пример:
ВВОД
INSERT INTO Customers
VALUES('1000000006 ' ,
1
Toy Land',
1
4 2 3 Any Street ,
1
New York',
1
'NY ,
'Hill' ,
1
USA',
NULL,
NULL);
В этом примере в таблицу добавляются сведения о новом
клиенте. Данные, которые должны быть сохранены в каж-
дом столбце таблицы, указываются в условии VALUES, зна-
чения должны быть приведены для каждого столбца. Если
для какого-то столбца не имеется соответствующего значе-
ния (например, как это произошло для столбцов
cust_contact и cust_email в данном примере), следует
использовать значение NULL (предполагается, что для дан-
ной таблицы разрешено не указывать значения в этих
столбцах). Столбцы должны заполняться в порядке, в кото-
ром они появились в определении таблицы.

Ключевое слово I N T O

В некоторых реализациях SQL вслед за оператором


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

Этот синтаксис довольно прост, но он не вполне безопа-


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

вательно, использовать оператор SQL, результаты примене-


ния которого зависят от порядка следования столбцов,
весьма небезопасно. Если вы будете пренебрегать этим сове-
том, вас ждут неприятности.
Безопасный (и, к сожалению, более громоздкий) способ
записи оператора INSERT таков:
ВВОД
INSERT INTO Customers(cust_id,
cust_name,
cust_address,
cust_city,
cust_state,
cust_ZIP,
cust_country,
cust_contact,
cust_email)
VALUES(•1000000006',
1
Toy Land•,
4 2 3 Any Street1 ,
1
New York•,
'NY' ,
•11111' ,
•USA1 ,
NULL,
NULL) ;

Анализ
В этом примере делается в точности то же самое, что и в
предыдущем варианте применения оператора INSERT, но на
этот раз имена столбцов явно указаны в круглых скобках,
следующих после имени таблицы. Когда строка вводится в
таблицу, СУБД устанавливает соответствие каждого пред-
мета в списке столбцов с соответствующим значением в
списке VALUES. Первое значение в списке VALUES соответст-
вует первому указанному имени столбца, второе значение
соответствует имени второго столбца и т.д.
Поскольку имена столбцов предоставлены, условие
VALUES должно подобрать названные имена столбцов в по-
рядке, в котором указаны столбцы, причем не обязательно
в порядке, в каком они следуют в реальной таблице. Пре-
имущество этого способа таково: даже если расположение
столбцов в таблице изменяется, оператор INSERT все равно
будет работать корректно.
156 Урок 15

Следующий оператор INSERT заполняет все столбцы


строки (так же, как и в предыдущем примере), но делает
это в другом порядке. Поскольку имена столбцов указыва-
ются, добавление будет выполнено правильно:
ВВОД
INSERT INTO Customers(cust_id,
cust_contact,
cust_email,
cust_name,
cust_address,
cust_city,
cust_state,
cust_ZIP,
VALUES('1000000006•,
NULL,
NULL,
1
Toy Land',
1
'123 Any Street ,
1
New York',
'NY' ,
1
11111',

Всегда используйте список столбцов


Как правило, оператор I N S E R T не используется без
явного указания списка столбцов. Благодаря этому
значительно возрастает вероятность того, что вы
сможете продолжать работу, даже если в таблице
произойдут изменения.

Аккуратно используйте п р е д л о ж е н и е V A L U E S

Независимо от синтаксиса, используемого для опе-


ратора I N S E R T , должны быть правильно указаны зна-
чения в предложении VALUES. Если имена столбцов
не указываются, должно быть указано значение для
каждого столбца таблицы. Если имена столбцов ука-
зываются, должно наличествовать какое-то значение
для каждого столбца, включенного в список. Если что-
то не указано, будет сгенерировано сообщение об
ошибке, и строка не будет вставлена.
Добавление данных 157

Добавление части строки


Рекомендуемый в предыдущем разделе способ использо-
вания оператора INSERT состоит в явном указании имен
столбцов таблицы. Используя такой синтаксис, вы также
получаете возможность пропустить некоторые столбцы. Это
означает, что вы вводите значения для одних столбцов и не
предлагаете для других.
Рассмотрим следующий пример:
ВВОД
INSERT INTO Customers(cust_id,
cust_name,
cust_address,
cust_city,
cust_state,
cust_ZIP,
cust_country)
VALUES('1000000006 ' ,
1
Toy Land',
4 2 3 Any S t r e e t 1 ,
1
New Y o r k ' ,
'NY1 ,
'11111',
1
USA') ;

Анализ
В примере, приведенном ранее в этом уроке, значения не
предлагаются для двух столбцов, cust_contact и
cust_email. Это означает, что в данном случае нет причин
включать эти столбцы в оператор INSERT. Поэтому данный
оператор INSERT не включает эти два столбца и два соот-
ветствующих им значения.
Попуск столбцов
Вы можете исключать некоторые столбцы из опера-
ции INSERT, если это позволяет делать определение
таблицы. Должно соблюдаться одно из следующих
условий:
• Этот столбец определен как допускающий значе-
ния NULL (отсутствие какого-либо значения).
158 Урок 15

В определении таблицы указано значение по умол-


чанию. Это означает, что, если не указано никакое
значение, будет использовано значение по умол-
чанию.

Если вы пропускаете столбец таблицы, которая не до-


пускает появления в своих строках значений NULL и не
имеет значения, определенного для использования по умол-
чанию, СУБД выдаст сообщение об ошибке, и эта строка не
будет добавлена.

Добавление выбранных данных


Обычно оператор INSERT служит для добавления строки
в таблицу с использованием указанных значений. Сущест-
вует и другая форма оператора INSERT, она может быть ис-
пользована для добавления в таблицу результата примене-
ния оператора SELECT. Известна эта форма как оператор
INSERT SELECT и, как подсказывает название последнего,
данный оператор выполняет то же самое, что делают опера-
торы INSERT и SELECT.
Предположим, вы хотите ввести в таблицу Customers
список клиентов из другой таблицы. Вместо того чтобы
считывать по одной строке и затем добавлять ее посредст-
вом оператора INSERT, вы можете сделать следующее.
Инструкции для следующего примера
В следующем примере данные импортируются из
таблицы CustNew в таблицу Customers. Сначала соз-
дайте и наполните таблицу CustNew. Формат таблицы
CustNew должен быть таким же, как и таблицы
Customers, описанной в приложении А. После запол-
нения CustNew удостоверьтесь в том, что не были ис-
пользованы значения c u s t _ i d , которые уже приме-
нялись в таблице Customers (последующая операция
I N S E R T потерпит неудачу, если значения первичного
ключа будут повторяться).
Добавление данных 159

ВВОД
INSERT INTO Customers(cust_id, cust_contact,
cust_email,
cust_name,
cust_address,
cust_city,
cust_state,
cust_ZIP,
cust_country)
SELECT cust_id,
cust_contact,
cust_email,
cust_name,
cust_address,
cust_city,
cust_state,
cust_ZIP,
cust_country
FROM CustNew;

Анализ
В этом примере для импорта всех данных из таблицы
CustNew в таблицу Customers используется оператор
INSERT SELECT. Вместо того чтобы перечислять значения,
которые должны быть добавлены, оператор SELECT выбира-
ет их из таблицы CustNew. Каждый столбец в операторе
SELECT соответствует столбцу в списке указанных столбцов.
Сколько же строк добавит этот оператор? Это зависит от то-
го, сколько строк содержится в таблице CustNew. Если таб-
лица пуста, никакие строки добавлены не будут (и никакое
сообщение об ошибке не будет выдано, поскольку эта опе-
рация остается правомерной). Если таблица содержит дан-
ные, все они будут добавлены в таблицу Customers.
Имена столбцов в операторе INSERT SELECT

В этом примере были использованы одинаковые


имена столбцов в операторах I N S E R T И SELECT. Учти-
те, ЧТО к именам столбцов не предъявляются никакие
требования. В действительности СУБД вообще не об-
ращает внимания на имена столбцов, возвращаемых
оператором SELECT. Точнее, ею используется поло-
жение столбца, так что первый столбец в SELECT (не-
зависимо от имени) будет использован для заполне-
ния первого указанного столбца таблицы и т.д.
160 Урок 15

Оператор SELECT, используемый в INSERT SELECT, мо-


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

Добавление нескольких строк


Оператор I N S E R T обычно добавляет только одну стро-
ку. Чтобы добавить несколько строк, нужно выполнить
несколько операторов I N S E R T . Исключением и з этого
правила является оператор INSERT SELECT, который
может быть использован для добавления многих строк
посредством одного оператора — какие бы данные ни
возвратил оператор SELECT, ОНИ могут быть добавлены
в таблицу посредством оператора INSERT.

Копирование данных из одной


таблицы в другую
Это — другая форма добавления данных, при использо-
вании которой оператор INSERT вообще не применяется.
Чтобы скопировать содержимое какой-то таблицы в новую
(которая создается "на лету"), можно использовать оператор
SELECT INTO.

Не п о д д е р ж и в а е т с я в D B 2

СУБД DB2 не поддерживает использование операто-


ра S E L E C T I N T O о п и с а н н ы м выше с п о с о б о м .

В отличие от оператора INSERT SELECT, посредством ко-


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

Разница между INSERT SELECT И SELECT INTO

Одно из отличий между операторами SELECT I N T O И


I N S E R T S E L E C T состоит в том, что первый оператор
экспортирует данные, а второй — импортирует.
Добавление данных 161

Следующий пример демонстрирует способ применения


оператора SELECT INTO:
ВВОД
SELECT *
INTO CustCopy
FROM Customers;

Анализ
Этот оператор SELECT создает новую таблицу с именем
CustCopy и копирует в нее все содержимое таблицы
Customers.
Поскольку был использован оператор SELECT *, каждый
столбец таблицы Customers будет создан в таблице
CustCopy (и соответственно заполнен). Чтобы скопировать
только часть доступных столбцов, следует явно указать
имена столбцов, а не использовать метасимвол * (звездоч-
ка).
В СУБД MySQL и Oracle используется несколько иной
синтаксис:
ВВОД
CREATE TABLE CustCopy AS
SELECT *
FROM Customers;

Анализ
При использовании оператора SELECT INTO нужно об-
ращать внимание на следующие моменты.
• Можно использовать любые опции и предложения
оператора SELECT, включая WHERE и GROUP BY.
• Для добавления данных из нескольких таблиц можно
использовать объединения.
• Данные можно добавить только в одну таблицу неза-
висимо от того, из скольких таблиц они были извле-
чены.
162 Урок 15

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


Оператор SELECT I N T O является прекрасным сред-
ством создания копий таблиц для экспериментов с но-
выми для вас операторами SQL. Создав копию, вы по-
лучите возможность проверить возможности SQL на
этой копии, а не на таблицах реальной базы данных.

Больше примеров
Вам нужны еще примеры использования оператора
I N S E R T ? Ознакомьтесь со с ц е н а р и я м и заполнения
таблиц, описанными в приложении А.

Резюме
В этом уроке вы узнали о том, как можно добавлять
строки в таблицу базы данных. Вы познакомились с не-
сколькими способами использования оператора INSERT и
узнали, почему желательно явно указывать имена столб-
цов. Вы научились использовать оператор INSERT SELECT
для импорта строк из другой таблицы и применять опера-
тор SELECT INTO для экспорта строк в новую таблицу.
В следующем уроке мы расскажем о том, как для манипу-
лирования данными таблиц следует использовать операто-
ры UPDATE И DELETE.
Урок 16

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

Обновление данных
Для обновления (модификации) данных какой-либо таб-
лицы используется оператор UPDATE. Этот оператор можно
использовать двумя способами:
• для обновления определенной строки таблицы;
• для обновления всех строк таблицы.
Рассмотрим каждый из названных способов.
Не п р о п у с к а й т е п р е д л о ж е н и е WHERE

Применять оператор UPDATE нужно особенно акку-


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

Оператор UPDATE И безопасность

Для использования оператора U P D A T E в СУБД со


структурой клиент-сервер могут понадобиться осо-
бые права доступа. Прежде чем применять этот опе-
ратор, удостоверьтесь в том, что вам предоставлены
соответствующие права.
164 Урок 16

Оператор UPDATE очень прост в использовании, он состо-


ит из трех основных частей:
• имени таблицы, подлежащей обновлению;
• имен столбцов и их новых значений;
• условий фильтрации, определяющих, какие именно
строки должны быть обновлены.
Рассмотрим простой пример. Допустим, у клиента
1000000005 появился адрес электронной почты, поэтому
его запись нужно обновить. Такое обновление можно вы-
полнить посредством следующего оператора:
ВВОД
UPDATE Customers
SET cust_email = '[email protected]'
WHERE cust_id = '1000000005';
Оператор UPDATE всегда начинается с имени таблицы,
подлежащей обновлению. В нашем примере это таблица
Customers. Затем используется команда SET, чтобы вве-
сти в столбец новое значение. В нашем случае предложе-
ние SET устанавливает определенное значение для столбца
cust_eraail:
SET cust_email = '[email protected]'
Заканчивается оператор UPDATE предложением WHERE,
которое сообщает СУБД, какая строка подлежит обновле-
нию. При отсутствии предложения WHERE СУБД обновила
бы все строки таблицы Customers, введя в них новый
(причем один и тот же!) адрес электронной почты; это, ко-
нечно, не то, что требовалось.
Для обновления нескольких столбцов необходим иной
синтаксис:
ВВОД
UPDATE Customers
SET cust_contact = 'Sam Roberts',
cust_email • '[email protected]'
WHERE cust_id = '1000000006';
Для обновления нескольких столбцов используется только
одна команда SET, и каждая пара столбец-значение отделяется
от другой запятой (после имени последнего столбца запятая не
ставится). В нашем примере оба столбца, cust_contact и
cust email, будут обновлены для клиента 1000000006.
Обновление и удаление данных 165

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


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

Ключевое слово FROM


Некоторые реализации SQL поддерживают предло-
жение FROM в операторе UPDATE, оно может быть ис-
пользовано для обновления строк одной таблицы
данными из другой. Обратитесь к документации сво-
ей СУБД и выясните, поддерживает ли она эту осо-
бенность.

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


его строкам значения NULL (если определение таблицы по-
зволяет вводить в нее значения NULL). Это можно сделать
следующим образом:
ВВОД
UPDATE Customers
SET cust_email = NULL
WHERE cust_id = '1000000005';
Здесь ключевое слово NULL используется для хранения
"никакого" значения в столбце cust email.

Удаление данных
Для удаления данных из таблицы применяется оператор
DELETE.
Его можно использовать двумя способами:
• для удаления из таблицы определенных строк;
• для удаления из таблицы всех ее строк.
166 Урок 16

Не забывайте указывать предложение WHERE


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

Оператор DELETE и безопасность

Для использования оператора D E L E T E в СУБД со


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

Рассмотрим каждый из этих способов.


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

ВВОД
DELETE FROM Customers
WHERE cust_id = '1000000006';
Оператор DELETE FROM требует, чтобы вы указали имя
таблицы, из которой должны быть удалены данные. Пред-
ложение WHERE фильтрует строки, определяя, какие из них
должны быть удалены. В нашем примере должна быть уда-
лена строка, относящаяся к клиенту 1000000006. Если бы
предложение WHERE было пропущено, этот оператор удалил
бы все столбцы таблицы.

Ключевое слово FROM

В некоторых реализациях SQL за D E L E T E м о ж е т о п -


ционально следовать ключевое слово FROM. Однако
хорошим тоном считается всегда указывать это клю-
чевое слово, даже если в нем нет необходимости. По-
ступая таким образом, вы обеспечите переносимость
своего SQL-кода между СУБД.
Обновление и удаление данных 167

Оператор DELETE не принимает имена столбцов или ме-


тасимволы. Он удаляет строки целиком, а не отдельные
столбцы. Для удаления определенного столбца следует ис-
пользовать оператор UPDATE.

Содержимое таблиц, но не сами таблицы


Оператор D E L E T E удаляет и з таблицы отдельные
строки или даже все строки за один раз, но он нико-
гда не удаляет саму таблицу.

Более быстрое удаление


Если необходимо удалить значения из всех строк таб-
лицы, не используйте оператор DELETE. Вместо него
нужно применить оператор TRUNCATE T A B L E , кото-
рый выполняет ТО же самое, но делает это намного
быстрее (потому что изменения данных не регистри-
руются).

Советы по обновлению
и удалению данных
Все операторы UPDATE DELETE, рассмотренные в преды-
дущем разделе, сопровождались предложениями WHERE, и
на это есть очень веская причина. Если вы пропустите
предложение WHERE, оператор UPDATE или DELETE будет
применен по отношению ко всем строкам таблицы. Други-
ми словами, если вы выполните оператор UPDATE без пред-
ложения WHERE, каждая строка таблицы будет заменена но-
выми значениями. Аналогичным образом, если вы выпол-
ните оператор DELETE без предложения WHERE, будет
удалено все содержимое таблицы.
Далее перечислены правила хорошего тона, которым
следуют программисты SQL.
• Никогда не выполняйте оператор UPDATE или DELETE
без предложения WHERE, если только вы на самом де-
ле не хотите обновить или удалить каждую строку.
168 Урок 16

Убедитесь в том, что каждая таблица имеет первич-


ный ключ (вернитесь к уроку 12, "Объединение таб-
лиц", если забыли, что это такое), и используйте его
в предложении WHERE всякий раз, когда это оказыва-
ется возможным. (Вы можете указать отдельные пер-
вичные ключи, несколько значений или диапазоны
значений.)
Прежде чем использовать предложение WHERE с опе-
ратором UPDATE или DELETE, сначала проверьте его с
оператором SELECT, чтобы убедиться в том, что оно
правильно фильтрует записи, — можно ошибиться и
сформулировать неправильное предложение WHERE.
Используйте средства принудительного обеспечения
ссылочной целостности данных (см. урок 12), чтобы
СУБД не позволяла удалять строки, для которых в
других таблицах имеются связанные с ними данные.
Некоторые СУБД позволяют администраторам баз дан-
ных устанавливать ограничения, препятствующие вы-
полнению операторов UPDATE или DELETE без предло-
жения WHERE. Если ваша СУБД поддерживает эту осо-
бенность, рассмотрите возможность ее использования.

Используйте операторы удаления с осторожностью


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

Резюме
В этом уроке вы узнали, как нужно применять операто-
ры UPDATE и DELETE для манипулирования данными таб-
лиц. Вы познакомились с синтаксисом каждого из этих
операторов, а также с опасностями, которыми чревато их
применение. Вы также узнали, почему столь важно исполь-
зовать предложение WHERE в операторах UPDATE и DELETE,
и познакомились с основными правилами, которым нужно
следовать, чтобы по неосторожности не повредить данные.
Урок 17

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

Создание таблиц
Язык SQL используется не только для манипуляций с
данными таблиц, он предназначен для выполнения всех
операций с базами данных и таблицами, включая собствен-
но создание таблиц и работу с ними.
Существует два способа создания таблиц.
• Большинство СУБД сопровождается инструментарием
администратора, который можно использовать для ин-
терактивного создания таблиц базы данных и управ-
ления ими.
• Таблицами можно также манипулировать посредст-
вом операторов языка SQL.
Для создания таблиц программным способом используют
оператор SQL CREATE TABLE. Стоит отметить, что, когда вы
используете интерактивный инструментарий, в действи-
тельности вся работа выполняется операторами SQL. Одна-
ко вам не приходится писать эти операторы; интерфейс
создает и выполняет их незаметно для вас (то же самое
справедливо и для процедуры изменения существующих
таблиц).
170 Урок 17

Разница в синтаксисе
Точный синтаксис оператора CREATE TABLE может
быть несколько различным для разных реализаций
SQL. Обязательно обратитесь к документации своей
СУБД за дополнительной информацией и выясните,
какой в точности синтаксис для нее необходим и ка-
кие возможности она поддерживает.

Полное рассмотрение всех опций, применяемых при соз-


дании таблиц, не входит в задачи нашего урока, мы рас-
смотрим только основы. Для получения дополнительной и
специфичной для вашей СУБД информации настоятельно
рекомендуем обратиться к ее документации.
Примеры для конкретных СУБД
:. . .
Операторы CREATE TABLE для конкретных СУБД приве-
дены в примерах сценариев создания таблиц (см. при-
ложение А, "Сценарии демонстрационных таблиц").

Основы создания таблиц


Чтобы создать таблицу с помощью оператора CREATE
TABLE, нужно указать следующие данные:
• имя новой таблицы; оно вводится после ключевого
слова CREATE TABLE;
• имена и определения столбцов таблицы, разделенные
запятыми;
• в некоторых СУБД также требуется, чтобы было ука-
зано место размещения таблицы.
Посредством следующего оператора SQL создается таб-
лица Products, часто используемая в нашей книге:
ВВОД
CREATE TABLE Products
(
prod_id CHAR(10) NOT NULL,
vend_id CHAR(10) NOT NULL,
prod_name CHAR(254) NOT NULL,
prod_price DECIMAL(8,2) NOT NULL,
Создание таблиц и работа с ними 171

prod_desc VARCHAR(1000) NULL

Анализ
Как видите, имя таблицы указывается сразу же после
ключевых СЛОВ CREATE TABLE.
Определение таблицы (все ее столбцы) заключается в
круглые скобки. Имена столбцов разделяются запятыми.
Приведенная в примере таблица состоит из пяти столбцов.
Определение каждого столбца начинается с имени столбца
(которое должно быть уникальным в пределах данной таб-
лицы), за ним указывается тип данных. (Обратитесь к уро-
ку 1, "Что такое SQL", чтобы вспомнить, что такое типы
данных. Кроме того, в приложении Г, "Использование ти-
пов данных SQL", приведен перечень часто используемых
типов данных и сведения об их совместимости.) Оператор в
целом заканчивается символом "точка с запятой", следую-
щим после закрывающей круглой скобки.
Ранее уже говорилось, что синтаксис оператора CREATE
TABLE весьма различен для разных СУБД, и только что
представленный нами простой сценарий доказывает это.
В СУБД Oracle, PostgreSQL, SQL Server и Sybase представ-
ленный оператор будет работать в той форме, в которой он
представлен в примере, а вот в MySQL тип VARCHAR должен
быть заменен типом t e x t . В DB2 значение NULL следует
удалить из последнего столбца. Именно поэтому нами были
предложены различные сценарии создания таблиц SQL для
каждой СУБД (см. приложение А).

Форматирование оператора
Пробелы игнорируются операторами SQL. Оператор
можно ввести в одной длинной строке или разбить ее
на несколько строк, разницы между ними не будет.
Это позволяет форматировать выражения SQL так,
как вам удобно. Показанный выше оператор CREATE
TABLE — хороший пример форматирования операто-
ра SQL. Код разбит на несколько строк, определения
столбцов разнесены для удобства чтения и редакти-
рования. Форматировать выражения SQL подобным
образом не обязательно, но все же настоятельно ре-
комендуется.
172 Урок 17

Замена существующих таблиц


Когда вы создаете новую таблицу, указываемое вами
имя не должно существовать в СУБД, иначе будет вы-
дано сообщение об ошибке. Чтобы избежать случай-
ной перезаписи, SQL требует, чтобы вы вначале вруч-
ную удалили таблицу (подробности освещены в сле-
дующем разделе), а затем вновь создали ее, а не
просто перезаписали.

Работа со значениями NULL


В уроке 4, "Фильтрация данных", рассказывалось о том,
что такое значение NULL. Использование этого значения
подразумевает, что в столбце не должно содержаться ника-
кое значение или неизвестно значение, которое должно
быть в столбце. Столбец, в котором разрешается присутст-
вие значения NULL, позволяет также добавлять в таблицу
строки, в которых не предусмотрено значение для данного
столбца. Столбец, в котором не разрешается присутствие
значения NULL, не принимает строки с отсутствующим зна-
чением. Иными словами, для этого столбца всегда потребу-
ется вводить какое-то значение при добавлении или обнов-
лении строк.
Каждый столбец таблицы может быть или пустым
(NULL), или не пустым (NOT NULL), и это его состояние ого-
варивается в определении таблицы во время ее создания.
Рассмотрим следующий пример:
ВВОД
CREATE TABLE Orders
(
order_num INTEGER NOT NULL,
order_date DATETIME NOT NULL,
cust id CHAR(10) NOT NULL

Анализ
Посредством этого оператора создается таблица Orders,
неоднократно использованная в книге. Таблица Orders со-
стоит из трех столбцов: номер заказа (order number), дата
С о з д а н и е т а б л и ц и работа с н и м и 173

заказа ( o r d e r d a t e ) и идентификатор клиента (customer


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

ВВОД
CREATE TABLE Vendors
(
vend_id CHAR(10) NULL,
vend_name CHAR(50) NOT NULL,
vend_address CHAR(50),
vend_city CHAR(50),
vend_state CHAR(5),
vend_ZIP CHAR(10),
vend_country CHAR(50)

Анализ
Посредством этого оператора создается таблица Vendors,
неоднократно используемая в книге. Столбцы с идентифи-
катором поставщика и именем поставщика необходимы,
поэтому оба определены как NOT NULL (т.е. не допускаю-
щие значение NULL). Пять остальных столбцов допускают
значения NULL, поэтому для них не указано требование NOT
NULL. Значение NULL является значением по умолчанию,
поэтому, если не указано требование NOT NULL, предполага-
ется разрешение на использование значения NULL.

Указание значения N U L L

Во м н о г и х СУБД отсутствие ключевых слов NOT N U L L


трактуется как N U L L . Однако не во всех. В СУБД DB2
наличие ключевого слова N U L L является обязатель-
ным; если о н о не указано, генерируется с о о б щ е н и е
об ошибке. Обратитесь к документации своей СУБД,
чтобы получить исчерпывающую информацию о син-
таксисе.
174 Урок 17

Первичные ключи и з н а ч е н и я N U L L

В уроке 1 говорилось о том, что первичные ключи


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

Что такое NULL


Не удивляйтесь, увидев значения NULL В пустых стро-
ках. Значение NULL означает отсутствие значения; это
не пустая строка. Если вы указали в коде ' ' (две
одинарных кавычки, между которыми ничего нет), это
"значение" можно было бы ввести в столбец типа NOT
NULL. Пустая строка является допустимым значени-
ем; это не означает отсутствие значения. Значения
NULL указываются посредством ключевого слова
N U L L , н о н е пустой с т р о к о й .

Определение значений по умолчанию


Язык SQL позволяет определять значения по умолча-
нию, которые будут использованы в том случае, если при
добавлении строки какое-то ее значение не указано. Значе-
ния по умолчанию определяются с помощью ключевого
слова DEFAULT в определениях столбца оператора CREATE
TABLE.
Рассмотрим следующий пример:
ВВОД
CREATE TABLE Orderltems
(
order_num INTEGER NOT NULL,
order_item INTEGER NOT NULL,
prod_id CHAR(10) NOT NULL,
quantity INTEGER NOT NULL DEFAULT 1,
item_j>rice DECIMAL (8 ,2) NOT NULL
Создание таблиц и работа с ними 175

Анализ
Посредством этого оператора создается таблица
Order I t ems, содержащая отдельные предметы, которые мо-
гут быть заказаны. (Сам заказ хранится в таблице Orders.)
Столбец q u a n t i t y (количество) содержит количество каждо-
го предмета в заказе. В данном примере добавление текста
DEFAULT 1 в описание столбца предписывает СУБД указы-
вать количество, равное 1, если не указано иное.
Значения по умолчанию часто используются для хранения
в столбцах даты и денежных единиц. К примеру, системная
дата может быть использована как дата по умолчанию путем
указания функции или переменной, используемой для ссыл-
ки на системную дату. Например, пользователи MySQL мог-
ли бы указать дату как DEFAULT CURRENT_DATE ( ) , в то вре-
мя как пользователям Oracle следовало бы вводить дату как
DEFAULT SYSDATE, а пользователям SQL Server — как
DEFAULT GETDATE ( ) . К сожалению, команда, используемая
для получения системной даты, в каждой СУБД своя.
В табл. 17.1 приведен синтаксис для нескольких СУБД (если
ваша СУБД не представлена в этом списке, обратитесь к ее
документации).
Таблица 1 7 . 1 . Получение значения даты из системы
СУБД Функция/переменная
Access NOW()
DB2 CURRENT_DATE
MySQL CURRENT_DATE()
Oracle SYSDATE
PostgreSQL CURRENT_DATE
SQL Server GETDATE()
Sybase GETDATE()

Использование значений DEFAULT вместо значе-


ний N U L L

Многие разработчики баз данных используют значе-


ния DEFAULT вместо столбцов NULL. Часто значения
DEFAULT применяются в столбцах, которые будут ис-
пользованы в вычислениях или при статистической
обработке данных.
176 Урок 17

Обновление таблиц
Для того чтобы обновить определения таблицы, следует
воспользоваться оператором ALTER TABLE. Хотя все СУБД
поддерживают этот оператор, то, что они при этом позво-
ляют вам делать, в значительной степени зависит от реали-
зации СУБД. Ниже приведены несколько соображений по
поводу применения оператора ALTER TABLE.
• В идеальном случае структура таблицы вообще не
должна меняться после того, как в таблицу введены
данные. Вам придется потратить немало времени,
пытаясь предугадать будущие потребности в процессе
разработки таблиц, чтобы позже не потребовалось
вносить в их структуру существенные изменения.
• Все СУБД позволяют добавлять в уже существующие
таблицы столбцы, но некоторые ограничивают типы
данных, которые могут быть добавлены (а заодно и
использование значений NULL и DEFAULT).
• Многие СУБД не позволяют удалять или изменять
столбцы в таблице.
• Большинство СУБД разрешают переименовывать
столбцы.
• Многие СУБД налагают серьезные ограничения на
изменения, которые могут быть сделаны по отноше-
нию к заполненным столбцам, и несколько мень-
шие — по отношению к незаполненным.
Как видите, вносить изменения в существующие табли-
цы ничуть не проще, чем создавать их заново. Обратитесь к
документации вашей СУБД, чтобы уточнить, что можно
изменять.
Чтобы изменить таблицу посредством оператора ALTER
TABLE, нужно ввести следующую информацию.
• Имя таблицы, подлежащей изменению, после ключе-
вых слов ALTER TABLE. (Таблица с таким именем
должна существовать, иначе будет выдано сообщение
об ошибке.)
• Список изменений, которые должны быть сделаны.
Поскольку добавление столбцов в таблицу — единст-
венная операция, поддерживаемая всеми СУБД,
именно ее мы рассмотрим в качестве примера.
Создание таблиц и работа с ними 177

ВВОД
ALTER TABLE Vendors
ADD vend_j>hone CHAR(20);

Анализ
Посредством этого оператора в таблицу Vendors добав-
ляется столбец, названный vend_phone. Должен быть оп-
ределен тип данных.
Другие операции изменения, например, изменение или
удаление столбцов, введение ограничений или ключей, тре-
буют похожего синтаксиса. (Отметим, что следующий при-
мер будет работать уже не во всех СУБД.)
ВВОД
ALTER TABLE Vendors
DROP COLUMN vend_phone;
Сложные изменения структуры таблицы обычно выпол-
няются вручную и включают следующие шаги.
• Создание новой таблицы с новым расположением
столбцов.
• Использование оператора INSERT SELECT (см.
урок 15, "Добавление данных," в котором подробно
рассмотрены вопросы применения этого оператора)
для копирования данных из старой таблицы в новую.
При необходимости используются функции преобра-
зования и вычисляемые поля.
• Проверка того факта, что новая таблица содержит
нужные данные.
• Переименование старой таблицы (или удаление ее).
• Присвоение новой таблице имени, которое ранее при-
надлежало старой таблице.
• Восстановление триггеров, хранимых процедур, ин-
дексов и внешних ключей, если это необходимо.
178 Урок 17

Аккуратно используйте оператор A L T E R TABLE

Оператор A L T E R T A B L E следует использовать с особой


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

Удаление таблиц
Удаление таблиц (имеется в виду удаление именно таб
лиц, а не их содержимого) — очень простой процесс. Таб
лицы удаляются с помощью оператора DROP TABLE:
ВВОД
DROP TABLE CustCopy;

Анализ
Этот оператор удаляет таблицу CustCopy (которую вы
создали в ходе изучения материалов урока 15). В данном
случае не требуется никакого подтверждения, невозможнс
возвратиться к прежнему состоянию — в результате приме-
нения этого оператора таблица будет безвозвратно удалена.
Использование реляционных правил для предот-
вращения ошибочного удаления
Во многих СУБД применяются правила, препятст-
вующие удалению таблиц, связанных с другими таб-
лицами. Если эти правила действуют и вы применяе-
те оператор DROP T A B L E ПО отношению к таблице,
которая связана с другой таблицей, СУБД блокирует
проведение этой операции до тех пор, пока не будет
удалена данная связь. Применение этих опций при-
ветствуется, поскольку благодаря им можно воспре-
пятствовать ошибочному удалению нужных таблиц.
Создание таблиц и работа с ними 179

Переименование таблиц
В разных СУБД переименование таблиц осуществляется
по-разному. Не существует жестких, устоявшихся стандар-
тов на выполнение этой операции. Пользователи СУБД
DB2, MySQL, Oracle и PostgreSQL могут применять для
этого оператор RENAME. Пользователи SQL Server и Sybase
могут использовать хранимую процедуру sp_rename. Ос-
новной синтаксис для всех операций переименования тре-
бует указания старого и нового имен. Однако существуют
различия, зависящие от реализации. Обратитесь к докумен-
тации своей СУБД, чтобы узнать подробности относительно
поддерживаемого ею синтаксиса.

Резюме
В этом уроке вы познакомились с несколькими новыми
операторами SQL. Оператор CREATE TABLE применяется для
создания новых таблиц, ALTER TABLE — для изменения
столбцов таблицы (или других объектов, таких как ограни-
чения или индексы), а оператор DROP TABLE позволяет
полностью удалить таблицу. Все эти операторы нужно ис-
пользовать с особой осторожностью и только после создания
резервных копий базы данных. Поскольку точный синтак-
сис этих операторов варьируется в зависимости от СУБД,
вам придется обратиться к документации своей СУБД за
дополнительной информацией.
Урок 18

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

Что такое представления


Представления — это виртуальные таблицы. В отличие
от таблиц, содержащих данные, представления содержат
запросы, которые динамически выбирают данные, когда это
необходимо.
Поддержка в MySQL
К моменту выхода этой книги СУБД MySQL еще не
поддерживала представления (их поддержку плани-
ровалось осуществить в версии MySQL 5). Поэтому
приведенные нами примеры в настоящее время ра-
ботать не будут.

Лучший способ объяснить, что такое представления, —


рассмотреть конкретный пример. Возвратимся к уроку 12,
"Объединение таблиц", в котором был использован сле-
дующий оператор SELECT для выборки данных сразу из
трех таблиц:
ВВОД
SELECT cust_name, cust_contact
FROM Customers, Orders, Orderltems
WHERE Customers.cust id = Orders.cust id
182 Урок 18

AND Orderltems .order__num = Orders . order_num


AND prod_id = 'RGAN011;
Этот запрос был использован для извлечения информ
ции о клиентах, которые заказали указанный продук
Всякий, кому необходимы эти данные, должен был бы р
зобраться в структуре таблицы, а также в методике созд
ния запроса и объединения таблиц. Чтобы извлечь анал
гичные данные для другого продукта (или для несколько
продуктов), последнее предложение WHERE придется мод]
фицировать.
Теперь предположим, что вы могли бы сохранить ве<
этот запрос в виртуальной таблице с имене
ProductCustomers. Затем для выборки тех же самых да]
ных нужно было бы просто сделать следующее:
ВВОД
SELECT cust_name, cust_contact
FROM ProductCustomers
WHERE prod_id = 'RGAN01';
Это как раз тот случай, когда в игру вступают предста]
ления. Таблица ProductCustomers является представлен!
ем, поэтому она не содержит каких-либо столбцов или да!
ных. Вместо них хранится запрос — тот самый запрос, К(
торый был использован выше для объединения таблиц.
Постоянство СУБД

Синтаксис создания представлений одинаков для


всех основных СУБД.

Для чего используют представления


Вы только что познакомились с одним случаем испол!
зования представления. Довольно часто они применяютс
для выполнения следующих операций:
• для повторного использования операторов SQL;
• для упрощения выполнения сложных операций. Пс
еле того как запрос подготовлен, его можно с легке
стью использовать повторно, для этого не нужно рас
бираться в особенностях его работы;
Использование представлений 183

• для вывода частей таблицы вместо вывода ее полно-


стью;
• для защиты данных. Пользователям можно предоста-
вить доступ к определенному поднабору таблиц, а не
ко всем таблицам;
• для изменения форматирования и отображения дан-
ных. Представления могут возвращать данные, от-
форматированные и отображенные иначе, чем они
хранятся в таблицах.
После того как представления созданы, их можно ис-
пользовать точно так же, как таблицы. Вы можете выпол-
нять операции SELECT, фильтровать и сортировать данные,
объединять представления с другими представлениями или
таблицами и, возможно, даже добавлять в них данные либо
обновлять их. (На последнюю операцию накладываются не-
которые ограничения. Ниже мы расскажем о них.)
Важно не забывать о том, что представления — это
только представления, данные которых хранятся в других
таблицах. Представления не содержат данных как таковых,
поэтому данные, которые они возвращают, извлекаются из
других таблиц. Если данные этих таблиц изменяются или
происходит добавление в них данных, представления воз-
вратят уже новые, измененные данные.
Проблемы производительности
Поскольку представления не содержат данных, каж-
дый раз, когда используется представление, для вы-
полнения запроса приходится проводить некоторый
поиск. Если вы создали сложное представление с не-
сколькими объединениями и фильтрами или если
были использованы вложенные представления, про-
изводительность СУБД резко снизится. Рекоменду-
ется провести тестирование, прежде чем использо-
вать приложения, в которых интенсивно используют-
ся представления.

Представления: правила и ограничения


Прежде чем создавать представления, следует ознако-
миться с некоторыми накладываемыми на них ограниче-
184 Урок 18

ниями. К сожалению, представления весьма специфичн


для каждой СУБД, поэтому прежде чем приступать к и
использованию, рекомендуем обратиться к документаци
вашей СУБД,
Ниже приведено несколько самых общих правил и огр*
ничений, которыми следует руководствоваться при создг
нии и использовании представлений.
• Представления, так же как и таблицы, должны име!
уникальные имена. (Они не могут быть названы та
же, как какая-нибудь другая таблица или предста]
ление.)
• Не существует ограничения на количество предста!
лений, которые могут быть созданы.
• Для того чтобы создать представление, вы должн]
иметь соответствующие права доступа. Обычно и
предоставляет администратор базы данных.
Представления могут быть вложенными; это означав!
что представление может быть создано посредством запросе
который выбирает данные из другого представления. То*
ное количество уровней вложения различно для разны
СУБД. (Вложенные представления могут серьезно снизит
производительность при выполнении запроса, поэтому и
нужно основательно протестировать, прежде чем применят
в реальных условиях.)
• Во многих СУБД запрещается использование предлс
жения ORDER BY в запросах к представлениям.
• В некоторых СУБД требуется, чтобы каждый возвра
щаемый столбец имел имя — это подразумевает ис
пользование псевдонимов, если столбцы представля
ют собой вычисляемые поля (см. урок 7, "Создани
вычисляемых полей," где представлена дополнитель
ная информация о псевдонимах столбцов).
• Представления не могут быть проиндексированы. Он]
также не могут иметь триггеров или связанных с ни
ми значений по умолчанию.
• В некоторых СУБД представления трактуются ка]
запросы, предназначенные только для чтения. Эт(
означает, что из представлений можно выбирать дан
ные, но их нельзя вносить в таблицы, на основе ко
торых было создано представление. Обратитесь к до
Использование представлений 185

кументации своей СУБД, если хотите узнать подроб-


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

Обратитесь к документации своей СУБД


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

Создание представлений
Итак, вы знаете, что такое представления (а также от-
части знакомы с правилами, которыми следует руково-
дствоваться при работе с ними), теперь разберемся, как они
создаются.
Представления создаются с помощью оператора CREATE
VIEW. Аналогично оператору CREATE TABLE, оператор
CREATE VIEW можно использовать только для создания
представления, которого до сих пор не существовало.
Удаление представлений
Для удаления представления используется опера-
тор DROP. Его синтаксис прост: DROP VIEW
имя представления;.
186 Урок 18

Чтобы перезаписать (или обновить) представление,


вначале нужно применить по отношению к нему опе-
ратор DROP, а потом заново создать представление.

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


упрощения сложных объединений
Чаще всего представления используются для упрощения
работы с SQL, и нередко это относится к объединениям.
Посмотрите на следующий оператор:

ВВОД
CREATE VIEW ProductCustomers AS
SELECT cust_name, cust_contact, prod_id
FROM Customers, Orders, Orderltems
WHERE Customers.cust_id = Orders.cust_id
AND Orderltems.order num = Orders.order num;

Анализ
Посредством этого оператора создается представление,
названное P r o d u c t C u s t o m e r s , которое объединяет три таб-
лицы с целью возвращения списка клиентов, заказавших
какой-то продукт. Если бы был использован оператор
SELECT * FROM P r o d u c t C u s t o m e r s , в список был бы
включен любой клиент, который сделал заказ.

Создание представлений и SQL Server


В отличие от большинства операторов SQL, Microsoft
SQL Server не поддерживает использование точки с
запятой после оператора CREATE VIEW.

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


RGAN01, нужно выполнить следующее:

ВВОД
SELECT cust_name, cust_contact
FROM ProductCustomers
WHERE prod_id = 'RGAN01';
Использование представлений 187

ВЫВОД
cust name cust contact

Fun4All Denise L. Stephens


The Toy Store Kim Howard

Анализ
Этот оператор возвращает указанные данные из пред-
ставления в результате применения предложения WHERE.
Когда СУБД обрабатывает запрос, она добавляет указанное
предложение WHERE к каждому уже существующему пред-
ложению WHERE в запросе к представлению, так что данные
фильтруются правильно.
Таким образом, представления могут значительно упро-
стить сложные операторы SQL. Используя представления,
вы можете один раз записать код SQL и затем повторно ис-
пользовать его, если возникает такая необходимость.
Создание повторно используемых представлений
Хорошей идеей является создание представлений, не
привязанных к конкретным данным. Например, пред-
ставление, созданное в предыдущем примере, возвра-
щает имена клиентов, заказавших все продукты, а не
только продукт RGANOI (для которого представление
первоначально и создавалось). Расширение возможно-
стей представления позволяет многократно использо-
вать его, тем самым устраняется также необходимость
создавать и хранить много похожих представлений, что
делает представление еще более эффективным.

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


переформатирования выбранных
данных
Как уже говорилось выше, другим наиболее частым слу-
чаем использования представлений является переформати-
рование выбранных данных. Следующий оператор SELECT
(см. урок 7, "Создание вычисляемых полей") возвращает
имя поставщика и его местонахождение в одном комбини-
рованном вычисляемом столбце:
188 Урок 18

ВВОД
SELECT RTRIM(vend_name) + ' (' + RTRIM(vend__country)
Ь+ ' )' AS vend_title
FROM Vendors
ORDER BY vend name;

ВЫВОД
vend t i t l e

Bear Emporium (USA)


Bears R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)
Следующий оператор такой же, но в нем применяется
синтаксис | | (его мы рассматривали в уроке 7):
ВВОД
SELECT RTRIM(vend_name) j | ' (' |
•^RTRIM(vend_country) || ' )' AS vend_title
FROM Vendors
ORDER BY vend name;

ВЫВОД
vendtitle

Bear Emporium (USA)


Bears R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)
Теперь предположим, что результаты регулярно требу-
ются в таком формате. Вместо того чтобы выполнять объе-
динение каждый раз, когда в этом возникает необходи-
мость, вы можете создать представление и использовать его
вместо объединения. Для превращения этого оператора в
представление нужно сделать следующее:
ВВОД
CREATE VIEW VendorLocations AS SELECT RTRIM(vend_name)
(' + RTRIM(vend_country)
Использование представлений 189

Ь+ ')' AS v e n d _ t i t l e
FROM Vendors;
Здесь также применяется оператор, использующий син-
таксис I I:

ВВОД
CREATE VIEW VendorLocations AS
SELECT RTRIM(vend_name) || ' (' | |
^RTRIM(vend_country) || ' ) ' AS vend_title
FROM Vendors;

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

ВЫВОД
vend title
Bear Emporium (USA)
Bears R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)

Все ограничения о п е р а т о р а S E L E C T сохраняются


Ранее в этом уроке говорилось, что синтаксис, при-
меняемый для создания представлений, различен в
разных СУБД. Но почему так много версий синтаксиса
операторов? Представление просто скрывает опера-
тор SELECT, и синтаксис этого оператора SELECT
должен четко соответствовать правилам и ограниче-
ниям используемой СУБД.
190 Урок 18

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


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

ВВОД
CREATE VIEW CustomerEMailList AS
SELECT cust_id, cust_name, cust_email
FROM Customers
WHERE cust email IS NOT NULL;

Анализ
Очевидно, отправляя сообщение в соответствии со спи-
ском адресов e-mail, следовало бы пропустить клиентов, у
которых нет адреса электронной почты. Предложение
WHERE отфильтровывает здесь строки, имеющие значения
NULL в столбцах c u s t _ e r a a i l , так что соответствующие за-
писи не будут выбираться.
Теперь представление CustomerEMailList можно ис-
пользовать подобно любой другой таблице.

ВВОД
SELECT *
FROM CustomerEMailList;

ВЫВОД
cust id cust name cust email

1000000001 Village Toys [email protected]


1000000003 Fun4All [email protected]
1000000004 Fun4All [email protected]

П р е д л о ж е н и я WHERE

Если предложение WHERE используется п р и выборке


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

Использование представлений
с вычисляемыми полями
Представления чрезвычайно полезны для упрощения ис-
пользования вычисляемых полей. Далее приведен оператор
SELECT, впервые использованный нами в уроке 7. Он из-
влекает предметы указанного заказа и вычисляет суммар-
ную стоимость для каждого предмета:
ВВОД
SELECT prod_id,
quantity,
item_price,
quantity*item_jprice AS expanded_price
FROM OrderItems
WHERE order num = 20008;

ВЫВОД
prod_id quantity item_price expanded_price

RGAN01 5 4.9900 24.9500


BR03 5 11.9900 59.9500
BNBG01 10 3.4900 34.9000
BNBG02 10 3.4900 34.9000
BNBG03 10 3.4900 34.9000
Для превращения его в представление необходимо вы-
полнить следующее:
ВВОД
CREATE VIEW OrderltemsExpanded AS
SELECT order_num,
prod_id,
quantity,
item_price,
quantity*item_price AS expanded_price
FROM Orderltems;
Чтобы получить информацию относительно заказа 2 0008
(она была выведена выше), необходимо сделать следующее:
ВВОД
FROM SELECT *
OrderltemsExpanded
WHERE order num = 20008;
192 Урок 18

ВЫВОД
order_num prod_id quantity item_price expanded_price

20008 RGAN01 5 4.99 24.95


20008 BR03 5 11.99 59.95
20008 BNBG01 10 3.49 34.90
20008 BNBG02 10 3.49 34.90
20008 BNBG03 10 3.49 34.90
Как видите, представления легко создавать, а использо-
вать еще легче. Будучи использованными корректно, пред-
ставления могут существенно упростить сложные манипу-
ляции с данными.

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

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

Что такое хранимые


процедуры
Большинство операций SQL, которые мы до сих пор вы-
полняли, просты в том смысле, что в них применяется
только один оператор по отношению к одной или несколь-
ким таблицам. Но не все операции столь просты — зачас-
тую приходится использовать несколько операторов для
выполнения сложной операции. Например, рассмотрим
следующие сценарии.
• При обработке заказа бывает необходимо удостове-
риться в том, что соответствующие товары есть на
складе.
• Если товары есть на складе, они должны быть заре-
зервированы, чтобы их не продали кому-нибудь еще,
а их количество, доступное другим покупателям,
должно быть уменьшено соответственно изменившей-
ся ситуации.
• Товары, отсутствующие на складе, должны быть зака-
заны, для этого нужно связаться с их поставщиком.
• Клиенту необходимо сообщить, какие товары есть на
складе (и могут быть отгружены немедленно) и заказ
на какие товары выполнен быть не может.
194 Урок 19

Очевидно, это не полный список примеров, но cyri


должна быть вам ясна. Решение подобной задачи потребуеп
применения многих операторов SQL по отношению ко мно
гим таблицам. Помимо того что сами SQL-операторы, подле
жащие выполнению в подобных случаях, и их порядок н<
постоянны, они могут (и будут) изменяться в зависимости оч
того, какие товары имеются на складе, а каких там нет.
Как бы вы написали этот код? Можно было бы написат!
каждый из операторов SQL отдельно и выполнить другие
операторы в зависимости от полученных результатов. Вак
пришлось бы делать это каждый раз, когда возникала бь:
необходимость подобной обработки данных (и для каждогс
приложения, которое в ней нуждается).
Вы могли бы также создать хранимую процедуру. Хра-
нимая процедура — это совокупность нескольких операто-
ров (или даже один оператор), сохраненная для последую-
щего использования. Ее можно рассматривать как команд-
ный файл, хотя на самом деле это нечто большее.

Access и MySQL
Хранимые процедуры не поддерживаются в Access.
Кроме того, когда эта книга готовилась к печати,
СУБД MySQL v4.x (текущая версия) также не поддер-
живала хранимые процедуры (их поддержку планиро-
валось осуществить в версии MySQL 5).

Гораздо больше информации


Хранимые процедуры— тема довольно сложная,
полностью ее рассмотреть можно только в отдельной
книге. Этот урок не научит вас всему, что необходимо
знать о хранимых процедурах. Скорее это введение в
данную тему, призванное познакомить вас с тем, что
собой представляют хранимые процедуры и что с их
помощью можно делать. По существу, представлен-
ные здесь примеры соответствуют только синтаксису
Oracle и SQL Server.
Работа с хранимыми процедурами 195

Для чего используют


хранимые процедуры
Теперь, когда вы знаете, что такое хранимые процедуры,
возникает другой вопрос: для чего их использовать? На это
существует множество причин, ниже приведены лишь ос-
новные.
• Для упрощения сложных операций (как уже говори-
лось в предыдущем примере) за счет инкапсуляции
процессов в один блок, простой для выполнения.
• Для обеспечения непротиворечивости данных и вме-
сте с тем без необходимости снова и снова воспроиз-
водить одну и ту же последовательность шагов. Если
все разработчики и приложения используют одни и те
же хранимые процедуры, значит, один и тот же код
будет использоваться всеми.
• Побочным эффектом этого является предотвращение
ошибок. Чем больше шагов необходимо выполнить,
тем выше вероятность появления ошибок. Предот-
вращение ошибок обеспечивает целостность данных.
• Для упрощения управления изменениями. Если таб-
лицы, имена столбцов, деловые правила (или что-то
подобное) изменяются, обновлять приходится только
код хранимой процедуры и ничего больше.
Побочным эффектом этого является повышение безо-
пасности. Ограничение доступа к основным данным
только через хранимые процедуры снижает вероят-
ность повреждения данных (случайного или предна-
меренного).
• Поскольку хранимые процедуры обычно сохраняются
в компилированном виде, СУБД тратит меньше вре-
мени на обработку их команд. Это приводит к повы-
шению производительности.
• Существуют элементы языка SQL и некоторые воз-
можности, реализуемые только в хранимых процеду-
рах. Хранимые процедуры, таким образом, можно
использовать для написания более гибкого и мощного
кода.
196 Урок 19

Итак, имеются три основных преимущества: простота,


безопасность и производительность. Очевидно, все они
чрезвычайно важны. Однако прежде чем вы броситесь пре-
вращать весь свой SQL-код в хранимые процедуры, взгля-
ните на другую строну медали.
• Синтаксис хранимых процедур весьма различен для
разных СУБД. Написать по-настоящему переносимый
код хранимой процедуры практически невозможно.
Следует также упомянуть о том, что метод вызова
самих хранимых процедур (их имена и метод переда-
чи им данных) может быть достаточно переносимым,
поэтому если вам необходимо перейти на другую
СУБД, по крайней мере код вашего клиентского при-
ложения, возможно, не придется изменять.
• Хранимые процедуры сложнее в написании, чем ос-
новные операторы SQL, их подготовка требует большей
квалификации и опыта. Поэтому многие администра-
торы баз данных ограничивают права на создание хра-
нимых процедур в качестве меры безопасности.
Несмотря на вышесказанное, хранимые процедуры весь-
ма полезны и непременно должны использоваться. В дейст-
вительности многие СУБД располагают всевозможными
хранимыми процедурами, которые используются для
управления базами данных и таблицами. Обратитесь к до-
кументации своей СУБД, чтобы получить больше информа-
ции по данному вопросу.

Не можете написать хранимые процедуры? Тогда


просто используйте их
Во многих СУБД различаются меры безопасности и
права доступа, необходимые для написания храни-
мых процедур, и меры безопасности и права доступа,
необходимые для их выполнения. И это хорошо. Если
вы не намерены писать свои хранимые процедуры,
используйте готовые, если они вам подходят.
Работа с хранимыми процедурами 197

Выполнение хранимых
процедур
Хранимые процедуры выполняются намного чаще, чем
пишутся, поэтому мы начнем именно с их выполнения.
Оператор SQL для выполнения хранимой процедуры —
EXECUTE — принимает имя хранимой процедуры и некото-
рые параметры, необходимые для перехода к ней. Посмот-
рите на этот пример:
ВВОД
EXECUTE AddNewProduct ('JTS01' ,
'Stuffed Eiffel Tower',
6.49,
'Plush stuffed toy with the
La Tour Eiffel in red white and blue')

Анализ
Здесь выполняется хранимая процедура по имени
AddNewProduct; она добавляет новый продукт в таблицу
Products. Хранимая процедура AddNewProduct принимает
четыре параметра: идентификатор поставщика (первичный
ключ таблицы Vendors), название продукта, цена и описа-
ние. Эти четыре параметра соответствуют четырем ожидае-
мым переменным хранимой процедуры (определенным как
часть самой хранимой процедуры). Данная хранимая про-
цедура добавляет новую строку в таблицу Products и рас-
пределяет эти передаваемые атрибуты по соответствующим
столбцам.
В таблице Products есть еще один столбец, нуждаю-
щийся в присвоении значения: столбец prod_id, который
является первичным ключом таблицы. Почему это значение
не передается в хранимую процедуру в виде атрибута? Для
того чтобы идентификаторы генерировались правильно,
безопаснее сделать этот процесс автоматизированным (и не
полагаться на конечного пользователя). Именно поэтому
хранимая процедура используется в этом примере, она вы-
полняет следующие действия.
• Подтверждает правильность передаваемых данных,
обеспечивая наличие значений у всех четырех пара-
метров.
198 Урок 19

• Генерирует уникальный идентификатор, который бу-


дет использован в качестве первичного ключа.
• Добавляет данные о новом продукте в таблицу
Products, сохраняя созданный первичный ключ к
передавая данные в соответствующие столбцы.
Такова основная форма выполнения хранимой процеду-
ры. В зависимости от СУБД могут быть использованы дру-
гие опции выполнения, включая следующие.
• Опциональные параметры со значениями по умолча-
нию, присваиваемыми в случае, если параметр не
предложен пользователем.
• Нестандартные параметры, указываемые в виде пар
параметр^ значение.
• Выходные параметры, позволяющие хранимой про-
цедуре обновлять параметр для использования его Е
выполняемом приложении.
• Значение даты, выбираемое оператором SELECT.
• Возвращаемые коды, позволяющие хранимой процеду-
ре возвращать значение в выполняемое приложение.

Создание хранимых процедур


Как уже говорилось, создание хранимой процедуры —
задача не из тривиальных. Чтобы вы могли понять, что она
собой представляет, рассмотрим простой пример: хранимук
процедуру, которая подсчитывает в списке адресатов числе
клиентов, имеющих адрес электронной почты.
Вот версия для СУБД Oracle:
ВВОД
CREATE PROCEDURE MailingListCount
(ListCount OUT NUMBER)
IS
BEGIN
SELECT * FROM Customers
WHERE NOT cust_email IS NULL;
ListCount := SQL%ROWCOUNT;
END;
Работа с хранимыми процедурами 199

Анализ
Эта хранимая процедура принимает один параметр, на-
зываемый ListCount. Вместо того чтобы передавать значе-
ние в хранимую процедуру, этот параметр передает значе-
ние из нее. Ключевое слово OUT указывает ей вести себя по-
добным образом. СУБД Oracle поддерживает параметры
типов IN (которые передаются в хранимые процедуры), OUT
(они передаются из хранимых процедур) и INOUT (они ис-
пользуются для передачи параметров в хранимые процеду-
ры и из них). Собственно код хранимой процедуры заклю-
чен между BEGIN и END, и здесь для выборки клиентов,
имеющих адреса электронной почты, выполняется простой
оператор SELECT. Затем передаваемому выходному пара-
метру ListCount присваивается значение, равное количест-
ву строк в выборке.
А вот версия для Microsoft SQL:
ВВОД
CREATE PROCEDURE MailingListCount
AS
DECLARE @cnt INTEGER
SELECT @cnt = COUNT(*)
FROM Customers
WHERE NOT cust_email IS NULL;
RETURN @cnt;

Анализ
Эта хранимая процедура вообще не принимает парамет-
ров. Вызываемое приложение выбирает нужное значение,
пользуясь тем, что в СУБД SQL Server поддерживается воз-
вращение кода. Здесь посредством оператора DECLARE объ-
явлена локальная переменная @cnt (имена всех локальных
переменных в SQL Server начинаются с символа @). Эта пе-
ременная затем используется в операторе SELECT, так что
он содержит значение, возвращаемое функцией COUNT ().
Наконец, оператор RETURN используется для возвращения
результатов подсчета в вызывающее приложение — RETURN
@cnt.
Приведем еще один пример, на этот раз мы будем добав-
лять новый заказ в таблицу Orders. Этот пример подходит
только для SQL Server, но он хорошо показывает, как нуж-
но использовать хранимые процедуры:
200 Урок 19

ВВОД
CREATE PROCEDURE NewOrder @cust_id CHAR(10)
AS
-- Объявление переменной для номера заказа
DECLARE @order_num INTEGER
-- Получение текущего наибольшего номера заказа
SELECT @order_num=MAX(order_num)
FROM Orders
Determine next order number
SELECT @order_num=@order_num+l
-- Добавление нового заказа
INSERT INTO Orders(order_num order_date, cust_id)
VALUES(@order_num, GETDATE() @cust id)
-- Возвращение номера заказа
RETURN ©order nura;

Анализ
Эта хранимая процедура создает новый заказ в таблице
Orders. Она принимает один параметр — идентификатор
клиента, сделавшего заказ. Два других столбца таблицы,
номер и дата заказа, генерируются автоматически в самой
хранимой процедуре. Вначале в коде объявляется локаль-
ная переменная для хранения номера заказа. Затем выби-
рается текущий наибольший номер заказа (посредством
функции МАХ ()) и увеличивается на единицу (с помощью
оператора SELECT). После этого добавляется заказ посредст-
вом оператора INSERT с использованием только что сгене-
рированного номера заказа, выбирается текущая системная
дата (с помощью функции GETDATE ()) и передается иден-
тификатор клиента. Наконец, номер заказа (необходимый
для обработки предметов заказа) возвращается как RETURN
@order_nura. Отметим, что код снабжен комментариями, это
всегда следует делать при написании хранимых процедур.

Комментируйте ваш код


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

Стандартный способ ввода в код комментариев состоит в


предварении их символами -- (двумя дефисами). Некото-
рые СУБД поддерживают и альтернативный синтаксис
комментариев, но все поддерживают -- (два дефиса), и по-
этому лучше всего использовать их.
Вот несколько различных версий одного и того же кода
для SQL Server:

ВВОД
CREATE PROCEDURE NewOrder @cust_id CHAR(10)
AS
-- Добавление нового заказа
INSERT INTO Orders(cust_id)
VALUES(@cust_id)
-- Возвращение номера заказа
SELECT order num = ©©IDENTITY;

Анализ
Эта хранимая процедура также создает новый заказ в
таблице O r d e r s . На этот раз СУБД сама генерирует номер
заказа. Большинство СУБД поддерживают такой тип функ-
циональности; SQL Server обращается к этим автоинкре-
ментируемым столбцам как к полям I d e n t i t y (другие
СУБД используют такие имена, как Auto Number или
Sequences). Опять же, передается только один параметр:
идентификатор клиента, сделавшего заказ. Номер и дата за-
каза не указываются вообще — СУБД использует значение
по умолчанию для даты (функция GETDATE ()), а номер зака-
за генерируется автоматически. Как можно узнать, кокой
идентификатор пользователя был сгенерирован? В СУБД SQL
Serer для этого используется глобальная переменная
©©IDENTITY, возвращаемая в вызывающее приложение (на
этот раз с использованием оператора SELECT).
Как видите, хранимые процедуры очень часто позволяют
решить одну и ту же задачу разными способами. Метод, ко-
торый вы выберете, во многом будет зависеть от особенно-
стей СУБД, которую вы используете.
202 Урок 19

Резюме
В этом уроке вы узнали, что такое хранимые процедуры
и для чего они используются. Вы также познакомились с
основами синтаксиса, применяемого для выполнения и соз-
дания хранимых процедур, и узнали о некоторых способах
их использования. Возможно, в вашей СУБД форма выпол-
нения этих функций будет несколько иной и в ваше распо-
ряжение будут предоставлены возможности, не упомянутые
в этой книге. За дополнительной информацией рекоменду-
ем обратиться к документации вашей СУБД.
Урок 20

Обработка транзакций
В этом уроке вы узнаете, что такое транзакции и как ис-
пользовать операторы COMMIT и ROLLBACK для их обработки.

Что такое обработка


транзакций
Обработка транзакций обеспечивает сохранение целост-
ности базы данных за счет того, что пакеты операций SQL
выполняются полностью или не выполняются вовсе.
Как объяснялось в уроке 12, "Объединение таблиц", ре-
ляционные базы данных организованы таким образом, что
информация в них хранится во многих таблицах. Благода-
ря этому облегчается манипулирование, управление данны-
ми, а также их повторное использование. Не вдаваясь в
подробности, как и почему именно так устроены реляцион-
ные базы данных, следует заметить, что схемы всех хорошо
спроектированных баз данных можно в какой-то степени
отнести к реляционным.
Таблица Orders, которую мы использовали в последних
18-ти уроках, — хороший пример. Заказы хранятся в двух
таблицах, в таблице Orderltems хранится информация об
отдельных предметах заказов. Эти две таблицы связаны (со-
отнесены) между собой с помощью уникального идентифика-
тора, который называется первичный ключ (см. урок 1, "Что
такое SQL"). Эти таблицы, кроме того, связаны и с другими
таблицами, содержащими информацию о клиентах и про-
дуктах.
Процесс добавления нового заказа состоит в выполнении
следующих этапов.
1. Проверка, содержится ли информация о клиенте в базе
данных. Если нет, такая информация добавляется.
204 Урок 20

2. Выборка идентификатора клиента.


3. Добавление строки в таблицу Orders, связывающую
ее (строку) с идентификатором клиента.
4. Выборка идентификатора нового заказа, присвоенного
ему в таблице Orders.
5. Добавление одной строки в таблицу Orderltems для
каждого заказанного предмета, соотнесение его с таб-
лицей Orders посредством выбранного идентифика-
тора (и с таблицей Products посредством идентифи-
катора продукта).
Теперь предположим, что какая-то ошибка в базе дан-
ных (например, нехватка места на диске, ограничения, свя-
занные с безопасностью, блокировка таблицы) помешала
завершить эту последовательность действий.
Что случится с данными?
Хорошо, если ошибка произойдет после добавления ин-
формации о клиенте в таблицу, но до того как она будет
добавлена в таблицу Orders — в этом случае проблем не
будет. Вы можете иметь данные о клиентах без заказов.
При повторном выполнении последовательности добавлен-
ная запись о клиенте будет возвращена и использована. Вы
сможете легко продолжить работу с того места, на котором
остановились.
Но что если ошибка произойдет после того, как была до-
бавлена строка в таблицу Orders, но до того, как будут до-
бавлены строки в таблицу Orderltems? Теперь в вашей ба-
зе данных будет присутствовать пустой заказ.
Еще хуже: что если система сделает ошибку в процессе
добавления строк в таблицу Orderltems? В таком случае в
вашу базу данных заказ будет внесен лишь частично, и вы
даже не будете знать об этом.
Как можно решить эту проблему? Именно здесь в игру
вступает транзактная организация обработки данных, кото-
рую мы ради краткости будем называть обработка тран-
закций. Обработка транзакций — это механизм, используе-
мый для управления наборами операций SQL, которые
должны быть выполнены в пакете, т.е. таким образом, что-
бы в базу данных не могли попасть результаты частичного
выполнения этого пакета операций. При обработке тран-
закций вы можете быть уверенными в том, что выполнение
набора операций не было прервано на середине — они или
Обработка транзакций 205

были выполнены все, или не была выполнена ни одна из


них (если только не было явно указано иное). Если ошибки
не произошло, результаты работы всего набора операторов
фиксируются (записываются) в таблицах базы данных. Ес-
ли произошла ошибка, должна быть выполнена отмена (ан-
нулирование) всех операций, чтобы возвратить базу данных
в известное и безопасное состояние.
Итак, если вернуться к нашему примеру, то вот как
должен на самом деле выполняться процесс.
1. Проверка, содержится ли информация о клиенте в базе
данных. Если нет, такая информация добавляется.
2. Фиксация информации о клиенте.
3. Выборка идентификатора клиента.
4. Добавление строки в таблицу Orders.
5. Если во время добавления строки в таблицу Orders
происходит ошибка, операция отменяется.
6. Выборка идентификатора нового заказа, присвоенного
ему в таблице Orders
7. Добавление одной строки в таблицу Orderlteras для
каждого заказанного предмета.
8. Если в процессе добавления строк в таблицу
Order Items происходит ошибка, добавление всех
строк в таблицу Orderltems отменяется.
При работе с транзакциями вы часто будете сталкивать-
ся с одними и теми же терминами:
• Транзакция (Transaction). Блок операторов SQL.
• Отмена (Rollback). Процесс аннулирования указан-
ных операторов SQL (такой процесс иногда называют
"откат").
• Фиксация (Commit). Запись несохраненных операто-
ров SQL в таблицы базы данных.
• Точка сохранения (Savepoint). Временное состояние
в ходе выполнения транзакции, в которое можно
вернуться после отмены части операций пакета (в от-
личие от отмены всей транзакции). Иногда это со-
стояние называют "точка отката".
206 Урок 2 0

Действие каких операторов можно отменить?


Обработка транзакций используется в ходе управле-
ния действием операторов INSERT, UPDATE И DELETE.
Вы не можете отменить действие оператора S E L E C T .
(В выполнении такой отмены вообще нет смысла.) Вы
не можете отменить операции CREATE ИЛИ DROP. ЭТИ
операторы можно использовать в блоке операторов
транзакции, но если вам понадобится выполнить от-
мену (откат), действие этих операторов аннулировано
не будет.

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

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


ее SQL-операторы на логические части и явно указать, ко-
гда может быть выполнена отмена, а когда нет.
В некоторых СУБД требуется, чтобы вы явно отметили
начало и конец каждого блока операторов транзакции. На-
пример, в SQL Server нужно сделать следующее:
ВВОД
BEGIN TRANSACTION
COMMIT TRANSACTION

Анализ
В этом примере все операторы, заключенные между
BEGIN TRANSACTION И COMMIT TRANSACTION, ДОЛЖНЫ быть
или выполнены, или не выполнены.
Эквивалентный код для MySQL таков:
Обработка транзакций 207

ВВОД
START TRANSACTION

ВВОД
В СУБД PostgreSQL используется синтаксис ANSI SQL:
ввод
BEGIN;

В других СУБД используются вариации на указанную


тему.

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


Оператор ROLLBACK используется для отмены (аннулиро-
вания) операторов SQL, как показано ниже:
ВВОД
DELETE FROM Orders;
ROLLBACK;

Анализ
В этом примере выполняется и сразу же, посредством
оператора ROLLBACK, аннулируется операция DELETE. Хотя
это и не самый полезный пример, он все равно показывает,
что, будучи включенными в блок транзакции, операции
DELETE (а также INSERT и UPDATE) не являются оконча-
тельными.

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


Обычно после выполнения операторов SQL результаты
записываются непосредственно к таблицы баз данных. Это
называется неявная фиксация — операция фиксации (со-
хранения или записи) выполняется автоматически.
Однако внутри блока транзакции фиксация неявно мо-
жет и не проводиться. Это зависит от того, с какой СУБД
вы работаете. Некоторые СУБД трактуют завершение тран-
закции как неявную фиксацию.
208 Урок 20

Для безусловного выполнения неявной фиксации ис-


пользуется оператор COMMIT. Вот соответствующий пример
для SQL Server:
ВВОД
BEGIN TRANSACTION
DELETE Orderltems WHERE order_num = 12345
DELETE Orders WHERE order_num = 12345
COMMIT TRANSACTION

Анализ
В этом примере для SQL Server заказ номер 12345 пол-
ностью удаляется из системы. Поскольку это приводит к
обновлению двух таблиц базы данных, Orders и
Orderltems, блок транзакции применяется для того, чтобы
заказ не мог быть удален лишь частично. Конечный опера-
тор COMMIT записывает изменения только в случае, если не
произошло ошибки. Если первый оператор будет выполнен,
а второй, из-за ошибки, не выполнен, удаление не будет
зафиксировано.
Чтобы выполнить то же самое в СУБД Oracle, нужно
сделать следующее:
ВВОД
DELETE Orderltems WHERE order_num = 12345;
DELETE Orders WHERE order_num = 12345;
COMMIT;

Использование точек сохранения


Простые операторы ROLLBACK и COMMIT позволяют запи-
сывать или отменять транзакции в целом. Хотя это вполне
применимо по отношению к простым транзакциям, для бо-
лее сложных могут понадобиться частичные фиксации или
отмены.
Например, процесс добавления заказа, описанный выше,
представляет собой одну транзакцию. Если произойдет
ошибка, вы просто вернетесь в состояние, когда строка в
таблицу Orders еще не была добавлена. Но вы вряд ли за-
хотите отменить добавление данных в таблицу Customers
(если оно было сделано).
Для отмены части транзакции вы должны иметь воз-
можность размещения меток в стратегически важных точ-
Обработка транзакций 209

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


сможете вернуть базу данных в состояние, соответствующее
одной из меток.
В языке SQL эти метки называются точками сохранения
(savepoints). Для создания такой точки в СУБД MySQL и
Oracle применяется оператор SAVEPOINT:

ВВОД
SAVEPOINT deletel;
В SQL Server и Sybase нужно сделать следующее:

ВВОД
SAVE TRANSACTION deletel;
Каждая точка сохранения должна иметь уникальное
имя, идентифицирующее ее таким образом, чтобы, когда
вы выполняете отмену, СУБД "знала", в какую точку она
должна вернуться. Чтобы выполнить отмену действия всех
операторов после этой точки, в СУБД SQL Server нужно
выполнить следующее:

ВВОД
ROLLBACK TRANSACTION deletel;
В MySQL и Oracle можно сделать так:

ВВОД
ROLLBACK TO deletel;
А вот полный пример для SQL Server:

ВВОД
BEGIN TRANSACTION
INSERT INTO Customers(cust_id, cust_name)
VALUES(4000000010', 'Toys Emporium');
SAVE TRANSACTION StartOrder;
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20100,'2001/12/1','1000000010');
IF @@ERROR о 0 ROLLBACK TRANSACTION StartOrder;
INSERT INTO Orderltems(order_num, order_item,
(
i>prod_id, quantity, item_price)
VALUES(20010, 1, 'BR011, 100, 5.49);
IF @@ERROR <> 0 ROLLBACK TRANSACTION StartOrder;
INSERT INTO Orderltems(order_num, order_item,
4>prod_id, quantity, item_price)
1
VALUES(20010, 2, 'BR03 , 100, 10.99);
210 Урок 20

IF @@ERR0R <> 0 ROLLBACK TRANSACTION StartOrderj


COMMIT TRANSACTION

Анализ
Здесь имеется набор, состоящий из четырех операторо!
INSERT, включенных в блок транзакции. Точка сохранения
определена после первого оператора INSERT, так что еслк
какая-то из последующих операций INSERT закончится не-
удачей, отмена транзакции произойдет лишь до этой точки
В SQL Server для контроля успешности завершения какой
либо операции может быть использована переменная с име-
нем @@ERROR. (В других СУБД используются иные функция
или переменные для возвращения такой информации.) Ес-
ли переменная @@ERROR возвращает значение, отличное oi
О, значит, произошла ошибка и транзакция отменяется дс
точки сохранения. Если обработка транзакции в целом за-
вершается успешно, выполняется операция COMMIT для со-
хранения данных.
Чем больше точек сохранения, тем лучше
Вы можете создать столько точек сохранения в ва-
шем SQL-коде, сколько захотите, и чем больше, тем
лучше. Почему? Потому что чем больше у вас точек
сохранения, тем большая гибкость вам доступна в
управлении отменами.

Резюме
Транзакции представляют собой блоки из операторов
SQL, которые должны выполняться в пакетном режиме (все
вместе). Вы познакомились с правилами использования
операторов COMMIT и ROLLBACK для явного управления про-
цессами записи и отмены результатов операций. Вы также
узнали, как нужно использовать точки сохранения для
обеспечения более высокой степени контроля за выполне-
нием операций отмены.
Урок 21

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

Что такое курсоры


Операции выборки SQL работают с наборами строк, ко-
торые называются результирующие множества. Все воз-
вращаемые строки являются строками, соответствующими
примененному SQL-оператору, их может быть нуль или
больше. При использовании простых операторов SELECT не-
возможно получить первую строку, последнюю строку или
предыдущие 10 строк. Это объясняется особенностями
функционирования реляционной СУБД.

Результирующее множество
Результаты, возвращаемые в ответ на SQL-запрос.

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


или обратном направлении один или несколько раз. Именно
для этого используются курсоры. Курсор представляет со-
бой запрос к базе данных, хранящийся на сервере СУБД, —
это не оператор SELECT, но результирующее множество,
выборка, полученная в результате действия оператора
SELECT. После того как курсор сохранен, приложения мо-
гут "прокручивать" (просматривать) данные в прямом или
обратном направлении, как только возникает такая потреб-
ность.
212 Урок 21

Поддержка в MySQL
В то время, когда эта книга готовилась к печати, СУБД
MySQL еще не поддерживала курсоры (поддержку
для них планируется ввести в MySQL 5).

Различные СУБД поддерживают разные опции и воз


можности курсоров. Наиболее часто обеспечиваются еле
дующие из них.
• Возможность помечать курсор как предназначенньп
только для чтения, в результате чего данные могу
считываться, но не могут обновляться или удаляться.
• Возможность управлять направлением выполняемы:
операций (вперед, назад, первая, последняя, абсо
лютное положение, относительное положение и т.д.).
• Возможность помечать некоторые столбцы как редак
тируемые, а другие — как нередактируемые.
• Указание области видимости, благодаря чему курсо]
может быть доступен или для запроса, посредством
которого он был создан (например, для хранимо!
процедуры), или для всех запросов.
• Указание СУБД скопировать выбранные данньи
(в противоположность работе с "живыми" данными ]
таблицах), чтобы они не изменялись в промежуто!
времени между открытием курсора и обращением i
нему.

Поведение реляционных СУБД становится похо-


жим на поведение нереляционных
В качестве сравнения отметим, что организация дос-
тупа и просмотр строк в такой форме в действитель-
ности соответствует применению индексно-последо-
вательного метода доступа (Indexed Sequential Access
Method, ISAM) в базах данных (таких как Btrieve и
dBASE). Курсоры как часть спецификации SQL инте-
ресны тем, что с их помощью можно заставить реля-
ционную базу данных вести себя подобно базе дан-
HbixTnnalSAM.
Использование курсоров 213

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


ми приложениями, предоставляющими пользователям воз-
можность прокручивать отображаемые на экране данные
вперед и назад, просматривать их или изменять.
Курсоры и Web-приложения
Курсоры практически бесполезны, если их применять
к приложениям, основанным на Web-технологиях (на-
пример, таких как ASP, ColdFusion, PHP и JSP). Курсо-
ры предназначены для использования в течение се-
анса связи между клиентским приложением и серве-
ром, но эта модель "клиент-сервер" не годится для
мира Web-приложений, потому что сервер приложе-
ний является клиентом базы данных, а не конечным
пользователем. А раз так, то большинство разработ-
чиков приложений избегают использования курсоров
и добиваются выполнения нужных функций, если это
необходимо, своими силами.

Работа с курсорами
Работу с курсором можно разделить на несколько четко
выраженных стадий.
• Прежде чем курсор может быть использован, его сле-
дует объявить (определить). В ходе этого процесса
выборка данных не производится, просто определяет-
ся оператор SELECT, который будет использован, и
некоторые опции курсора.
• После объявления курсор может быть открыт для ис-
пользования. В ходе этого процесса уже производится
выборка данных согласно предварительно определен-
ному оператору SELECT.
• После того как курсор заполнен данными, могут быть
извлечены (выбраны) отдельные необходимые строки.
• После того как это сделано, курсор должен быть за-
крыт и, возможно, должны быть освобождены ресур-
сы, которые он занимал (в зависимости от СУБД).
214 Урок 21

После того как курсор объявлен, его можно открывать


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

Создание курсоров
Курсоры создаются с помощью оператора DECLARE, сив
таксис которого различен для разных СУБД. Операто
DECLARE дает курсору имя и принимает оператор SELEd
дополненный при необходимости предложением WHERE :
другими. Чтобы показать, как это работает, мы создадим
курсор, который будет делать выборку всех клиентов, н
имеющих адресов электронной почты, в виде части прилс
жения, позволяющего служащему вводить недостающие ад
реса.
Приведенная версия подходит для DB2, SQL Server i
Sybase:
ВВОД
DECLARE CustCursor CURSOR
FOR
SELECT * FROM Customers
WHERE cust email IS NULL
А вот версия для Oracle и PostgreSQL:
ВВОД
DECLARE CURSOR CustCursor
IS
SELECT * FROM Customers
WHERE cust email IS NULL

Анализ
В обеих версиях для определения имени курсора исполь
зуется оператор DECLARE — в данном случае это будет им*
CustCursor. Оператор SELECT определяет курсор, содер
жащий имена всех клиентов, которые не имеют адрес*
электронной почты (соответствующее значение равно NULL).
Теперь, после того как курсор определен, его можно от
крыть.
Использование курсоров 215

Использование курсоров
Курсоры открываются с помощью оператора OPEN
i^JRSOR, синтаксис которого настолько прост, что его под-
{ерживают большинство СУБД:
)PEN CURSOR CustCursor
При обработке оператора OPEN CURSOR выполняется за-
ipoc, и выборка данных сохраняется для последующих
фосмотра и прокрутки.
Теперь доступ к данным этого курсора может быть по-
гучен с помощью оператора FETCH. Оператор FETCH указы-
вает строки, которые должны быть выбраны, откуда они
щ ж н ы быть выбраны и где их следует сохранить (имя пе-
ременной, например). В первом примере используется син-
таксис Oracle для выборки одной строки курсора (первой).

ВВОД
DECLARE TYPE CustCursor IS REF CURSOR
Ь RETURN Customers%ROWTYPE;
DECLARE CustRecord Customers%ROWTYPE
3EGIN
OPEN CustCursor;
FETCH CustCursor INTO CustRecord;
CLOSE CustCursor;
END;

Анализ
В данном примере оператор FETCH используется для вы-
борки текущей строки (автоматически он начнет с первой
строки) в переменную, объявленную с именем CustRecord.
С выбранными данными ничего не делается.
В следующем примере (в нем вновь используется син-
таксис Oracle) выбранные данные подвергаются цикличе-
ской обработке от первой строки до последней:
ВВОД
DECLARE TYPE CustCursor IS REF CURSOR
•^ RETURN CuStomers%ROWTYPE;
DECLARE CustRecord Customers%ROWTYPE
BEGIN
OPEN CustCursor;
LOOP
FETCH CustCursor INTO CustRecord;
EXIT WHEN CustCursor%NOTFOUND;
216 Урок 21

END LOOP;
CLOSE CustCursor;
END;

Анализ
Аналогично предыдущему примеру, здесь используете
оператор FETCH для выборки текущей строки в перемер
ную, объявленную с именем CustRecord. Однако в отличи
от предыдущего примера, здесь оператор FETCH находите
внутри цикла LOOP, так что он выполняется снова и снов*
Код EXIT WHEN CustCursor%NOTFOUND указывает, что это
процесс должен быть завершен (выход из цикла), когд
больше не останется строк для выборки. В этом пример
также не выполняется никакой обработки, тогда как в р(
альном коде вам следовало бы заменить . . . вашим co6ci
венным кодом.
Вот другой пример, на этот раз с использованием сиь
таксиса Microsoft SQL Server:

ВВОД
DECLARE @cust_id CHAR(10),
@cust_name CHAR(50),
@cust_address CHAR(50),
@cust_city CHAR(50),
@cust_state CHAR(5),
@cust_ZIP CHAR(10),
@cust_country CHAR(50),
@cust_contact CHAR(50),
@cust_email CHAR(255),
OPEN CustCursor
FETCH NEXT FROM CustCursor
INTO @cust_id, @cust_name, @cust_address,
@cust_city, @cust_state, @cust_ZIP,
@cust_country, @cust_contact, @cust_email
WHILE @@FETCH_STATUS = 0
BEGIN

FETCH NEXT FROM CustCursor


INTO @cust_id, @cust_name, @cust_address,
@cust_city, @cust_state, @cust_ZIP,
@cust_country, @cust_contact, @cust_email
END
CLOSE CustCursor
Использование курсоров 217

Анализ
В этом примере переменные объявляются для каждого
из выбираемых столбцов, а операторы FETCH осуществляют
выборку строки и сохранение значений в этих переменных.
Цикл WHILE используется для организации цикла по стро-
кам, а условие WHILE @@FETCH_STATUS = 0 обеспечивает
завершение обработки (выход из цикла) после того как все
строки будут извлечены. И вновь этот пример ничего на
самом деле не обрабатывает. В реальном коде нужно заме-
нить . . . вашим собственным кодом.

Закрытие курсоров
Как следует из предыдущих примеров, после использо-
вания курсоров их нужно закрывать. Кроме того, в некото-
рых СУБД (таких как SQL Server) требуется, чтобы ресур-
сы, занятые курсором, были освобождены явным образом.
Вот соответствующий синтаксис для СУБД DB2, Oracle и
PostgreSQL:
ВВОД
CLOSE CustCursor
А это синтаксис для Microsoft SQL Server:
ВВОД
CLOSE CustCursor
DEALLOCATE CURSOR CustCursor
Для закрытия курсора используется оператор CLOSE; по-
сле того как курсор закрыт, его нельзя использовать, не
открыв перед этим вновь. Однако его не нужно объявлять
заново при повторном использовании, достаточно оператора
OPEN.

Резюме
В этом уроке вы узнали, что такое курсоры и как их ис-
пользуют. В вашей СУБД, возможно, эти функции выпол-
няются несколько иначе, а также доступны функции, не
упомянутые в книге. За дополнительной информацией вам
следует обратиться к документации вашей СУБД.
Урок 22

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

Что такое ограничения


Было разработано много версий языка SQL, прежде чем
он стал столь полноценным и мощным. Многие из наиболее
эффективных инструментов манипуляции с данными осно-
ваны на таких методах, которые обеспечиваются с помо-
щью ограничений.
И реляционные таблицы, и целостность на уровне ссылок
несколько раз упоминались в предыдущих уроках. В них, в
частности, говорилось, что реляционные базы данных хранят
данные во многих таблицах, каждая из которых содержит
данные, связанные с данными из других таблиц.
Для создания ссылок из одной таблицы на другие ис-
пользуются ключи (отсюда термин целостность на уровне
ссылок).
Чтобы реляционная база данных работала должным обра-
зом, необходимо удостовериться в том, что данные в ее таб-
лицы введены правильно. Например, если в таблице Orders
хранится информация о заказе, а в Order Items — его де-
тальное описание, вы должны быть уверены, что все иденти-
фикаторы заказов, упомянутые в таблице Orderltems, су-
ществуют и в таблице Orders. Аналогично, каждый кли-
ент, упомянутый в таблице Orders, не должен быть забыт
и в таблице Customers.
Хотя вы можете проводить соответствующие проверки,
прежде чем вводить новые строки (выполняя оператор
220 Урок 22

SELECT для другой таблицы, дабы удостовериться в том,


что нужные значения правильны), лучше избегать такой
практики по следующим причинам.
• Если правила, обеспечивающие целостность базы
данных, принудительно осуществляются на клиент-
ском уровне, их придется выполнять каждому клиен-
ту (некоторые из клиентов наверняка не захотят это-
го делать).
• Вам придется принудительно ввести правила для вы-
полнения операций UPDATE И DELETE.
• Выполнение проверок на клиентской стороне — про-
цесс, отнимающий много времени.
Заставить СУБД выполнять эти проверки — метод на-
много более эффективный.

„Ограничения
Правила, регламентирующие ввод данных в базу дан-
ных и манипуляцию ими.

СУБД принудительно обеспечивают целостность на


уровне ссылок за счет ограничений, налагаемых на табли-
цы базы данных. Большинство ограничений вводится в оп-
ределениях таблиц (с помощью операторов CREATE TABLE
или ALTER TABLE, об этом рассказывалось в уроке 17,
"Создание таблиц и работа с ними").

Предупреждение
Существует несколько типов ограничений, и каждая
СУБД обеспечивает свой собственный уровень их
поддержки. Следовательно, примеры, приведенные
ниже, могут работать не так, как вы предполагаете.
Обратитесь к документации своей СУБД, прежде чем
выполнять их.

Первичные ключи
О первичных ключах мы рассказывали в уроке 1, "Что
такое SQL". Первичный ключ — это особое ограничение,
применяемое для того, чтобы значения в столбце (или на-
Расширенные возможности SQL 221

боре столбцов) были уникальными и никогда не изменя-


лись. Другими словами, это столбец (или столбцы) табли-
цы, значения которого однозначно идентифицируют каж-
дую строку таблицы. Это облегчает непосредственное мани-
пулирование отдельными строками и взаимодействие с
ними. Без первичных ключей было бы очень трудно обнов-
лять или удалять определенные строки, не задевая при
этом другие.
Любой столбец таблицы может быть назначен на роль
первичного ключа, но только если он удовлетворяет сле-
дующим условиям.
• Никакие две строки не могут иметь одно и то же зна-
чение первичного ключа.
• Каждая строка должна иметь какое-то значение пер-
вичного ключа. (В таких столбцах не должно быть
разрешено использование значений NULL.)
• Столбец, содержащий значения первичного ключа, не
может быть модифицирован или обновлен.
• Значения первичного ключа ни при каких обстоя-
тельствах не могут быть использованы повторно. Ес-
ли какая-то строка удалена из таблицы, ее первич-
ный ключ не может быть назначен какой-то другой
строке.
Одним из способов определения первичных ключей яв-
ляется их создание:
ВВОД
CREATE TABLE Vendors
(
vend_id CHAR(10) NOT NULL PRIMARY KEY,
vend_name CHAR(50) NOT NULL,
vend_address CHAR(50) NULL,
vend_city CHAR(50) NULL,
vend_state CHAR(5) NULL,
vend_ZIP CHAR(10) NULL
vend_country CHAR(50) NULL

Анализ
В этом примере в определение таблицы добавлено клю-
чевое слово PRIMARY KEY, так что столбец vend_id стано-
вится первичным ключом.
222 Урок 22

ВВОД
ALTER TABLE Vendors
ADD CONSTRAINT PRIMARY KEY (vend id);

Анализ
Здесь в качестве первичного ключа определен тот же са-
мый столбец, но использован синтаксис CONSTRAINT. Этот
синтаксис может быть использован в операторах CREATE
TABLE И ALTER TABLE.

Внешние ключи
Внешний ключ — это столбец одной таблицы, значения
которого совпадают со значениями столбца, являющегося
первичным ключом другой таблицы. Внешние ключи —
очень важная часть механизма обеспечения ссылочной цело-
стности данных. Чтобы разобраться в том, что собой пред-
ставляют внешние ключи, рассмотрим следующий пример.
Таблица Orders содержит единственную строку для ка-
ждого заказа, зафиксированного в базе данных. Информа-
ция о клиенте хранится в таблице Customers. Заказы в
таблице Orders связаны с определенными строками в таб-
лице Customers за счет идентификатора клиента. Иденти-
фикатор клиента является первичным ключом в таблице
Customers; каждый клиент имеет уникальный идентифи-
катор. Номер заказа является первичным ключом в табли-
це Orders; каждый заказ имеет свой уникальный номер.
Значения в столбце таблицы Orders, содержащем иден-
тификаторы клиентов, не обязательно уникальные. Если
клиент сделал несколько заказов, может быть несколько
строк с тем же самым идентификатором клиента (хотя ка-
ждая из них будет иметь свой номер заказа). В то же время
единственные значения, которые могут появиться в столбце
идентификаторов клиента таблицы Orders, — это иденти-
фикаторы клиентов из таблицы Customers.
Именно так и образуются внешние ключи. В нашем
примере внешний ключ определен как столбец идентифи-
каторов клиента, содержащихся в первичном ключе табли-
цы Customers, так что этот столбец может принимать
только значения, имеющиеся в первичном ключе таблицы
Customers.
Расширенные возможности SQL 223

Вот один из способов определения внешнего ключа:


ВВОД
CREATE TABLE Orders
(
order_num INTEGER NOT NULL PRIMARY KEY,
order_date DATETIME NOT NULL,
cust_id CHAR(10) NOT NULL REFERENCES
"^Customers (cust id)

Анализ
Это определение таблицы, использующее ключевое слово
REFERENCES для утверждения того факта, что любое значе-
ние в столбце cust_id должно быть также и в столбце
cust_id таблицы Customers.
Того же результата можно было бы добиться с использо-
ванием синтаксиса CONSTRAINT в операторе ALTER TABLE:
ВВОД
ALTER TABLE Customers
ADD CONSTRAINT
FOREIGN KEY (cust id) REFERENCES Customers (cust id)

Внешние ключи могут воспрепятствовать слу-


чайному удалению данных
В дополнение к тому, что внешние ключи помогают
принудительно сохранять целостность ссылочных дан-
ных, они могут выполнять много других важных функ-
ций. После того как внешний ключ определен, ваша
СУБД не позволит удалять строки, связанные со стро-
ками в других таблицах. Например, вы не сможете уда-
лить информацию о клиенте, у которого есть заказы.
Единственный способ удалить информацию о таком
клиенте состоит в предварительном удалении связан-
ных с ним заказов (для чего, в свою очередь, нужно
удалить информацию о предметах этих заказов). По-
скольку требуется столь методичное и целенаправлен-
ное удаление, внешние ключи могут оказать помощь в
предотвращении случайного удаления данных.
224 Урок 22

Однако в некоторых СУБД поддерживается возмож-


ность, получившая название каскадное удаление. Ес-
ли такая функция реализована, можно удалять все
связанные с этой строкой данные при удалении ее из
таблицы. Например, если возможно каскадное уда-
ление и имя клиента удаляется из таблицы
Customers, все связанные с его заказом строки уда-
ляются автоматически.

Ограничения уникальности
Ограничения уникальности обеспечивают уникальность
всех данных в столбце (или в наборе столбцов). Такие
столбцы похожи на первичные ключи, но имеются и важ-
ные отличия.
• Таблица может содержать множество ограничений
уникальности, но у нее должен быть только один
первичный ключ.
• Столбцы с ограничением уникальности могут содер-
жать значения NULL.
• Столбцы с ограничением уникальности можно моди-
фицировать и обновлять.
• Значения столбцов с ограничением уникальности
можно использовать повторно.
• В отличие от первичных ключей, ограничения уни-
кальности не могут быть использованы для определе-
ния внешних ключей.
Примером использования ограничения может служить
таблица с данными о служащих. Каждый из них имеет
свой уникальный номер карточки социального страхования,
но вы вряд ли будете использовать его в качестве первично-
го ключа, поскольку он слишком длинный (и, кроме того,
вы вряд ли захотите сделать эту информацию легко доступ-
ной). Поэтому каждому служащему присваивается уни-
кальный идентификатор (первичный ключ) в дополнение к
его номеру карточки социального страхования.
Поскольку идентификатор служащего является первич-
ным ключом, вы можете быть уверены в том, что он уни-
кален. К примеру, для того чтобы СУБД проверила уни-
Расширенные возможности SQL 225

кальность каждого номера карточки социального страхова-


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

Ограничения на значения столбца


Ограничения на значения столбца используют для того,
чтобы данные в столбце (или наборе столбцов) соответство-
вали ряду определенных вами критериев. Наиболее часто
используемыми из них являются следующие:
• Ограничение максимального и минимального значе-
ний — например, для предотвращения появления за-
казов на 0 (нуль) предметов (хотя 0 и является до-
пустимым числом).
• Указание диапазонов — например, ограничение на
то, чтобы дата отгрузки наступала позже или соот-
ветствовала текущей дате и не отстояла от нее боль-
ше, чем на год.
• Разрешение только определенных значений — на-
пример, разрешение вводить в поле "пол" только бук-
вы М или F.
Типы данных (см. урок 1) ограничивают типы данных,
которые могут храниться в столбце. Ограничения на значе-
ния столбца предъявляют дополнительные требования уже
к данным определенного типа.
В следующем примере накладывается ограничение на
значения столбцов таблицы Order I t ems с тем, чтобы для
всех предметов указывалось количество, большее 0:

CREATE TABLE Orderltems

order_num INTEGER NOT NULL,


order_item INTEGER NOT NULL,
prod_id CHAR(10) NOT NULL,
226 Урок 22

quantity INTEGER NOT NULL CHECK


4> (quantity > 0) ,
item_jjrice MONEY NOT NULL

Анализ
После применения этого ограничения каждая добавляе-
мая (или обновляемая) строка будет проверяться на пред-
мет того, что количество предметов больше нуля.
Чтобы проконтролировать тот факт, что в столбце с на-
именованием пола может содержаться только буква М или
F, можно сделать следующее в операторе ALTER TABLE:
ВВОД
ADD CONSTRAINT CHECK ( g e n d e r LIKE ' [MF] ' )

Пользовательские типы данных


Пользователи некоторых СУБД могут определять
собственные типы данных. Обычно это весьма про-
стые типы данных, определенные с контрольными
(или другими) ограничениями. Например, вы можете
определить свой тип данных, назвав его gender (пол);
он будет представлять собой тип данных, состоящих
из одной буквы с ограничением на значения столбца,
допускающим для этих данных только два значения, м
или F (и, возможно, NULL, если пол служащего неиз-
вестен). Вы могли бы использовать этот тип данных в
определениях таблиц. Преимущество пользователь-
ских типов данных состоит в том, что такие ограниче-
ния могут быть определены только один раз (в опреде-
лении типа данных), а потом они будут автоматически
применяться каждый раз, когда будет использован
пользовательский тип данных. Посмотрите в доку-
ментации своей СУБД, поддерживает ли она пользо-
вательские типы данных.
Расширенные возможности SQL 227

Что такое индексы


Индексы используются для логической сортировки дан-
ных с целью повышения скорости поиска и выполнения в
последующем операций сортировки. Лучший способ понять,
что такое индексы — взглянуть на предметный указатель
(по-английски — "index") в конце этой книги.
Предположим, что вы хотите найти вхождения слова
индекс в книге. Простейшим способом выполнения этой за-
дачи было бы вернуться на ее первую страницу и затем
просмотреть каждую строку каждой страницы в поисках
соответствий. Хотя такой способ и применим, это, очевид-
но, неработоспособное решение. Просмотреть несколько
страниц текста еще можно, но просматривать подобным об-
разом всю книгу — плохая затея. Чем больше объем тек-
ста, в котором нужно провести поиск, тем больше времени
требуется на выявление мест вхождения нужных данных.
Именно поэтому книги снабжают предметными указате-
лями. Предметный указатель — это список слов, располо-
женных в алфавитном порядке, со ссылками на страницы,
на которых искомые слова упоминаются в книге. Чтобы
найти термин индекс, в предметном указателе следует оп-
ределить, на каких страницах он встречается.
Что делает предметный указатель эффективным средст-
вом поиска? Попросту говоря, тот факт, что он правильно
отсортирован. Трудность поиска слов в книге обусловлена
не тем, что ее объем может быть слишком велик, скорее
это обусловлено тем, что ее содержимое не отсортировано в
алфавитном порядке. Если бы оно было отсортировано по-
добно тому, как это делается в словарях, в предметном ука-
зателе не было бы необходимости (именно поэтому словари
не снабжаются предметными указателями).
Индексы баз данных работают весьма похожим образом.
Данные первичного ключа всегда отсортированы — СУБД
делает это для вас. Выборка указанных строк по первично-
му ключу, таким образом, всегда гарантирует быстроту и
эффективность этой операции.
Поиск значений в других столбцах, однако, выполняется
уже не столь эффективно. Что произойдет, например, если
вы захотите сделать выборку всех клиентов, проживающих
в определенном штате? Поскольку таблица не отсортирова-
на по названиям штатов, СУБД придется читать каждую
228 Урок 2 2

строку таблицы (начиная с самой первой), отыскивая соот-


ветствия, точно так же как это сделали бы вы в поисках вхо-
ждений слов в книге, не имеющей предметного указателя.
Решение этой проблемы состоит в использовании индек-
са. Вы можете определить в качестве индекса один или не-
сколько столбцов так, чтобы СУБД хранила отсортирован-
ный список содержимого удобным для вас образом. После
того как индекс определен, СУБД использует его точно так
же, как вы используете предметный указатель книги. Она
производит поиск в отсортированном индексе, чтобы найти
местоположения всех соответствий и затем выбрать эти
строки.
Однако прежде чем создавать множество индексов, при-
мите во внимание следующее.
• Индексы повышают производительность операций
выборки, но ухудшают производительность при вы-
полнении таких операций, как добавление данных,
их модификация и удаление. Вызвано это тем, что
при выполнении подобных операций СУБД должна
еще и динамически обновлять индекс.
• Для хранения данных индекса требуется много места
на жестком диске.
• Не все данные подходят для индексации. Данные,
которые не являются по своей сути уникальными
(как, например, названия штатов в столбце
cust_state), не дадут такого выигрыша от индекса-
ции, как данные, которые имеют больше возможных
значений (как, например, имя и фамилия).
• Индексы используются для фильтрации и сортировки
данных. Если вы часто сортируете данные определен-
ным образом, эти данные могут быть кандидатом на
индексацию.
• В качестве индекса можно определить несколько
столбцов (например, с названием штата и названием
города). Такой индекс можно использовать, только ес-
ли данные будут отсортированы в порядке "штат плюс
город". (Если вы захотите отсортировать данные по на-
званию города, такой индекс использован не будет).
Не существует твердых правил относительно того, что и
когда следует индексировать. В большинстве СУБД предла-
гаются утилиты, которые можно использовать для опреде-
Расширенные возможности SQL 2 2 9

ления эффективности индексов, ими следует регулярно


пользоваться.
Индексы создаются с помощью оператора CREATE INDEX
(синтаксис которого весьма различен для разных СУБД). По-
средством следующего оператора создается простой индекс
для столбца с наименованием продукта таблицы Products:
ВВОД
CREATE INDEX prod_name_ind
ON PRODUCTS (prod_name);

Анализ
Каждый индекс должен иметь уникальное имя. В данном
случае оно определено как prod_name_ind после ключевых
слов CREATE INDEX. Ключевое слово ON используется для
указания таблицы, которая должна быть проиндексирована,
столбцы, включаемые в индекс (в нашем примере он один),
указываются в круглых скобках после имени таблицы.
Пересмотр индексов
Эффективность индексов снижается, если в таблицу
добавляются данные или происходит их обновление.
Многие администраторы баз данных считают так: то,
что когда-то было идеальным набором индексов, мо-
жет перестать быть таковым после нескольких меся-
цев манипуляции с данными. Целесообразно регу-
лярно пересматривать индексы и при необходимости
осуществлять их точную настройку;

Что такое триггеры


Триггеры — это особые хранимые процедуры, автомати-
чески выполняемые при использовании базы данных опре-
деленным образом. С любой операцией, вызывающей изме-
нение содержимого таблицы, можно связать сопутствующее
действие (триггер), которое СУБД должна выполнять при
выполнении каждой такой операции. Триггеры могут быть
связаны с выполнением операций INSERT, UPDATE и DELETE
(или какой-то их комбинацией) по отношению к указанным
таблицам.
230 Урок 2 2

Поддержка в MySQL
Когда эта книга готовилась к печати, СУБД MySQL
еще не поддерживала триггеры (их поддержку плани-
ровалось ввести в версии MySQL 5.1).

В отличие от хранимых процедур (которые представля-


ют собой просто хранимые операторы SQL) триггеры привя-
заны к отдельным таблицам. Триггер, ассоциирующийся с
операциями INSERT по отношению к таблице O r d e r s , будет
выполняться только в том случае, если строка добавляется
в таблицу O r d e r s . Аналогично, триггер, относящийся к
операциям INSERT и UPDATE для таблицы Customers, будет
выполняться только в случае выполнения названных опе-
раций по отношению к указанной таблице.
Будучи примененным в триггере, ваш код может иметь
доступ к следующим данным:
• ко всем новым данным в операциях INSERT;
• ко всем новым и старым данным в операциях
UPDATE;
• к удаляемым данным в операциях DELETE.
В зависимости от СУБД, которую вы используете, триг-
гер может выполняться до или после связанной с ним опе-
рации.
Чаще всего триггеры используются:
• для обеспечения непротиворечивости данных (напри-
мер, для преобразования всех названий штатов в
верхний регистр во время выполнения операций
INSERT ИЛИ UPDATE);
• для выполнения действий по отношению к другим
таблицам, основанных на изменениях, которые были
сделаны в какой-то таблице (например, для внесения
записи в контрольный журнал с целью регистрации
каждого случая обновления или удаления строки);
• для выполнения дополнительной проверки и отмены
введения данных (например, чтобы удостовериться в
том, что разрешенная для клиента сумма кредита не
превышена, в противном случае операция блокируется);
• для подсчета значений вычисляемых полей или об-
новления меток даты/времени.
Расширенные возможности SQL 231

Как вы, наверное, уже догадываетесь, синтаксис созда-


ния триггеров весьма различен для разных СУБД. За под-
робностями обратитесь к документации своей СУБД.
В следующем примере создается триггер, преобразую-
щий значения столбца c u s t _ s t a t e в таблице Customers в
верхний регистр при выполнении любых операций INSERT
И UPDATE.
Вот версия для SQL Server:
ВВОД
CREATE TRIGGER customer_state
ON Customers
FOR INSERT, UPDATE
AS
UPDATE Customers
SET cust_state = Upper(cust_state)
WHERE Customers.cust_id = inserted.cust_id;
А вот версия для Oracle и PostgreSQL:
ВВОД
CREATE TRIGGER customer_state
AFTER INSERT OR UPDATE
FOR EACH ROW
BEGIN
UPDATE Customers
SET cust_state = Upper(cust_state)
WHERE Customers.cust_id = :OLD.cust_id
END;

Ограничения работают быстрее, чем триггеры


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

Безопасность баз данных


Нет ничего более ценного для организации, чем ее дан-
ные, поэтому они всегда должны быть защищены от кражи
или случайного просмотра. Конечно, данные должны быть
в то же время доступны для определенных пользователей,
поэтому большинство СУБД предоставляет в распоряжение
232 Урок 22

своих администраторов механизмы, посредством которых


они могут разрешить или ограничить доступ к данным.
В основе любой системы безопасности лежат авториза-
ция и аутентификация пользователей. Так называется про-
цесс, в ходе которого пользователь подтверждает, что он —
это именно он и что ему разрешено проводить операции,
которые он собирается выполнить. Некоторые СУБД ис-
пользуют для этого средства безопасности операционной
системы, другие ведут свои собственные списки пользовате-
лей и паролей, третьи интегрируются с внешними сервера-
ми службы каталогов.
Часто используются следующие механизмы обеспечения
безопасности:
• ограничение доступа к механизмам управления базой
данных (создание таблиц, изменение или уничтоже-
ние существующих таблиц и т.д.);
• ограничение доступа к отдельным базам данных или
таблицам;
• ограничение типа доступа (только для чтения, доступ
к отдельным столбцам и т.д.);
• организация доступа к таблицам только через пред-
ставления или хранимые процедуры;
• создание нескольких уровней безопасности, вследст-
вие чего обеспечивается различная степень доступа и
контроля на основе регистрационного имени пользо-
вателя;
• ограничение возможности управлять учетными запи-
сями пользователей.
Управление системой безопасности осуществляется по-
средством операторов SQL GRANT и REVOKE, хотя большин-
ство СУБД предлагает интерактивные утилиты админист-
рирования, в которых используются те же операторы GRANT
И REVOKE.

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

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


для обработки данных перед началом или сразу после за-
вершения определенных операций, а опции системы безо-
пасности можно использовать для управления доступом к
данным. Возможно, ваша СУБД обеспечивает в той или
иной форме эти возможности. Обратитесь к ее документа-
ции, чтобы больше узнать об этом.
Приложение А

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

Что такое демонстрационные


таблицы
Таблицы, используемые на протяжении всей книги, яв-
ляются частью системы записи заказов воображаемого ди-
стрибьютора игрушек. Эти таблицы служат для решения
нескольких задач:
• взаимодействие с поставщиками;
• работа с каталогами продуктов;
• работа со списками клиентов;
• ввод заказов клиентов.
Для выполнения всех этих задач требуется пять таблиц
(тесно связанных между собой и являющихся частью реля-
236 Приложение А

ционной базы данных). В следующих разделах описана ка-


ждая из таблиц.

Упрощенные образцы
Таблицы, используемые в книге, нельзя назвать пол-
ными. Реальная система регистрации заказов храни-
ла бы множество других данных, не включенных в
представленные таблицы (например, платежи и дан-
ные учета, сведения об отгрузке и многие другие).
Однако с помощью этих таблиц будет наглядно пока-
зано, как организовываются данные и отношения ме-
жду таблицами в реальных условиях. Вы сможете
применить эти методы и технологии по'отношению к
вашим собственным базам данных.

Описания таблиц
Далее будут представлены каждая из пяти таблиц с ука-
занием имен столбцов каждой таблицы и их описаниями.
Таблица Vendors
В таблице Vendors хранятся данные о поставщиках,
продукты которых продаются. Для каждого поставщика в
этой таблице имеется запись, а столбец с идентификатором
поставщика (vend_id) используется для указания соответ-
ствия между продуктами и поставщиками.
Таблица. А.1. Столбцы таблицы columns
Столбец Описание
vend_id "Уникальный идентификатор (ID) поставщика
vend_name Имя поставщика
vend_address Адрес поставщика
vend_city Город поставщика
vend_state Штат поставщика
vend_ZIP ZIP-код поставщика
vend_country Страна поставщика
Сценарии демонстрационных таблиц 2 3 7

• Для всех таблиц должны быть определены первичные


ключи. Для данной таблицы в качестве первичного
ключа следует использовать ее столбец vend_id.

Таблица Products
Таблица Products содержит каталог продуктов, по од-
ному продукту в строке. Каждый продукт имеет уникаль-
ный идентификатор (в столбце prod_id) и связан с соответ-
ствующим поставщиком через vend_id (уникальный иден-
тификатор поставщика).
Таблица А.2. Столбцы таблицы Products
Столбец Описание
prod_id Уникальный идентификатор (ID) продукта
vend_id Идентификатор поставщика продукта (соответст-
вует столбцу vend_id таблицы Vendors)
prod_name Название продукта
prod_price Цена продукта
prod_desc Описание продукта

• Для всех таблиц нужно определить первичные клю-


чи. Для этой таблицы в качестве первичного ключа
следует использовать столбец prod_id.
• Для обеспечения целостности ссылочных данных сле-
дует определить внешний ключ на основе столбца
vend_id, связав его с vend_id в таблице Vendors.

Таблица Customers
В таблице Customers хранится информация обо всех
клиентах. Каждый из них имеет уникальный идентифика-
тор (столбец cust_id).
Таблица А.З. Столбцы таблицы Customers
Столбец Описание
cust_id Уникальный идентификатор клиента
cust_name Имя клиента
cust_address Адрес клиента
cust_city Город клиента
238 Приложение А

Окончание табл. А.З

Столбец Описание
cust_state Штат клиента
cust_ZIP ZIP-код клиента
cust_country Страна клиента
cust_contact Контактное имя клиента
cust_email Контактный адрес электронной почты клиента

• Для всех таблиц следует определить первичные клю-


чи. Для этой таблицы в качестве первичного ключа
следует использовать столбец cust_id.

Таблица Orders
В таблице Orders хранится информация о заказах кли-
ентов (без подробностей). Каждый заказ пронумерован с со-
блюдением правила уникальности (столбец order_num). За-
казы связаны с соответствующими клиентами через столбец
cust_id (который связан с уникальным идентификатором
клиента в таблице Customers).
Таблица А.4. Столбцы таблицы Orders
Столбец Описание
order_num Уникальный номер заказа
order_date Дата заказа
cust_id Идентификатор клиента, сделавшего заказ (свя-
зан со столбцом cust_id таблицы Customers)

• Для всех таблиц следует определить первичные клю-


чи. Для этой таблицы в качестве первичного ключа
следует использовать столбец order_nura.
• Для обеспечения целостности ссылочных данных сле-
дует определить внешний ключ на основе столбца
cust_id, связав его с cust_id в таблице Customers.

Таблица Orderltems
В таблице Orderltems хранятся предметы каждого за-
каза, для каждого предмета каждого заказа выделено по
одной строке. Каждой строке таблицы Orders соответствует
Сценарии демонстрационных таблиц 2 3 9

одна или несколько строк в таблице Orderltems. Каждый


предмет заказа идентифицирован уникальным образом по-
средством номера заказа в совокупности с предметом заказа
(первый предмет заказа, второй предмет заказа и т.д.).
Предмет заказа связан с соответствующими ему заказа-
ми через столбец order_num (который соотносит его с уни-
кальным идентификатором заказа в таблице Orders). Кро-
ме того, каждая запись о предмете заказа содержит иден-
тификатор продукта (который опять связывает предмет с
таблицей Products).
Таблица А.5. Столбцы таблицы Orderltems
Столбец Описание
order_num Номер заказа (связан со столбцом order_num в
таблице Orders)
order_item Номер предмета заказа (последовательно присваи-
ваемый внутри заказа)
prod_id Идентификатор продукта (связан со столбцом
prod_id в таблице Products)
quantity Количество предметов
item_price Цена предмета

• Для всех таблиц следует определить первичные ключи.


В качестве первичных ключей для этой таблицы сле-
дует использовать столбцы order_num и order_item.
• Для обеспечения целостности ссылочных данных сле-
дует определить внешние ключи на основе столбца
order_num, связав его с order_num в таблице Orders,
и prod_id, связав его с prod_id таблицы Products.

Получение демонстрационных
таблиц
Чтобы попрактиковаться в выполнении представленных
в книге примеров, вам нужен будет набор заполненных
таблиц. Все, что вам необходимо получить и испытать,
можно найти на Web-странице этой книги по адресу
http://www.forta.com/books/0672325675/.
240 Приложение А

Загрузка готового к работе MDB-файла


для Microsoft Access
Вы можете загрузить полностью готовый MDB-файл для
Microsoft Access с вышеуказанной страницы. Если вы вос-
пользуетесь этим файлом, вам не придется выполнять ка-
кие-либо сценарии создания и заполнения.
MDB-файл Access можно использовать с любыми кли-
ентскими утилитами ODBC, а также с интерпретаторами
языков сценариев, таких как ASP и ColdFusion.

Загрузка SQL-сценариев СУБД


Большинство СУБД хранят данные в форматах, которые не
позволяют распространять файлы баз данных (в отличие от
Access). Для таких СУБД вы можете загрузить SQL-сценарии
со страницы http://www.forta.com/books/0672325675/.
Для каждой СУБД имеется два файла.
• Файл c r e a t e . t x t , содержащий SQL-операторы, не-
обходимые для создания пяти таблиц базы данных
(включая определения всех первичных ключей и ог-
раничений внешних ключей).
• Файл p o p u l a t e . t x t , содержащий SQL-операторы
INSERT, используемые для заполнения этих таблиц.
Операторы SQL, содержащиеся в этих файлах, весьма
различны для разных СУБД, поэтому следует убедиться,
что вы выполняете именно тот, который соответствует ва-
шей СУБД. Эти сценарии предназначены для удобства чте-
ния книги, и никакая ответственность за возможные про-
блемы при их использовании не предполагается.
К тому времени, когда эта книга уходила в печать, были
доступны сценарии для следующих СУБД:
• IBM DB2;
• Microsoft SQL Server;
• MySQL;
• Oracle;
• PostgreSQL;
• Sybase Adaptive Server.
Сценарии демонстрационных таблиц 241

При необходимости этот список может быть пополнен


другими СУБД.
В приложении Б, "Работа с популярными приложения-
ми", приведены инструкции по выполнению сценариев для
нескольких популярных сред программирования.
Вначале создать, потом заполнять
Следует вначале выполнять сценарии создания таб-
лиц, а потом уже их заполнения. Убедитесь в том, что
никаких сообщений об ошибках эти сценарии не воз-
вратили. Если сценарии создания потерпят неудачу,
нужно вначале выявить и устранить возникшую про-
блему, а потом уже заполнять таблицы.
Приложение Б

Работа с популярными
приложениями
Как говорилось в уроке 1, "Что такое SQL," SQL — это
не приложение, но язык. Для того чтобы выполнить при-
меры этой книги, вам необходимо приложение, поддержи-
вающее выполнение SQL-операторов.
В приложении Б описываются шаги по выполнению
операторов SQL в некоторых наиболее часто используемых
приложениях.
Вы можете использовать любое приложение из числа
указанных ниже, а также многие другие для проверки SQL-
кода и экспериментирования с ним. Итак, какое же при-
ложение использовать?
• Многие СУБД поставляются со своими собственными
клиентскими утилитами, с ними вполне можно начи-
нать работу. Однако для них не характерен интуи-
тивно понятный пользовательский интерфейс.
• Пользователи Windows, возможно, установили на
своем компьютере утилиту Microsoft Query. Эта про-
стая утилита очень хороша для проверки простых
операторов.
• Прекрасная альтернатива для пользователей Windows —
Query Tool Джорджа Пулоса (George Poulose). Ссылку
можно найти на Web-странице книги по адресу
http://www.forta.com/books/0672325667/.
• Aqua Data Studio — чрезвычайно полезная бесплат-
ная Java-утилита, которая работает под управлением
Windows, Linux, Unix, Mac OSX и других операцион-
ных систем. Ссылку на эту утилиту можно найти на
Web-странице книги по адресу h t t p : //www. f o r t a .
com/books/0672325667/.
Любая из названных утилит будет хорошим выбором. За
дополнительными рекомендациями обратитесь к Web-стра-
нице этой книги.
244 Приложение Б

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


Studio
Aqua Data Studio — это бесплатный SQL-клиент, основан-
ный на технологии Java. Он выполняется на всех главных
платформах и поддерживает все наиболее распространенные
СУБД (а также ODBC1). Чтобы выполнить какой-нибудь SQL-
оператор в Aqua Data Studio, сделайте следующее.
1. Запустите Aqua Data Studio.
2. Прежде чем СУБД можно будет использовать, ее не-
обходимо зарегистрировать. Выберите в меню Select
пункт Register Server.
3. Выберите СУБД, которую вы используете, в отобра-
женном на экране списке (выберите Generic ODBC для
использования Microsoft Access или произвольную
базу данных ODBC — для этого требуется, чтобы был
определен источник данных ODBC, о чем будет сказа-
но в конце данного приложения). На основании вы-
бранной СУБД вам будет предложен путь к файлу
или информация относительно регистрации. Запол-
ните форму и щелкните на кнопке ОК. После завер-
шения регистрации этот сервер будет появляться в
списке слева.
4. Выберите сервер в списке зарегистрированных серве-
ров.
5. Запустите Query Analyzer, выбрав команду Query
Analyzer в меню Server или нажав <Ctrl+Q>.
6. Введите свой SQL-код в окне запроса (верхнее окно).
7. Чтобы выполнить SQL-код, выберите команду Execute
в меню Query, или нажмите <Ctrl+E>, или щелкните
на кнопке Execute (кнопке с зеленой стрелкой).
8. Результаты появятся в нижнем окне.

1
ODBC (сокр. от Open DataBase Connectivity) — открытый интер-
фейс доступа к базам данных, встроенный в Windows и Windows NT,
определяет набор функций, которые можно использовать для доступа
к любой реляционной СУБД. — Прим. ред.
Работа с популярными приложениями 245

Использование DB2
СУБД DB2 компании IBM — это мощная высокопроиз-
водительная многоплатформенная СУБД. Она поставляется
с целым набором клиентских инструментов, которые могут
быть использованы для выполнения операторов SQL.
Приведенные ниже инструкции предназначены для Java-
утилиты Command Center — одной из самых простых и
наиболее универсальной среди всех приложений.
1. Запустите Command Center.
2. Выберите вкладку Script.
3. Введите оператор SQL в поле Script.
4. Выберите команду Execute в меню Script или щелкни-
те на кнопке Execute, чтобы выполнить этот сцена-
рий.
5. Результирующие данные в необработанном виде будут
отображены в нижнем окне. Перейдите на вкладку
Results, чтобы отобразить результаты в виде таблицы.
6. Command Center предлагает также интерактивный фор-
мирователь SQL-операторов, называемый SQL Assist.
Его можно запустить из вкладки Interactive.

Использование Macromedia
ColdFusion
ColdFusion компании Macromedia представляет собой
платформу для разработки Web-приложений.
ColdFusion использует для создания сценариев язык, ос-
нованный на дескрипторах (тегах). Чтобы протестировать
ваш SQL-код, создайте простую страницу, которую вы смо-
жете отобразить, вызвав ее посредством своего Web-брау-
зера. Выполните следующие шаги:
1. Прежде чем вы сможете обращаться к каким-либо ба-
зам данных из ColdFusion, должен быть определен ис-
точник данных (Data Source). Программа ColdFusion
Administrator обеспечивает Web-интерфейс для опре-
деления источников данных (обратитесь за помощью к
документации ColdFusion, если это необходимо).
246 Приложение Б

2. Создайте новую страницу ColdFusion (с расширением


CFM).
3. Используйте дескрипторы CFML <CFQUERY> и
</CFQUERY> для создания блока запроса. Назовите
его, используя атрибут NAME, и определите источник
данных в атрибуте DATASOURCE.
4. Введите свой SQL-оператор между дескрипторами
<CFQUERY> и </CFQUERY>.
5. Используйте цикл <CFDUMP> или <CFOUTPUT> для
отображения результатов запроса.
6. Сохраните страницу в каком-нибудь каталоге испол-
няемых файлов корневого каталога Web-сервера.
7. Отобразите страницу, вызвав ее из Web-браузера.

Использование Microsoft
Access
Microsoft Access обычно используется интерактивно для
создания баз данных, управления, манипулирования и
взаимодействия с данными, a Access предлагает еще и кон-
структор запросов (Query Designer), который можно ис-
пользовать для интерактивного построения операторов SQL.
Зачастую остающаяся невыявленной возможность конст-
руктора запросов состоит в том, что он также позволяет
вводить SQL-код для немедленного выполнения. Благодаря
этому Access можно использовать для передачи операторов
SQL любому источнику данных ODBC, хотя больше всего
эта программа подходит для выполнения SQL-кода в уже
открытой базе данных. Для того чтобы использовать на-
званную возможность, сделайте следующее.
1. Запустите Microsoft Access. Вам предложат открыть
(или создать) базу данных. Откройте базу данных,
которую вы собираетесь использовать.
2. Выберите меню Запросы в окне с названием вашей
базы данных, а затем дважды щелкните на ссылке
Создание запроса в режиме конструктора (либо щелк-
ните на кнопке Создать и выберите в появившемся
окне пункт Конструктор).
Работа с популярными приложениями 2 4 7

3. Появится диалоговое окно Добавление таблицы. За-


кройте его, не выбрав ни одну из таблиц.
4. Выберите команду Режим SQL в меню Вид.
5. Введите ваш оператор SQL в окне запроса.
6. Чтобы выполнить оператор SQL, щелкните на кнопке
Запуск (она помечена восклицательным знаком). Ре-
зультаты будут отображены в этом же окне, но в ре-
жиме таблицы.
7. Переходите при необходимости от режима ввода за-
просов (вам нужно будет повторно выполнить коман-
ду Режим SQL для изменения вашего SQL-кода) к ре-
жиму отображения их результатов. Вы можете также
использовать режим Создание запроса с помощью
мастера для интерактивного построения операторов
SQL.
Microsoft Access также поддерживает режим запроса к
серверу, который позволяет использовать Access для от-
правки SQL-операторов любому источнику данных ODBC.
Эту возможность следует использовать для взаимодействия
с внешними базами данных, и никогда — для непосредст-
венного взаимодействия с Access. Чтобы воспользоваться
этой возможностью, выполните следующее.
1. Microsoft Access для взаимодействия с базами данных
использует ODBC, так что в системе должен присут-
ствовать источник данных ODBC. Только в этом слу-
чае можно будет начать обработку запросов (см. пре-
дыдущие инструкции).
2. Запустите Microsoft Access. Вам предложат открыть
(или создать) базу данных. Откройте какую-нибудь
базу данных.
3. Выберите меню Запросы в окне с названием вашей
базы данных, а затем дважды щелкните на ссылке
Создание запроса в режиме конструктора (либо щелк-
ните на кнопке Создать и выберите в появившемся
окне пункт Конструктор).
4. Появится диалоговое окно Добавление таблицы. За-
кройте его, не выбрав ни одну из таблиц.
5. В меню Запрос выберите подменю Запрос SQL, а за-
тем — команду К серверу.
248 Приложение Б

6. В меню Вид выберите команду Свойства, чтобы ото-


бразить диалоговое окно Свойства запроса.
7. Щелкните в поле Строка подключения ODBC, а за-
тем — на кнопке с многоточием (...), чтобы отобра-
зить диалоговое окно Выбор источника данных, кото-
рое вы будете использовать для выбора источника
данных ODBC.
8. Выберите ваш источник данных и щелкните на кноп-
ке ОК, чтобы вернуться в диалоговое окно Свойства
запроса.
9. Щелкните в поле списка Возврат записей. Если вы
выполняете оператор SELECT (или другой оператор,
возвращающий результаты), выберите Да. Если же
вы выполняете оператор SQL, который не возвращает
данные (например, INSERT, UPDATE или DELETE), вы-
берите Нет.
10. Введите свой оператор SQL в окне запроса к серверу.
11. Чтобы выполнить этот оператор SQL, щелкните на
кнопке Запуск (на ней изображен восклицательный
знак красного цвета).

Использование режима запроса к серверу


Режим запроса к серверу лучше работает при под-
ключении к СУБД, отличной от Access. Если устанав-
ливается связь с MDB-файлом Access, лучше исполь-
зовать какие-то другие клиентские средства, о кото-
рых говорилось выше.

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


Microsoft ASP — это платформа подготовки сценариев,
ориентированная на создание Web-приложений.
Для того чтобы протестировать ваши операторы SQL на
странице ASP, вам вначале придется создать страницу, ко-
торую вы сможете отобразить на экране, вызвав ее с помо-
щью своего Web-браузера. Ниже перечислены шаги, кото-
рые необходимо сделать для выполнения оператора SQL на
странице ASP.
Работа с популярными приложениями 2 4 9

1. ASP для взаимодействия с базами данных использует


ODBC, поэтому прежде чем начать работу, вам следу-
ет побеспокоиться об источнике данных ODBC, до-
полнительную информацию можно найти в конце
этого приложения.
2. Создайте новую страницу ASP (с расширением ASP),
используя любой текстовый редактор.
3. Используйте метод Server.CreateObject для созда-
ния экземпляра объекта ADODB. Connection.
4. Используйте метод Open для открытия нужного ис-
точника данных ODBC.
5. Передайте ваш оператор SQL методу Execute в каче-
стве аргумента. Метод возвратит результирующее
множество. Используйте команду Set для сохранения
полученных данных.
6. Чтобы отобразить эти результаты, воспользуйтесь
циклом <% Do While NOT EOF %>.
7. Сохраните эту страницу в любом каталоге исполняе-
мых файлов корневого каталога Web-сервера.
8. Откройте страницу, вызвав ее посредством Web-
браузера.

Использование Microsoft
ASP.NET
Microsoft ASP.NET — это платформа подготовки сцена-
риев для создания Web-приложений с использованием тех-
нологии .NET. Чтобы протестировать операторы SQL на
странице ASP.NET, создайте страницу, которую можно ото-
бразить, вызвав ее посредством браузера. Это можно сде-
лать разными способами, ниже описан один из них.
1. Создайте новый файл с расширением . aspx.
2. Создайте подключение к базе данных, используя
функцию SqlConnectionO или OleDbConnectionO .
3. Используйте функцию SqlCommand () или
OleDbCommand () для передачи оператора в СУБД.
250 Приложение Б

4. Создайте объект DataReader, используя метод


ExecuteReader.
5. Последовательно обработайте все записи, содержа-
щиеся в объекте, для получения возвращаемых зна-
чений.
6. Сохраните эту страницу в любом каталоге исполняе-
мых файлов корневого каталога Web-сервера.
7. Откройте страницу, вызвав ее посредством Web-
браузера.

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


Microsoft Query — это стандартный инструмент подго-
товки SQL-запросов, он является идеальной утилитой для
тестирования операторов SQL с использованием источников
данных ODBC. Утилита Microsoft Query опционально уста-
навливается вместе с другими программами Microsoft, a
также с программами других фирм.
Получение MS-Query
MS-Query часто устанавливается на компьютер вме-
сте с другими программами Microsoft (например,
Office), хотя это происходит только при полной уста-
новке пакета. Если она не присутствует в меню Пуск,
воспользуйтесь командой Пуск^Найти^Файлы и пап-
ки, чтобы найти эту утилиту в своей системе.
(Утилита часто присутствует в системе, однако вы об
этом можете не знать.) Файл, который нужно искать,
называется MSQRY32.EXE или MSQUERY.EXE.

Для использования Microsoft Query необходимо выпол-


нить следующее.
1. Microsoft Query использует ODBC для взаимодействия
с базами данных, поэтому прежде чем вы начнете ра-
боту, на компьютере должен быть создан источник
данных ODBC (дополнительную информацию можно
найти в конце данного приложения).
2. Прежде чем вы сможете использовать утилиту
Microsoft Query, она должна быть установлена на ва-
Работа с популярными приложениями 251

шем компьютере. Просмотрите список программ ва-


шего компьютера, открывающийся после щелчка на
кнопке Пуск, и найдите утилиту.
3. В меню Файл утилиты выберите команду Выполнить
запрос SQL. Откроется окно Выполнение запроса SQL.
4. Щелкните на кнопке Источники, чтобы выбрать ис-
точник данных ODBC. Если нужный вам источник от-
сутствует в списке, щелкните на кнопке Обзор, чтобы
найти его. После того как будет выбран нужный ис-
точник данных, щелкните на кнопке ОК.
5. Введите ваш оператор SQL в поле Инструкция SQL.
6. Щелкните на кнопке Выполнить, чтобы выполнить
оператор SQL и отобразить полученные данные.

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


Server
Microsoft SQL Server предлагает основанный на Windows
инструментарий анализа запросов, называемый SQL Query
Analyzer. Хотя это средство создания запросов в основном
предназначено для анализа процесса выполнения операто-
ров SQL и их оптимизации, оно идеально подходит для тес-
тирования SQL-операторов и экспериментирования с ними.
Ниже даны пошаговые инструкции по использованию
SQL Query Analyzer.
1. Запустите приложение SQL Query Analyzer (его мож-
но найти в группе программ Microsoft SQL Server).
2. Вам будет представлена информация о сервере и
предложено зарегистрироваться. Зарегистрируйтесь в
программе SQL Server (запустив сервер, если это еще
не сделано).
3. После того как отобразится экран запросов, выберите
базу данных в раскрывающемся списке.
4. Введите свой SQL-код в большом текстовом окне и
затем щелкните на кнопке Execute Query (с зеленой
стрелкой), чтобы выполнить его. (Вы можете также
нажать клавишу <F5> или выбрать команду Execute в
меню Query.)
252 Приложение Б

5. Результаты будут отображены на отдельной панели


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

Использование MySQL
СУБД MySQL поставляется вместе с утилитой командной
строки, называемой mysql. Это сугубо текстовое средство
создания запросов, которое можно использовать для вы-
полнения любых операторов SQL. Чтобы воспользоваться
утилитой mysql, выполните следующее.
1. Введите mysql, чтобы запустить эту утилиту. В зави-
симости от ограничений, налагаемых системой безо-
пасности, вам может понадобиться использовать па-
раметры -и и -р, чтобы ввести регистрационную ин-
формацию.
2. В ответ на приглашение mysql > введите USE ба-
за_данных, указывая тем самым имя базы данных,
которая будет использоваться.
3. Введите ваш SQL-код после приглашения mysql >,
проверив, чтобы каждый оператор заканчивался точ-
кой с запятой (;). Результаты будут отображены на
экране.
4. Введите \h для получения списка команд, которые
вы можете использовать, и \s для получения инфор-
мации о статусе (включая информацию о версии
MySQL).
5. Введите \q для выхода из утилиты mysql.

Использование Oracle
СУБД Oracle поставляется с основанным на Java-
технологии средством управления, которое называется
Enterprise Manager. На самом деле это набор инструментов,
один из которых называется SQL*Plus Worksheet. Ниже
рассказано, как им нужно пользоваться.
Работа с популярными приложениями 253

1. Запустите SQL*Plus Worksheet (или напрямую, или


из Oracle Enterprise Manager).
2. Вам предложат ввести регистрационные данные. Вве-
дите имя пользователя и пароль, чтобы подключить-
ся к серверу базы данных.
3. Экран SQL Worksheet разделен на две панели. Введи-
те ваш SQL-код в верхней.
4. Чтобы выполнить оператор SQL, щелкните на кнопке
Execute (на ней изображена молния). Результаты бу-
дут отображены в нижней панели.

Использование РНР
РНР — это популярный язык написания Web-сценариев.
РНР предлагает функции и библиотеки, используемые для
подключения к различным базам данных, а поэтому код,
используемый для выполнения операторов SQL, может ме-
няться в зависимости от того, какая СУБД используется
(и как к ней осуществляется доступ). А раз так, то невоз-
можно предложить пошаговые инструкции, которые годи-
лись бы для любой ситуации. Обратитесь к документации
РНР за инструкциями по подключению именно к вашей
СУБД.

Использование PostgreSQL
PostgreSQL поставляется с утилитой командной строки,
которая называется psql. Это — сугубо текстовое средство
создания запросов, которое можно использовать для вы-
полнения любых операторов SQL. Для того чтобы восполь-
зоваться утилитой psql, выполните следующее.
1. Введите psql, чтобы запустить утилиту. Чтобы загру-
зить конкретную базу данных, укажите ее в команд-
ной строке как psql база_данных (PostgreSQL не
поддерживает команду USE).
2. Введите ваш SQL-код в ответ на приглашение =>,
убедившись в том, что каждый оператор заканчивает-
ся точкой с запятой (;). Результаты будут отображе-
ны на экране.
254 Приложение Б

3. Введите \?, чтобы отобразить список команд, кото-


рые вы можете использовать.
4. Введите \h, чтобы получить справку по SQL, \h —
чтобы получить справку относительно конкретного
оператора SQL (например, \h SELECT).
5. Введите \q, чтобы выйти из утилиты psql.

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


Query Tool — это стандартный инструмент запросов,
созданный Джорджем Пулосом (George Poulose). Этот инст-
румент является идеальной утилитой для тестирования
операторов SQL при использовании источников данных
ODBC. (Существует также версия для ADO2.)

Получение Query Tool

Утилита Query Tool может быть загружена через


Internet. Чтобы получить ее копию, перейдите на Web-
страницу книги по ссылке: h t t p : / / w w w . f o r t a . c o m /
books/0672321289/.

Чтобы воспользоваться утилитой Query Tool, выполните


следующее:
1. Query Tool использует ODBC для взаимодействия с
базами данных, поэтому источник данных ODBC
должен уже иметься на компьютере, прежде чем вы
начнете работу (см. инструкции, которые были даны
выше).
2. Прежде чем вы начнете использовать Query Tool, эта
утилита должна быть установлена на вашем компью-
тере. Просмотрите список установленных на нем про-
грамм и найдите ее.
3. В появившемся диалоговом окне вам предложат вы-
брать источник данных ODBC, который будет исполь-
зоваться. Если нужный вам источник данных в спи-

2
ADO (сокр. от ActiveX Data Objects) — технология доступа к
данным, включающая набор высокоуровневых интерфейсов, которые
позволяют разработчикам обращаться к данным на любом языке про-
граммирования. — Прим. ред.
Работа с популярными приложениями 255

ске не представлен, щелкните на кнопке New, чтобы


создать его. После того как будет правильно выбран
источник данных, щелкните на кнопке ОК.
4. Введите ваш оператор SQL в правом верхнем окне.
5. Щелкните на кнопке Execute (на ней изображена го-
лубая стрелка), чтобы выполнить оператор SQL и
отобразить возвращаемые данные в нижней панели.
(Вы можете также нажать клавишу <F5> или выбрать
команду Execute в меню Query.)

Использование Sybase
Sybase Adaptive Server поставляется с Java-утилитой
SQL Advantage. Данная утилита очень похожа на Query
Analyzer, поставляемую вместе с СУБД Microsoft SQL
Server (эти продукты имеют общее прошлое). Для того что-
бы воспользоваться SQL Advantage, выполните следующее:
1. Вызовите приложение SQL Advantage.
2. Получив предложение зарегистрироваться, введите
свое регистрационное имя и пароль.
3. После того как появится окно для ввода запроса, вы-
берите базу данных в раскрывающемся списке.
4. Введите в появившемся окне ваш SQL-код.
5. Чтобы выполнить запрос, щелкните на кнопке
Execute, выберите команду Execute Query в меню
Query или нажмите <Ctrl+E>.
6. Результаты (если они есть) будут отображены в новом
окне.

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

ODBC — это стандарт, который используется для обес-


печения того, чтобы клиентские приложения могли взаи-
модействовать с различными компьютерами, на которых
размещены базы данных, или процессорами баз данных.
При использовании ODBC можно написать код с помощью
одного клиента, и он будет взаимодействовать почти с лю-
бой базой данных или СУБД.
ODBC сам по себе не является базой данных. Скорее
ODBC представляет собой оболочку для баз данных, позво-
ляющую всем базам данных вести себя непротиворечивым и
четко выраженным образом. Он добивается этого за счет
использования программных драйверов, выполняющих две
основные функции. Во-первых, они инкапсулируют некото-
рые характерные для отдельных баз данных особенности и
скрывают их от клиента. Во-вторых, они обеспечивают об-
щий язык для взаимодействия с этими базами данных (при
необходимости выполняя нужное преобразование). Язык,
используемый ODBC, — это SQL.
Клиентские приложения ODBC не взаимодействуют с ба-
зами данных непосредственно. Вместо этого они взаимодей-
ствуют с источниками данных ODBC (ODBC Data Sources).
Источник данных ODBC представляет собой логическую ба-
зу данных, которая включает в свой состав драйвер (база
данных каждого типа имеет свой собственный драйвер) и
информацию о том, как нужно подключаться к этой базе
данных (пути к файлам, имена серверов и т.д.).
После того как источники данных ODBC определены,
ими может пользоваться любое ODBC-совместимое прило-
жение. Источники данных ODBC не специфичны для при-
ложений, они специфичны для систем.
Различия в реализации
Существует много версий системных модулей ODBC,
поэтому невозможно дать четкие инструкции, приме-
нимые ко всем версиям. Обращайте внимание на
приглашения, когда будете устанавливать свои ис-
точники данных.

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


ODBC-модуля панели управления Windows. Чтобы устано-
вить какой-либо источник данных ODBC, выполните сле-
дующее.
Работа с популярными приложениями 257

1. Откройте ODBC-модуль панели управления Windows.


2. Большинство источников данных ODBC должны быть
общесистемными (в противоположность источникам
данных, специфичным для пользователя), поэтому
выберите вкладку Системный DSN, если она доступна
для вас.
3. Щелкните на кнопке Добавить, чтобы добавить новый
источник данных.
4. Выберите драйвер, который будет использоваться.
Обычно по умолчанию доступен набор драйверов,
обеспечивающих поддержку большинства продуктов
компании Microsoft. В вашей системе могут быть ус-
тановлены другие драйверы. Вы можете выбрать
драйвер, соответствующий типу базы данных, к кото-
рой вы собираетесь подключаться.
5. В зависимости от типа базы данных или СУБД вам
предложат ввести имя сервера или путь к файлу и,
возможно, регистрационную информацию. Введите
запрашиваемую информацию и следуйте остальным
инструкциям, чтобы создать источник данных.
Приложение В

Синтаксис операторов
SQL
Для того чтобы помочь вам быстро найти образец нуж-
ного синтаксиса, в этом приложении приводятся образцы
для наиболее часто выполняемых операций SQL. Каждый
оператор начинается с краткого описания, затем приводит-
ся соответствующий синтаксис.
Для большего удобства даются также ссылки на уроки,
в которых изучались соответствующие операторы.
При рассмотрении синтаксиса операторов помните сле-
дующее:
• Символ " | " служит для выбора одного из нескольких
вариантов, поэтому NULL | NOT NULL означает указа-
ние NULL ИЛИ NOT NULL.
• Ключевые слова или предложения, заключенные в
квадратные скобки, [например, так], являются оп-
циональными.
• Представленный ниже синтаксис подходит почти для
любой СУБД. Рекомендуем обращаться к документа-
ции вашей СУБД за подробностями относительно
возможных изменений в синтаксисе.

ALTER TABLE
Оператор ALTER TABLE используется для обновления
схемы существующей таблицы. Чтобы создать новую таб-
лицу, используйте оператор CREATE TABLE. За более де-
тальной информацией обратитесь к уроку 17, "Создание
таблиц и работа с ними".
ВВОД
ALTER TABLE имя таблицы
260 Приложение В

ADD|DROP имя_столбца тип_данных [NULL|NOT


^NULL] [CONSTRAINTS] ,
ADD|DROP имя_столбца тип_данных [NULL|NOT
^NULL] [CONSTRAINTS] ,

COMMIT
Оператор COMMIT используется для создания запросов к
базе данных в виде транзакций. За более детальной инфор-
мацией обратитесь к уроку 20, "Обработка транзакций".
ВВОД
COMMIT [TRANSACTION];

CREATE INDEX
Оператор CREATE INDEX используется для создания ин-
декса одного или нескольких столбцов. За более детальной
информацией обратитесь к уроку 22, "Расширенные воз-
можности SQL".
ВВОД
CREATE INDEX название_индекса
ON имя_таблицы (имя_столбца, . . . ) ;

CREATE PROCEDURE
Оператор CREATE PROCEDURE используется для создания
хранимых процедур. За более детальной информацией об-
ратитесь к уроку 19, "Работа с хранимыми процедурами".
В СУБД Oracle используется синтаксис, отличный от опи-
санного в этом уроке.
ВВОД
CREATE PROCEDURE имя_процедуры [параметры]
^t> [опции]
AS
SQL statement;
Синтаксис операторов SQL 261

CREATE TABLE
Оператор CREATE TABLE используется для создания но-
вых таблиц базы данных. Чтобы обновить схему уже суще-
ствующей таблицы, используйте оператор ALTER TABLE. За
более детальной информацией обратитесь к уроку 17.
ВВОД
CREATE TABLE имя_таблицы
(
имя_столбца тип_данных [NULL|NOT NULL]
"*> [CONSTRAINTS] ,
имя_столбца тип_данных[NULL|NOT NULL]
Ь [CONSTRAINTS] ,

CREATE VIEW
Оператор CREATE VIEW используется для создания ново-
го представления одной или нескольких таблиц. За более
детальной информацией обратитесь к уроку 18, "Использо-
вание представлений".
ВВОД
CREATE VIEW имя_представления AS
SELECT имена_столбцов, ...
FROM t a b l e s , . . .
[WHERE . . . ]
[GROUP BY . . . ]
[HAVING . . . ] ;

DELETE
Оператор DELETE удаляет одну или несколько строк таб-
лицы. За более детальной информацией обратитесь к уро-
ку 16, "Обновление и удаление данных".
ВВОД
DELETE FROM имя_таблицы
[WHERE .. .] ;
262 Приложение В

DROP
Оператор DROP навсегда удаляет объекты базы данных
(таблицы, представления, индексы и т.д.). За более деталь-
ной информацией обратитесь к урокам 17 и 18.
ВВОД
DROP INDEX|PROCEDURE|TABLE|VIEW
%имя__индекса \ имя_процедуры\ имя_таблицы\ имя_представления;

INSERT
Оператор INSERT добавляет в таблицу одну строку. За
более детальной информацией обратитесь к уроку 15, "До-
бавление данных".
ВВОД
INSERT INTO имя_таблицы [(имена_столбцов, ...)]
VALUES{значения, ...) ;

INSERT SELECT
Оператор INSERT SELECT добавляет результаты выпол-
нения оператора SELECT в таблицу. За более детальной ин-
формацией обратитесь к уроку 15.
ВВОД
INSERT INTO имя_таблицы [(имена_столбцов, ...)]
SELECT имена_столбцов, ... FROM имя_таблицы, ...
[WHERE . . . ] ;

ROLLBACK
Оператор ROLLBACK используется для аннулирования ре-
зультатов работы блока транзакции. За более детальной
информацией обратитесь к уроку 20.
ВВОД
ROLLBACK [ ТО точка_сохранения];
Синтаксис операторов SQL 263

или
ввод
ROLLBACK TRANSACTION;

SELECT
Оператор SELECT используется для выборки данных из
одной или нескольких таблиц (или представлений). За бо-
лее детальной информацией обратитесь к уроку 2, "Выбор-
ка данных"; уроку 3, "Сортировка выбранных данных"; и
уроку 4, "Фильтрация данных". (Во всех уроках со 2 по 14
рассматриваются аспекты применения оператора SELECT.)
ВВОД
SELECT имя_столбца,
FROM имя_таблицы, .
[WHERE . . . ]
[UNION . . . ]
[GROUP BY . . . ]
[HAVING . . . ]
[ORDER BY . . . ] ;

UPDATE
Оператор UPDATE обновляет одну или несколько строк
таблицы. За более детальной информацией обратитесь к
уроку 16.
ВВОД
UPDATE имя_таблицы
SET имя__столбца = значение,
[WHERE . . . ] ;
Приложение Г

Использование типов
данных SQL
Как уже говорилось в уроке 1, "Что такое SQL", типы
данных представляют собой основные правила, определяю-
щие, какие данные могут храниться в столбцах и в каком
виде эти данные в действительности хранятся.
Типы данных используются по нескольким причинам.
• Типы данных позволяют ограничить разновидности
данных, которые могут храниться в столбце. Напри-
мер, столбцы с данными числового типа будут при-
нимать только числовые данные.
• Типы данных позволяют более эффективно организо-
вывать хранение. Числовые значения и значения да-
ты/времени могут храниться в более компактном
формате, чем текстовые строки.
• Типы данных позволяют изменять порядок сортиров-
ки. Если все данные трактуются как строки, то 1
предшествует 10, а 10 предшествует 2.
• (Строки сортируются в лексикографической последо-
вательности, по одному символу за один раз, начиная
слева). Если выполняется числовая сортировка, то
числа будут располагаться по возрастанию.
При разработке таблиц обращайте пристальное внимание
на используемые в них типы данных. При использовании
неправильных типов данных работа вашего приложения
серьезно осложнится.
Изменение типов данных уже имеющихся и заполнен-
ных столбцов — задача нетривиальная. (Кроме того, при ее
выполнении возможна потеря данных.)
В одном приложении невозможно дать исчерпывающую
информацию по типам данных и методам их использова-
ния, однако здесь все же рассмотрены основные типы дан-
ных, рассказано, для чего они используются, а также рас-
крываются возможные проблемы совместимости.
266 Приложение Г

Не существует двух одинаковых СУБД


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

Строковые данные
Чаще всего используются данные типа строки, или стро-
ковые данные. К ним относятся хранимые в СУБД строки,
например, имена, адреса, номера телефонов и ZIP-коды.
Вам придется использовать строковые данные в основ-
ном двух типов — строки фиксированной длины и строки
переменной длины (табл. Г.1).
Строки фиксированной длины относятся к типу данных,
которые могут состоять из фиксированного числа символов,
это число определяется при создании таблиц.
Например, вы можете разрешить ввод 30 символов в
столбец, предназначенный для хранения имен, или 11 сим-
волов в столбец с номером карточки социального страхова-
ния. В столбцы для строк фиксированной длины нельзя
вводить больше символов, чем разрешено. Столбцы также
выделяют для хранения именно столько места, сколько
разрешено. Так, если имя Бен сохраняется в поле столбца
имен, рассчитанном на ввод 30 символов, будет сохранено
ровно 30 символов (при необходимости текст дополняется
пробелами или нулями).
В строках переменной длины можно хранить столько
символов, сколько необходимо (максимальное значение ог-
раничивается типом данных и СУБД). Некоторые типы
данных переменной длины имеют ограничение снизу (фик-
сированное значение минимальной длины). Другие ограни-
чений не имеют. В любом случае сохраняются только ука-
занные данные (и никаких дополнительных).
Если тип данных переменной длины обладает такой гиб-
костью, зачем вам использовать типы данных фиксирован-
Использование типов данных SQL 267

ной длины? Ответ прост: для повышения производительно-


сти. СУБД способна сортировать столбцы с данными фик-
сированной длины и манипулировать ими намного быстрее,
чем столбцами с данными переменной длины. Кроме того,
многие СУБД не способны индексировать столбцы с данны-
ми переменой длины (или переменную часть столбца). (За
подробностями относительно индексов вам следует обра-
титься к уроку 22, "Расширенные возможности SQL".)
Таблица Г. 1. Строковые данные
Тип данных Описание
CHAR С т р о к а ф и к с и р о в а н н о й д л и н ы , с о с т о я щ а я из
1-255 символов. Ее р а з м е р д о л ж е н быть оп-
ределен во в р е м я с о з д а н и я
NCHAR Особая ф о р м а т и п а д а н н ы х CHAR, разрабо-
т а н н а я с ц е л ь ю п о д д е р ж к и многобайтовых
символов и л и символов Unicode. ( Т о ч н а я
с п е ц и ф и к а ц и я з а в и с и т от р е а л и з а ц и и )
NVARCHAR С п е ц и а л ь н а я ф о р м а т и п а д а н н ы х TEXT, раз-
р а б о т а н н а я с ц е л ь ю п о д д е р ж к и многобайто-
в ы х символов и л и символов Unicode. (Точ-
н а я с п е ц и ф и к а ц и я зависит от р е а л и з а ц и и )
TEXT ( т а к ж е на- Т е к с т переменной д л и н ы
з ы в а е т с я LONG,
и л и MEMO, и л и
VARCHAR)

Использование кавычек
Независимо от формы используемых строковых дан-
ных значение строки должно быть всегда заключено в
одинарные кавычки.

Когда числовые значения не являются таковыми


Вы можете подумать, что номера телефонов и ZIP-
коды должны храниться в числовых полях (ведь они
содержат только числовые данные), но поступать так
нецелесообразно. Если вы сохраните ZIP-код 01234 в
числовом поле, будет сохранено число 1234. Вы по-
теряете одну цифру.
268 Приложение Г

Основное правило таково: если число предназначено


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

Числовой тип данных


Числовые типы данных предназначены для хранения
чисел. В большинстве СУБД поддерживаются многие чи-
словые типы данных, каждый из которых предназначен
для хранения чисел определенного диапазона.
Очевидно, чем больше поддерживаемый диапазон, тем
больше нужно места для хранения. Кроме того, некоторые
числовые типы данных поддерживают использование деся-
тичных точек (и дробей), другие поддерживают только це-
лые числа.
В табл. Г.2 представлены наиболее часто используемые
различные типы данных. Не все СУБД следуют соглашениям
о наименовании и описаниям, перечисленным в таблице.
Таблица Г.2. Числовые типы данных
Типы данных Описание
BIT Одноразрядное значение, 0 или 1, исполь-
зуется в основном для битовых флагов
DECIMAL (также на- Значения с фиксированной или плаваю-
зывается NUMERIC) щей запятой различной степени точности
FLOAT (также назы- Значения с плавающей запятой
вается NUMBER)
INT (также называ- 4-разрядные целые значения, поддержи-
ется INTEGER) ваются числа от -2147483648 до
2147483647
REAL 4-разрядные значения с плавающей за-
пятой
SMALLINT 2-разрядные целые значения, поддержи-
ваются числа от -32768 до 32767
TINYINT 1-байтовые целые значения, поддержи-
ваются числа от 0 до 255
Использование типов данных SQL 269

Кавычки не используются
В отличие от строковых типов данных, числовые нико-
гда не заключаются в кавычки.

Денежные типы данных


В большинстве СУБД поддерживается особый число-
вой тип данных для хранения денежных значений.
Обычно он называется MONEY ИЛИ CURRENCY. ЭТИ ТИПЫ
данных обычно относятся к типу DECIMAL, НО СО спе-
цифическими диапазонами, делающими их удобными
для хранения денежных значений.

Типы данных даты и времени


Все СУБД поддерживают типы данных, разработанные
для хранения значений даты и времени (табл. Г.З). Анало-
гично числовым значениям, большинство СУБД поддержи-
вают многие типы данных даты и времени, каждый со сво-
им диапазоном и степенью точности.
Таблица Г.З. Типы данных даты и времени
Тип данных Описание
DATE Значения даты
DATETIME (также на- Значения даты и времени
зывается TIMESTAMP)
SMALLDATETIME Значения даты и времени с точностью
до минуты (без значений секунд и л и
миллисекунд)
TIME Значение времени
270 Приложение Г

Указание дат
Не существует стандартного способа указания даты,
который подходил бы к любой СУБД. В большинстве
реализаций приемлем формат типа 2о04-12-30 или
Dec 3 0 t h , 2004, но даже эти значения могут ока-
заться проблемой для некоторых СУБД. Обязательно
обратитесь к документации своей СУБД и найдите
список распознаваемых ею форматов.

Даты в ODBC
Поскольку в каждой СУБД используется свой формат
представления даты, ODBC создал свой собственный
формат, который способен работать с любой СУБД
при использовании ODBC. Формат ODBC выглядит
так: {d '2004-12-30'} для значений дат,
{ t ' 2 1 : 4 6 : 2 9 ' } для значений времени и { t s '2004-
12-30 21:46 -.29'} для значений даты и времени. Ес-
ли вы выполняете SQL-код через ODBC, убедитесь в
том, что значения даты и времени отформатированы
подобным образом.

Двоичные типы данных


Двоичные типы данных относятся к числу наименее со-
вместимых (и реже всего используемых) типов данных.
В отличие от всех других типов данных, рассмотренных
нами до сих пор и предназначенных для весьма конкретно-
го применения, двоичные типы данных могут содержать
любые данные, даже информацию в двоичном виде, такую
как графические изображения, мультимедиа и документы
текстового процессора (табл. Г.4).
Использование типов данных SQL 2 7 1

Таблица Г.4. Двоичные типы данных

Тип данных Описание


BINARY Двоичные данные фиксированной длины
(максимальная длина может быть от
255 байт до 8000 байт, в зависимости от
реализации)
LONG RAW Двоичные данные переменной длины объ-
емом до 2 Гбайт
RAW (в некоторых Двоичные данные фиксированной длины
реализациях назы- объемом до 255 байт
ваются BINARY)
VARBINARY Двоичные данные переменной длины
(обычно максимальный объем варьируется
от 255 байт до 8000 байт, в зависимости от
реализации)

Сравнение типов данных


Чтобы выполнить реальный пример и провести срав-
нение типов данных различных СУБД, воспользуйтесь
таблицей создания сценариев, используемых для по-
строения экземпляров таблиц для этой книги (см.
приложение А, "Сценарии демонстрационных таб-
лиц"). Путем сравнения сценариев, используемых для
различных СУБД, вы на личном опыте убедитесь в
том, насколько сложна задача согласования типов
данных.
Приложение Д

Зарезервированные
слова SQL
В языке SQL широко используются ключевые слова —
особые слова, применяемые для выполнения операций SQL.
Нужно внимательно следить за тем, чтобы эти ключевые
слова не были использованы в качестве имен баз данных,
таблиц, столбцов и других объектов баз данных. Поэтому
ключевые слова считаются зарезервированными.
В данном приложении содержится перечень зарезерви-
рованных слов, наиболее часто встречающихся в основных
СУБД. Обратите внимание на следующие моменты.
• Ключевые слова — вещь весьма специфичная, поэто-
му не все приведенные ниже ключевые слова исполь-
зуются во всех СУБД.
• Во многих СУБД используется расширенный пере-
чень зарезервированных слов SQL; в него включаются
термины, специфичные для данной реализации. Мно-
гие из специфичных для отдельных СУБД ключевых
слов не представлены ниже.
• Чтобы обеспечить совместимость и переносимость,
следует избегать любого из зарезервированных слов,
если даже некоторые из них не относятся к числу за-
резервированных в вашей СУБД.
ABORT ABSOLUTE ACTION
ACTIVE ADD AFTER
ALL ALLOCATE ALTER
ANALYZE AND ANY
ARE AS AS С
ASCENDING ASSERTION AT
AUTHORIZATION AUTO AUTO-INCREMENT
AUTOINC AVG BACKUP
274 Приложение Д

BEFORE BEGIN BETWEEN


BIGINT BINARY BIT
BLOB BOOLEAN BOTH
BREAK BROWSE BULK
BY BYTES CACHE
CALL CASCADE CASCADED
CASE CAST CATALOG
CHANGE CHAR CHARACTER
CHARACTER_LENGTH CHECK CHECKPOINT
CLOSE CLUSTER CLUSTERED
COALESCE COLLATE COLUMN
COLUMNS COMMENT COMMIT
COMMITTED COMPUTE COMPUTED
CONDITIONAL CONFIRM CONNECT
CONNECTION CONSTRAINT CONSTRAINTS
CONTAINING CONTAINS CONTAINSTABLE
CONTINUE CONTROLROW CONVERT
COPY COUNT CREATE
CROSS CSTRING CUBE
CURRENT CURRENT_DATE CURRENT_TIME
CURRENTJTIMESTAMP CURRENTJJSER CURSOR
DATABASE DATABASES DATE
DATETIME DAY DBCC
DEALLOCATE DEBUG DEC
DECIMAL DECLARE DEFAULT
DELETE DENY DESC
DESCENDING DESCRIBE DISCONNECT
DISK DISTINCT DISTRIBUTED
DIV DO DOMAIN
DOUBLE DROP DUMMY
DUMP ELSE ELSEIF
ENCLOSED END ERRLVL
ERROREXIT ESCAPE ESCAPED
EXCEPT EXCEPTION EXEC
Зарезервированные слова SQL 275

EXECUTE EXISTS EXIT


EXPLAIN EXTEND EXTERNAL
EXTRACT FALSE FETCH
FIELD FIELDS FILE
FILLFACTOR FILTER FLOAT
FLOPPY FOR FORCE
FOREIGN FOUND FREETEXT
FREETEXTTABLE FROM FULL
FUNCTION GENERATOR GET
GLOBAL GO GOTO
GRANT GROUP HAVING
HOLDLOCK HOUR IDENTITY
IF IN INACTIVE
INDEX INDICATOR INFILE
INNER INOUT INPUT
INSENSITIVE INSERT INT
INTEGER INTERSECT INTERVAL
INTO IS ISOLATION
JOIN KEY KILL
LANGUAGE LAST LEADING
LEFT LENGTH LEVEL
LIKE LIMIT LINENO
LINES LISTEN LOAD
LOCAL LOCK LOGFILE
LONG LOWER MANUAL
MATCH MAX MERGE
MESSAGE MIN MINUTE
MIRROREXIT MODULE MONEY
MONTH MOVE NAMES
NATIONAL NATURAL NCHAR
NEXT NEW NO
NOCHECK NONCLUSTERED NONE
NOT NULL NULLIF
NUMERIC OF OFF
276 Приложение Д

OFFSET OFFSETS ON
ONCE ONLY OPEN
OPTION OR ORDER
OUTER OUTPUT OVER
OVERFLOW OVERLAPS PAD
PAGE PAGES PARAMETER
PARTIAL PASSWORD PERCENT
PERM PERMANENT PIPE
PLAN POSITION PRECISION
PREPARE PRIMARY PRINT
PRIOR PRIVILEGES PROC
PROCEDURE PROCESSEXIT PROTECTED
PUBLIC PURGE RAISERROR
READ READTEXT REAL
REFERENCES REGEXP RELATIVE
RENAME REPEAT REPLACE
REPLICATION REQUIRE RESERV
RESERVING RESET RESTORE
RESTRICT RETAIN RETURN
RETURNS REVOKE RIGHT
ROLLBACK ROLLUP ROWCOUNT
RULE SAVE SAVEPOINT
SCHEMA SECOND SECTION
SEGMENT SELECT SENSITIVE
SEPARATOR SEQUENCE SESSIONJJSER
SET SETUSER SHADOW
SHARED SHOW SHUTDOWN
SINGULAR SIZE SMALLINT
SNAPSHOT SOME SORT
SPACE SQL SQLCODE
SQLERROR STABILITY STARTING
STARTS STATISTICS SUBSTRING
SUM SUSPEND TABLE
TABLES TAPE TEMP
Зарезервированные слова SQL 277

TEMPORARY TEXT TEXTSIZE


THEN TIME TIMESTAMP
TO TOP TRAILING
TRAN TRANSACTION TRANSLATE
TRIGGER TRIM TRUE
TRUNCATE UNCOMMITTED UNION
UNIQUE UNTIL UPDATE
UPDATETEXT UPPER USAGE
USE USER USING
VALUE VALUES VARCHAR
VARIABLE VARYING VERBOSE
VIEW VOLUME WAIT
WAITFOR WHEN WHERE
WHILE WITH WORK
WRITE WRITETEXT XOR
YEAR ZONE
Предметный указатель
Q
ANSI SQL, 26 Query Designer, 246
Aqua Data Studio, 243, 244 Query Tool, 243, 254

ColdFusion, 245 SQL, 25


Command Center, 245 ANSI, 26
расширения, 26
D стандартный, 26
SQL Advantage, 255
Data Source ODBC, 255 Structured Query Language, 25
DB2, 245 Sybase Adaptive Server, 255

E
Enterprise Manager, 252 Аргумент
ALL, 96
M DISTINCT, 97
Macromedia, 245
Microsoft ASP, 248 Б
Microsoft ASP.NET, 249 База данных
Microsoft Query, 243, 250 безопасность, 231
Microsoft SQL Server, 251 основные понятия, 20
MySQL, 252 реляционная, 122
типа ISAM, 212
О
ODBC, 256 В
Oracle, 252 Внешнее объединение, 138
Внешний ключ, 222
Внутреннее объединение, 128
PHP, 253 Выборка
всех столбцов, 33
PostgreSQL, 44, 253
нескольких столбцов, 32
psql, 253
отдельных столбцов, 30
Вычисляемое поле, 69, 70
Предметный указатель 279

Индексно-последовательный
метод доступа, 212
Группа, 102 Источник данных ODBC, 256
фильтрующая, 104 Итоговые данные, 101
Групповой символ, 34
К
Д Кавычки, 47
Данные Каскадное удаление, 224
двоичные, 270 Ключ
добавление, 153 внешний, 222
итоговые, 101 первичный, 24, 122, 220
неотсортированные, 31 Ключевое слово, 29, 273
распределение по столбцам, AND, 52, 87
22 AS, 74, 134
сортировка, 35 ASC, 41
строковые, 266 BETWEEN, 48
тип, 23 DEFAULT, 174
форма представления, 33 DESC, 41
числовые, 268 FROM, 166
Декартово произведение, 126 IN, 56, 57
Добавление INTO, 154
выбранных данных, 158 NOT, 57, 58
данных, 153 ON, 229
нескольких строк, 160 OR, 53
полных строк, 153 OUT, 199
части строки, 157 PRIMARY KEY, 221
REFERENCES, 223
Е UNIQUE, 225
Код переносимый, 80
Естественное объединение, 137
Комбинированный запрос, 145
Копирование данных, 160
3 Критерий поиска, 43
Запись, 24 Курсор, 211
Запрос, 113 закрытие, 217
вложенный, 113 открытие, 215
комбинированный, 145 создание, 214
подчиненный, 113
сложный, 145 Л
Зарезервированное слово, 273
Левое внешнее объединение,
140
И
Индекс, 227
создание, 229
280 Предметный указатель

м GRANT, 232
INSERT, 153, 262
Масштабирование, 123 INSERT SELECT, 158, 262
Метасимвол, 62 INTERSECT, 152
знак процента, 62 LIKE, 61
квадратные скобки, 66 MINUS, 152
символ подчеркивания, 65 OPEN CURSOR, 215
Модуль ODBC, 256 RENAME, 179
REVOKE, 232
н ROLLBACK, 207, 262
SAVEPOINT, 209
Неявная фиксация, 207
SELECT, 29, 263
SELECT INTO, 160
О SQL, синтаксис, 259
Обновление данных, 163 TRUNCATE TABLE, 167
Объединение, 121 UNION, 146
внешнее, 138 UNION ALL, 150
внешнее левое, 140 UPDATE, 163, 263
внешнее полное, 141 в предложении WHERE, 51
внешнее правое, 140 завершение, 31
внутреннее, 128 левого внешнего
естественное, 137 объединения, 140
многих таблиц, 129 независимость от регистра,
перекрестное, 128 32
по эквивалентности, 128 правого внешнего
Ограничение, 219 объединения,140
на значения столбца, 225 условный, 45
уникальности, 224 Операция
Оператор !=, 47
ALTER TABLE, 176, 259 о, 47
CLOSE, 217 Откат, 205
COMMIT, 207, 260 Отмена, 205
CREATE INDEX, 229, 260
CREATE PROCEDURE, 260 п
CREATE TABLE, 169, 259, Первичный ключ, 24, 122, 220
261 создание, 221
CREATE VIEW, 185, 261
Переименование таблиц, 179
DECLARE, 214
Перекрестное объединение,
DELETE, 165, 261 128
DROP, 185, 262 Подзапрос, 113
DROP TABLE, 178 Поле, 70
EXCEPT, 152 вычисляемое, 69, 70
EXECUTE, 197 таблицы, 22
FETCH, 215
Предметный указатель 281

Полное внешнее объединение, Слово


141 зарезервированное, 273
Полностью определенное ключевое, 273
имя, 126 Сложный запрос, 145
Пользовательский тип Создание
данных, 226 индекса, 229
Порядок обработки курсора, 214
операторов, 54 таблицы, 169
Правое внешнее объединение, хранимой процедуры, 198
140 Сортировка
Предикат, 62, 98 в указанном направлении,
Предложение, 36 39
ALL, 103 данных, 35
FROM, 43 по невыбранным столбцам,
GROUP BY, 102 37
HAVING, 105 по нескольким столбцам, 37
ORDER BY, 36 по положению столбца, 38
SET, 164 результатов
VALUES, 156 комбинированных
WHERE, 43 запросов, 151
фильтрации, 43 Статистическая функция, 142
Представление, 181 Статистические вычисления,
методика создания, 185 96
удаление, 185 Столбец, 22, 70
Проверка полностью определенное
на диапазон значений, 48 имя, 126
на несовпадения, 46 производный, 76
на отсутствие значения, 48 Строка, 23
на равенство, 44 переменной длины, 266
одного значения, 46 фиксированной длины, 266
Псевдоним, 74, 133 СУБД, 20
столбца, 133 Схема, 22
таблицы, 134
т
Таблица, 21
Реляционная таблица, 121 переименование, 179
реляционная, 121
создание, 169
создание копии, 162
Самообъединение, 135 схема, 21
Символ удаление, 178
групповой, 34 уникальное имя, 21
звездочка, 34 Тип данных, 23, 265
Скобки, 55 даты и времени, 269
282 Предметный указатель

двоичный, 270 COUNT(), 92


денежный, 269 DATAPART(), 87
переменной длины, 266 LTRIM(), 74
пользовательский, 226 МАХ(), 93
совместимость, 23 MIN(), 94
фиксированной длины, 267 RTRIM(), 73
числовой, 268 SOUNDEX, 82
Точка SUM(), 95
отката, 205 TRIM0, 74
сохранения, 205, 209 UPPER0, 82
Транзакция, 203 итоговая, 90
управляемая, 206 манипулирования датой и
Триггер, 229 временем, 84
манипулирования текстом,
У 82
манипулирования числами,
Удаление 87
данных, 165 статистическая, 90
таблиц, 178
X
Ф
Хранимая процедура, 179,
Фиксация, 205 193
неявная, 207
частичная, 208
Фильтрация
ш
в SQL, 44 Шаблон поиска, 62
в приложении, 44
посредством подзапросов, Я
114
Фильтрация данных Язык структурированных
расширенная, 51 запросов, 25
Функция, 79
AVGQ, 90
Научно-популярное издание

Бен Форта
Освой самостоятельно SQL,
10 минут на урок
Литературный редактор П.Н. Мачуга
Верстка АЛ. Полинчик
Художественный редактор В.Г. Павлютин
Корректор Л. В. Пустовойтова

Издательский дом "Вильяме".


101509, Москва, ул. Лесная, д. 43, стр. 1.

Подписано в печать 29.04.2005. Формат 84ХЮ8/32.


Гарнитура Times. Печать офсетная.
Усл. печ. л. 15,1. Уч.-изд. л. 9,9.
Тираж 3000 экз. Заказ № 1645.

Отпечатано с диапозитивов в ФГУП "Печатный двор"


Министерства РФ по делам печати,
телерадиовещания и средств массовых коммуникаций.
197110, Санкт-Петербург, Чкаловский пр., 15.
MySQL
Учебное пособие
Люк Веллинг и Лора Томсон

К нига представляет собой крат- ISBN: 5-8459-0769-1


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

h t t p : / / w w w . w i l l i a m s p u b l i s h i n g . c o m
M Y S Q L .

РУКОВОДСТВО
АДМИНИСТРАТОРА
Компания MySQL AB MySQL занимает лидирующие
позиции среди множества
систем управления базами
данных с открытым исходным
кодом. Благодаря высокой
производительности и простоте
• настройки, богатому выбору
API-интерфейсов, а также
функциональным средствам
работы с сетями, сервер MySQL
стал одним из наиболее удачных
вариантов для разработки Web-
приложений, взаимодействующих
с базами данных.
В этой книге предложен
всеобъемлющий подход к
установке, обслуживанию и
администрированию сервера
баз данных MySQL. Являясь,
фактически, официальной
MySQL документацией, книга
покрывает весь спектр вопросов,
- касающихся администрирования,
ОфМЦМ-ЯДЬИС!? РУКОВОДСТВО ПО ¥С!3*Ю&К&,
а также предлагает информацию,
ориентированную на
опытных пользователей
www.williamspublishing.com и администраторов.
Книга рассчитана на
администраторов и
разработчиков Web-приложений
любой квалификации, а также
на студентов и преподавателей
соответствующих дисциплин.

ISBN 5 - 8 4 5 9 - 0 8 0 5 - 1 в продаже
M Y S Q L

СПРАВОЧНИК ПО ЯЗЫКУ

Компания MySQL AB Эта книга, написанная


специалистами компании
MySQL AB, является всеобъемлющим
справочником по языку SQL, который
используется для организации

шшшц
запросов к базам данных, а также
особенностях реализации стандарта
т SQL в сервере MySQL. По сути — это
официальная документация фирмы-
производителя. В книге рассмотрен
весь спектр вопросов, касающихся
языковой структуры, допустимых
типов столбцов, операторов,
операций и функций, а также
существующих расширений MySQL;
также представлена информация,
предназначенная для опытных
программистов и администраторов.
Как известно, MySQL занимает
лидирующие позиции среди
"шШтш множества систем управления
базами данных с открытым
MySQL исходным кодом. Благодаря
Справочник по языку высокой производительности и
простоте настройки, богатому
выбору API-интерфейсов, а также
функциональным средствам работы
с сетями, сервер MySQL стал одним
из наиболее удачных вариантов
www.williamspublishing.com для разработки Web-приложений,
взаимодействующих с базами данных.
Книга рассчитана на разработчиков
Web-приложений и администраторов
любой квалификации, а также
на студентов и преподавателей
соответствующих дисциплин.

ISBN 5-8459-0804-3 в продаже

Вам также может понравиться