SQL за 24 часа

SQL за 24 часа

1-й час Добро пожаловать в мир SQL

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

Основными на этом уроке будут следующие темы.

• Введение в SQL и краткая история SQL

• Введение в системы управления базами данных

• Обзор основных терминов и понятий

• Обзор базы данных, используемой в данной книге

Определение и история SQL

В любом бизнесе имеются данные, что в свою очередь требует создания некоторого организованного метода или механизма управления этими данными. Такой механизм принято называть системой управления базами данных (СУБД). Системы управления базами данных используются уже много лет, многие из них вышли из использовавшихся еще на мэйнфреймах систем плоских файлов. Основываясь на современных технологиях, доказавшие свою пользу системы управления базами данных начали развиваться в других направлениях, отвечая требованиям растущего бизнеса, все возрастающих объемов корпоративных данных и, конечно же, технологий, связанных с Internet.

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

Что такое SQL?

SQL - язык структурированных запросов - является стандартным языком управления реляционными базами данных. Его прототип был разработан фирмой IBM на основе идей, изложенных в статье д-ра Кодда (Е. F. Codd) "Реляционная модель данных для больших банков данных общего пользования". Немногим позже появления прототипа IBM, в 1979 году, на рынке появился первый продукт SQL под названием ORACLE, который был выпущен компанией Relational Software, Incorporated (впоследствии переименованной в Oracle Corporation). Сегодня эта компания является одним из выдающихся лидеров в области реализации технологий реляционных баз данных. SQL можно произносить либо по буквам - S-Q-L, либо как "сиквэл" (sequel) - оба произношения приемлемы.

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

Что такое ANSI SQL?

Американский национальный институт стандартов (ANSI) представляет собой организацию, которая устанавливает и внедряет стандарты в самых разных отраслях производства. SQL, ставший фактически стандартным языком в области управления базами данных, сначала был утвержден таковым в 1986 году на основе реализации IBM. В 1987 году стандарт ANSI SQL был принят в качестве международного стандарта Международной организацией стандартов (ISO). Этот стандарт был вновь пересмотрен в 1992 году и получил название SQL/92. Самый новый на сегодня стандарт называется SQL3 и иногда на него ссылаются как на SQL/99.

Новый стандарт: SQL3

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

• Часть 1 - SQL/Структура (SQL/Framework) - определяет общие требования соответствия и фундаментальные понятия SQL.

• Часть 2 - SQL/Основы (SQL/Foundation) - определяет синтаксис и операции SQL.

• Часть 3 - SQL/Интерфейс вызовов (SQL/Call-Level Interface) - определяет интерфейс программного взаимодействия приложений с SQL.

• Часть 4 - SQL/'Встроенные модули (SQL/Persistent Stored Modules) - определяет управляющие структуры, лежащие в основе SQL-программ. Часть 4 определяет и модули, содержащие SQL-программы.

• Часть 5 - SQL/Языковая привязка к серверу (SQL/Host Language Bindings) - определяет возможности встраивания операторов SQL в приложения, созданные на основе стандартных языков программирования.

Этот новый стандарт ANSI (SQL3) позволяет использовать два минимальных уровня взаимодействия, которые может объявить СУБД - это поддержка ядра SQL (Core SQL Support) и поддержка расширенного SQL (Enhanced SQL Support).

ANSI расшифровывается как American National Standards Institute (Американский Национальный институт стандартов). Этот институт представляет собой организацию, ответственную за внедрение стандартов на самые разные продукты и концепции.

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

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

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

Реализация SQL - это SQL-продукт конкретного производителя.

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

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

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

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

Рис. 1.1. База данных

Реляционные базы данных

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

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

Реляционная база данных - это база данных, состоящая из связанных объектов, главным образом таблиц. Таблицы являются основной формой хранения данных в базе данных.

Технология клиент/сервер

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

В системе клиент/сервер главный компьютер, называемый сервером, обычно доступен через сеть, как правило, это локальная сеть (LAN - Local area network) или глобальная сеть (WAN - Wide area network). Доступ к такому серверу теперь обеспечивается не посредством "тупых" терминалов, а персональных компьютеров (ПК) или других серверов. В этом случае персональный компьютер называется клиентом и должен иметь доступ к сети, чтобы между клиентом и сервером имелась возможность обмена данными. Главное различие между системой клиент/сервер и системой, основанной на использовании мэйнфрейма, заключается в том, что пользователь ПК в системе клиент/сервер может использовать вычислительные возможности своего собственного компьютера для обработки данных и выполнения других процессов непосредственно в памяти своего компьютера, но в то же время и сервер оказывается всегда доступным для пользователя через сеть. На сегодня в большинстве случаев система клиент/сервер удовлетворяет всем требованиям современного бизнеса, оказывается более гибкой и в конце концов более предпочтительной.

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

Рис. 1.3. Модель клиент/сервер

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

Популярные производители систем управления базами данных

Среди доминирующих производителей систем управления базами данных следует назвать Oracle, Microsoft, Informix, Sybase и IBM. И хотя в мире существует их значительно больше, именно представленные здесь имена вы чаще всего встречаете в книгах, газетах, журналах и в World Wide Web.

Различия между реализациями

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

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

Сеанс SQL

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

Команда CONNECT

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

CONNECT user@database

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

Команда DISCONNECT

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

DISCONNECT

Типы команд SQL

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

Такими категориями являются:

• DDL (Data Definition Language - язык определения данных);

• DML (Data Manipulation Language - язык манипуляций данными);

• DQL (Data Query Language - язык запросов к данным);

• DCL (Data Control Language - язык управления данными);

• команды администрирования данных;

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

Определение структур базы данных (DDL)

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

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

CREATE TABLE

ALTER TABLE

DROP TABLE

CREATE INDEX

ALTER INDEX

DROP INDEX

Эти команды будут подробно обсуждаться в ходе урока 3, "Управление объектами базы данных", и урока 17, "Повышение эффективности работы с базой данных".

Манипуляция данными (DML)

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

Вот три основные команды DML:

INSERT

UPDATE

DELETE

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

Отбор данных (DQL)

Хотя этот раздел языка представлен только одной командой, для пользователя реляционной базы данных язык запросов к данным (DQL) является самой главной частью SQL. Этой командой является команда

SELECT

Эта команда, имеющая множество опций и необязательных параметров, используется для построения запросов к реляционным базам данных. С ее помощью можно конструировать запросы любой сложности - от самых общих до очень специальных и от самых простых до невероятно сложных. Команда SELECT будет подробно обсуждаться в ходе уроков 7-16.

Запрос - это требование на получение информации из базы данных.

Язык управления данными (DCL)

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

ALTER PASSWORD

GRANT

REVOKE

CREATE SYNONYM

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

Команды администрирования данных

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

START AUDIT

STOP AUDIT

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

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

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

• Команда COMMIT используется для того, чтобы сохранить транзакции.

• Команда ROLLBACK используется для того, чтобы отменить транзакции.

• Команда SAVEPOINT создает точки внутри групп транзакций, к которым отсылает команда ROLLBACK.

• Команда SET TRANSACTION позволяет назначить транзакции имя.

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

Описание базы данных, используемой в данной книге

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

Схема таблиц, используемых в книге

На рис. 1.4 показаны отношения между таблицами, используемыми в этой книге для примеров, вопросов для проверки и упражнений. Каждая из таблиц имеет скос имя, точно так же свои имена назначены в таблицах каждому из полей. Линии, связывающие таблицы, указывают на связи таблиц посредством общего поля, которое в большинстве случаев называется ключевым полем (последние обсуждаются в ходе урока 3, "Управление объектами базы данных").

Стандарты назначения имен таблицам

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

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

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

Обзор данных

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

EMPLOYEE_TBL

EMP_ID

LAST NAM

FIRST NAM

ADDRESS

CITY

ST

ZIP

PHONE

311549902 442346889 213764555 313782439 220984332 443679012

STEPHENS PLEW GLASS GLASS WALLACE SPURGEON

TINA LINDA BRANDON JACOB MARIAH TIFFANY

D RR 3 BOX 17A С 3301 BEACON S 1710 MAIN ST 3789 RIVER BLVD 7789 KEYSTONE 5 GEORGE COURT

GREENWOOD INDIANAPOLIS WHITELAND INDIANAPOLIS INDIANAPOLIS INDIANAPOLIS

IN IN IN IN IN IN

47890 46224 47885 45734 46741 46234

3178784465 3172978990 3178984321 3175457676 3173325986 3175679007

EMPLOYEE PAY TBL

EMP_ID

POSITION

DATE HIRE

PAY RATE

DATE_LAST

SALARY

BONUS

311549902 442346889 213764555 313782439 220984332 443679012

MARKETING TEAM LEADER SALES MANAGER SALESMAN SHIPPER SHIPPER

23-MAY-89 17-JUN-90 14-AUG-94 28-JUN-97 22-JUL-96 14- JAN-91

14.75

11 15

Ol-MAY-99 Ol-JON-99 Ol-AUG-99

Ol-JUL-99 Ol-JAN-99

40000

30000 20000

2000 1000

CUSTOMERJTBL

ORDERS TBL

CUST ]

CD CUST_NAME

ADDRESS

CUST_CITY

ST

ZIP CUST_PHONE CUST FAX

232 109

345 090 12 432 333

21

43

287 288 590

610 560 221

LESLIE GLEASON NANCY BUNKER

ANGELA DOBKO WENDY WOLF MARYS GIFT SHOP SCOTTYS MARKET JASONS AND DALLAS GOODIES MORGAN CANDIES AND TREATS SCHYLERS NOVELTIES GAVINS PLACE HOLLYS GAMEARAM HEALTHERS FEATHERS AND THINGS RAGANS HOBBIES ANDYS CANDIES RYANS STUFF

798 HARDAWAY DR APT A 4556 WATERWAY RR3 BOX 76 3345 GATEWAY DR 435MAIN ST RR2 BOX 17 LAFAYETTE SQ MALL

5657 W TENTH ST 17 MAPLE ST

9880 ROCKVILLE RD 567 US 31 4090 N SHADELAND AVE

451 GREEN RR 1 BOX 34 2337 S SHELBY ST

INDIANAPOLIS BROAD RIPPLE

LEBANON INDIANAPOLIS DANVILLE BROWNSBURG INDIANAPOLIS

INDIANAPOLIS LEBANON

INDIANAPOLIS WHITELAND INDIANAPOLIS

PLAINFIELD NASHVILLE INDIANAPOLIS

IN IN

IN IN IL IN IN

IN IN

IN IN IN

IN IN IN

47856 3175457690 46950 3174262323

49967 7658970090 46224 3172913421 47978 3178567221 3178523434 45687 3178529835 3178529836 47856 3172978886 3172978887

46950 3172714398 49967 3174346758

46224 3172719991 3172719992 47978 3178879023 47856 3175456768

46950 3178393441 3178399090 49967 8123239871 46224 3175634402

ORD NUM

CUST_ID

PROD_ID

QTY

ORD DATE

56A901 56A917 32A132 16C17 18D778 23E934

232

12 43 090 287 432

11235 87 222 222 90 13

1 100 25 2 10 20

22-OCT-99 30-SEP-99 10-OCT-99 17-OCT-99 17-OCT-99 15-OCT-99

PRODUCTS_TBL

PROD_ID

PROD_DESC

COST

11235

222

13

90

15

9

6

87

119

1234

2345

КОСТЮМ ВЕДЬМЫ

ПЛАСТИКОВЫЕ ТЫКВЫ

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

ФОНАРИ

КОСТЮМЫ В АССОРТИМЕНТЕ

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ПЛАСТИКОВЫЕ ПАУКИ

МАСКИ В АССОРТИМЕНТЕ

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

ПОЛОЧКА ИЗ ДУБА

29.99

7.75

1.10

14.50

10.00

1.35

1.45

1.05

4.95

5.95

59.99

Из чего состоят таблицы

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

Поле

Всякая таблица делится на меньшие элементы, называемые полями. Полями В Таблице PRODUCTSJTBL ЯВЛЯЮТСЯ PROD_ID, PROD_DESC И COST. Эти поля распределяют хранимую в таблице информацию по категориям. Поле - это столбец в таблице, предназначенный для хранения определенной специфической информации о каждой записи в таблице.

Запись или строка данных

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

11235 КОСТЮМ ВЕДЬМЫ 29.99

Ясно, что в данном случае запись состоит из кода товара, описания товара и цены за его единицу. Для каждого из товаров предполагается наличие в таблице PRODUCTS_TBL отдельной записи. Запись представляет собой целую строку таблицы.

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

Столбец

Столбец - это колонка таблицы, содержащая все данные, относящиеся к заданному полю таблицы. Например, столбец таблицы PRODUCTS_TBL, соответствующий описанию товара, содержит следующие данные:

КОСТЮМ ВЕДЬМЫ

ПЛАСТИКОВЫЕ ТЫКВЫ

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

ФОНАРИ

КОСТЮМЫ В АССОРТИМЕНТЕ

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ПЛАСТИКОВЫЕ ПАУКИ

МАСКИ В АССОРТИМЕНТЕ

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

ПОЛОЧКА ИЗ ДУБА

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

Ключевое поле

Ключевое поле (primary key) - это столбец, данные в котором однозначно идентифицируют каждую строку данных в таблице реляционной базы данных. Ключевым полем в таблице PROD_TBL является PROD_ID, которое обычно за-

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

Значение NULL

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

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

Резюме

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

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

Вопросы и ответы

Изучив SQL, смогу ли я воспользоваться любой из реализаций SQL, если это потребуется?

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

В рамках технологии клиент/сервер персональный компьютер является клиентом или сервером?

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

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

Определенно нет. Суффикс _TBL выбран в качестве стандарта для того, чтобы легче было распознавать таблицы в базе данных. Таким образом, можно вместо TBL использовать TABLE или вообще отказаться от использования суффикса. Например, таблицу EMPLOYEE_TBL МОЖНО было бы назвать просто EMPLOYEE.

Что будет, если при вводе новой записи в таблицу я не введу, например, номер телефона нового служащего, а в столбце для номера телефона стоит NOT NULL?

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы-рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Что означает аббревиатура SQL?

2. На какие шесть категорий разделяются команды SQL?

3. Какие четыре команды являются командами управления транзакциями?

4. Каковы главные отличия технологии клиент/сервер от технологии, использующей мэйнфрейм?

5. Если поле определено как NULL, значит ли это, что в это поле обязательно должно быть что-нибудь введено?

Упражнения

1. Идентифицируйте категории, к которым относятся следующие команды SQL:

CREATE TABLE

DELETE

SELECT

INSERT

ALTER TABLE

UPDATE

2-й час Структура данных

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

Основными на этом уроке будут следующие темы.

• Анализ размещенных в таблице данных

• Основные типы данных

• Рекомендации по использованию основных типов данных

• Примеры, раскрывающие различия между типами данных

Что такое данные?

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

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

Данные являются основой любой базы данных, и они должны быть защищены. Такую защиту обычно осуществляет администратор базы данных, хотя и каждый пользователь базы данных должен осознать, что необходимо принять определенные меры для защиты данных. Защита данных подробно обсуждается в ходе урока 18, "Управление доступом к базе данных", и урока 19, "Обеспечение сохранности данных".

Основные типы данных

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

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

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

• символьные строки;

• числовые строки;

• значения даты и времени.

Строки фиксированной длины

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

CHARACTER:n

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

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

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

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

Строки переменной длины

SQL поддерживает строки переменной длины. Стандартное определение строк переменной длины в SQL выглядит так:

CHARACTER VARYING(n)

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

Обычными типами данных для строк переменой длины являются VARCHAR и VARCHAR2. VARCHAR соответствует стандарту ANSI и используется, например, в Microsoft SQL Server, a VARCHAR2 используется Oracle, чтобы не зависеть от возможных изменений VARCHAR в будущем. Этот тип данных предполагает хранение буквенночисловых значений.

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

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

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

Числовые значения хранятся в полях, определенных как некоторого типа числа и обычно имеющих атрибуты типа NUMBER, INTEGER, REAL, DECIMAL и т. п. Стандартными для SQL являются следующие значения:

BIT(П)

BIT VARYING (n)

DECIMAL(p,S)

INTEGER

SMALLINT

FLOAT(p)

REAL(s)

DOUBLE PRECISION(p)

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

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

NUMBER(5)

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

Десятичные значения

Десятичные значения - это числовые значения, в которых используется десятичная точка (десятичный разделитель). Вот стандартный оператор SQL для определения десятичного типа данных, где р задает точность, as - масштаб числа:

DECIMAL(p,s)

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

Масштаб - это число знаков справа от десятичного разделителя. В предыдущем примере DECIMAL (4,2) масштаб задается равным 2.

Если в поле, определенное как DECIMAL (3,1), ввести значение 34 .33, то введенное значение округлится до 34.3.

Если для значений в поле при определении назначен тип DECIMAL (4, 2), это значит, что значения, хранимые в поле, будут ограничены сверху числом 99.99.

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

Например, для столбца, определенного как DECIMAL (4,2), допустимыми будут следующие значения:

12

12.4

12.44

12. 449,

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

Целые

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

1 п

99

-99

199

Десятичные значения с плавающей точкой

Десятичные значения с плавающей точкой (float-point decimals) - это десятичные значения, чьи точность и масштаб имеют переменную длину и практически не имеют предела. Для таких значений допустимы любые точность и масштаб. Тип данных REAL используется для определения столбца с десятичными числами (с плавающей точкой) обычной точности, а тип данных DOUBLE PRECISION соответствует десятичным числам (с плавающей точкой) двойной точности. Чтобы значение считалось значением обычной точности, его точность должна задаваться числом от 1 до 21 включительно, а для значений двойной точности она должна быть между 22 и 53 включительно. Вот несколько примеров использования типа данных FLOAT:

FLOAT FLOAT(15) FLOAT(50)

Значения даты и времени

Тип данных даты и времени, очевидно, используется для хранения информации о датах и времени. Стандарт SQL поддерживает соответствующие типы данных, называемые DATETIME, которые представлены следующими конкретными типами:

DATE TIME

INTERVAL ТIMESTAMP

Тип данных TIMESTAMP состоит из следующих элементов:

YEAR

MONTH

DAY

HOUR

MINUTE

SECOND

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

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

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

Буквальные значения

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

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

'Hello'

45000

"45000"

3.14

' 1 ноября 1997'

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

Значения NULL

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

Для значения NULL можно использовать следующие две формы ссылки на него.

• NULL (ключевое слово NULL)

• ' ' (два знака одиночной кавычки и ничего между ними)

Следующая строка не представляет значения NULL, а представляет строку, содержащую символы N-U-L-L:

'NULL'

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

Значения типа BOOLEAN (логические значения) могут принимать значения TRUE (истина), FALSE (ложь) или NULL. Значения типа BOOLEAN используются для сравнения данных. Например, если в запросе заданы несколько критериев, каждое из заданных условий оценивается и им присваиваются значения TRUE, FALSE или NULL. Соответствующие данные включаются в ответ на запрос только тогда, когда для всех условий возвращается логическое значение TRUE. Если же среди возвращенных значений будут либо FALSE, либо NULL, данные в ответ на запрос могут не"включаться.

Рассмотрим следующий пример.

WHERE NAME = 'SMITH'

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

Пользовательские типы данных

Пользовательский тип данных - это тип данных, определяемый пользователем. Пользовательские типы данных дают возможность строить свои типы данных на основе уже имеющихся. Для создания такого типа данных используется оператор CREATE TYPE. Например,

CREATE TYPE PERSON AS OBJECT

(NAME VARCHAR2(30),

SSN VARCHAR2(9));

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

CREATE TABLE EMP_PAY (EMPLOYEE PERSON, SALARY NUMBER(10,2), HIRE_DATE DATE);

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

ALTER DOMAIN MONEY_D

ADD CONSTRAINT MONEY__CON1

CHECK (VALUE > 5};

Сослаться на домен можно так:

CREATE TABLE EMP__PAY

(EMP_ID NUMBER(9),

EMP_NAME VARCHAR2(30),

PAY_RATE MONEY_D);

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

Резюме

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

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

Вопросы и ответы

Почему можно вводить числа (например, идентификационный код) в поля, определенные как строки символов?

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

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

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно про'верить по Приложению Б, "Ответы".

Тесты

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

2. Верно ли утверждение: "Масштаб числового значения - это максимальная допустимая для значения длина?"

3. Все ли реализации используют одинаковые типы данных?

4. Какими для определенных ниже типов данных являются точности и масштабы значений?

DECIMAL(4,2) DECIMAL(10,2) DECIMAL(14,1)

5. Какие из следующих данных могут быть введены в столбец, тип данных которого DECIMAL(4,1)? а. 16.2 б. 116.2 в. 16.21 г. 1116.2 Д. 1116.21

Упражнения

1. Рассмотрите следующие имена столбцов и выберите для них подходящий тип данных и подходящую длину.

a ssn

б state

в. city

г. phone_number

д. zip

е. last__name

ж. firs t_name

з middle_narre

и. salary

к. houriy_pay_rate

л. date_hired

2. Для столбцов с теми же именами решите, следует ли для них определить значения NULL или NOT NULL. Обратите внимание на то, что в некоторых случаях, когда для столбца предусмотрено NOT NULI, значением соответствующего поля в строке может быть NULL, и наоборот

a ssn

б state

в city

г. phone_number

д. zip

е. last_name

ж. first_name

з. middle_name

и. salary

к hourly_pay_rate

л. date_hired

3-й час Управление объектами базы данных

На этом уроке мы обсудим объекты базы данных: узнаем, что они из себя представляют, как они работают, в каком виде хранятся и как связаны друг с другом. Объекты базы данных составляют основу реляционной базы данных. Эти объекты представляют собой логически цельные единицы, используемые для хранения информации, и поэтому на них ссылаются как на объекты базы данных нижнего уровня (back-end database). Большинство из приводимых в тексте этого урока инструкций относится к таблицам, но существуют и другие объекты базы данных, обсуждение которых предполагается по ходу изучения материала книги в других уроках.

Основными на этом уроке будут следующие темы.

• Знакомство с объектами базы данных

• Знакомство со схемами

• Структура таблиц и работа с ними

• Обсуждение природы и атрибутов таблиц

• Примеры создания таблиц и работа с ними

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

• Концепции ссылочной целостности и совместимости данных

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

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

Что такое схема?

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

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

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

EMPLOYEEJTBL USER1.EMPLOYEEJTBL

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

USER:.EMPLOYEEJTBL

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

Рис. 3.1. Схемы в базе данных

На рис. 3.1 показаны два пользователя, USER1 и USER2, имеющие в базе данных свои таблицы. Каждому из пользователей назначена своя схема. Вот примеры того, как эти пользователи могут обращаться к своим и к чужим таблицам: Доступ LJSER1 к своей таблице tablel: TABLE 1 Доступ USER1 к своей таблице test: TEST Доступ USER1 к таблице tablelO пользователя USER2: USER2.TABLE10 Доступ USER1 к таблице test пользователя USER2: USER2.TEST

Оба пользователя имеют по таблице с именем TEST. Таблицы, принадлежащие разным схемам в базе данных, могут иметь одинаковые имена. Если посмотреть на имена с точки зрения схем, имена таблиц в базе данных всегда будут уникальными, поскольку на самом деле частью имени таблицы всегда является имя владельца схемы. В данном случае, например, имя USER1.TEST отличается от имени USER2.TEST. Если при обращении к таблице по имени вы не укажете имя схемы, сервер базы данных будет искать таблицу только в рамках той схемы, владельцем которой вы являетесь по умолчанию. Например, если USER1 попытается обратиться к TEST, сервер базы данных сначала попытается найти таблицу с именем TEST среди таблиц пользователя USER1 и только потом обратится к другим объектам пользователя USER1, включая и синонимы для таблиц из других схем. Использование синонимов объясняется в ходе урока 21, "Работа с системным каталогом".

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

Таблица как основная форма хранения данных

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

Поля и столбцы

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

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

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

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

Строки

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

Оператор CREATE TABLE

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

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

• Какого типа данные будут вводиться в таблицу?

• Каким должно быть имя таблицы?

• Каким столбцом (или столбцами) будет задаваться ключевое поле (составной ключ)?

• Какие имена следует присвоить столбцам (полям)?

• Какие типы данных следует назначить столбцам?

• Какой выбрать длину каждого из столбцов?

• Какие столбцы таблицы будут требовать обязательного ввода данных?

Получив ответы на все эти вопросы, не составляет труда построить подходящий оператор CREATE TABLE и применить его.

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

CREATE TABLE ИМЯ_ТАБЛИЦЫ ( ПОЛЕ1 ТИП ДАННЫХ [ NOT NULL ] , ПОЛЕ2 ТИП ДАННЫХ [ NOT NULL ] , ПОЛЕЗ ТИП ДАННЫХ [ NOT NULL ] , ПОЛЕ4 ТИП ДАННЫХ [ NOT NULL ] , ПОЛЕ5 ТИП ДАННЫХ [ NOT NULL ] ) ;

В примерах этого урока используются такие популярные типы данных, как CHAR (символьный постоянной длины), VARCHAR (символьный переменной длины), NUMBER (числовой, для десятичных и не десятичных значений) и DATE (для значений даты и времени).

Создайте таблицу с именем EMPLOYEE_TBL, например, с помощью следующего оператора:

CREATE TABLE EMPLOYEE_TBL

(EMP_ID CHAR(9) NOT NULL,

EMP_NAME VARCHAR2(40) NOT NULL,

EMP_ST_ADDR VARCHAR2(20) NOT NULL,

EMP_CITY VARCHAR2U5) NOT NULL,

EMP_ST CHAR(2) NOT NULL,

EMP_ZIP NUMBER(5) NOT NULL,

EMP_PHONE NUMBER(10) NULL,

EMP_PAGER NUMBER(10) NULL);

В результате в таблице будет восемь столбцов. Обратите внимание на использование символа подчеркивания в именах столбцов так, что эти имена кажутся состоящими из нескольких слов (например, EMPLOYEE ID превратилось в EMP_ID). Каждому столбцу назначен свой тип данных определенной длины, а использование ограничений NULL /NOT NULL позволяет указать, какие из столбцов должны обязательно иметь значения во всех строках таблицы. Поле EMP_PHONE определено как NULL, и это значит, что для соответствующего столбца допустимы пустые значения (ввиду того, что не все могут иметь телефонные номера). Информация о столбцах разделяется запятыми, а описания всех столбцов заключены в круглые скобки (открывающая скобка помещена перед определением первого столбца, а закрывающая - после определения последнего).

Завершается оператор точкой с запятой. Большинство реализаций SQL предполагает использование некоторого символа, означающего завершение оператора или передачу оператора серверу базы данных. В Oracle используется точка с запятой. Trans-act-SQL использует оператор GO. В этой книге используется точка с запятой.

В созданной нами таблице каждая запись или строка с данными будет состоять из следующих полей: EMP_ID, EMP_NAME, EMP__ST_ADDR, EMP_CITY, EMP_ST, EMP_ZIP, EMP_PHONE, EMP_PAGER

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

Значение NULL является значением столбца по умолчанию, следовательно, это значение в операторе CREATE TABLE вводить не обязательно.

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

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

CREATE TABLE EMPLOYEEJTBL (EMP_ID CHAR(9) NOT NULL,

EMP_NAME VARCHAR2(40) NOT NULL,

EMP_ST_ADDR VARCHAR2(20) NOT NULL,

EMP_CITY VARCHAR2CL5) NOT NULL,

EMP_ST CHAR(2) NOT NULL,

EMP_ZIP NUMBER(5) NOT NULL,

EMP_PHONE NUMBER(10) NULL,

EMP_PAGER NUMBER(10) NULL) STORAGE

(INITIAL 3K NEXT 2К );

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

Обратите внимание на полученный с помощью отступов аккуратный вид приведенного выше примера использования оператора CREATE TABLE. Это облегчает чтение и отладку программ.

Ключевое слово STORAGE в различных реализациях SQL используется по-разному. Предыдущий пример использования STORAGE взят из Oracle, где оно добавляется к оператору CREATE TABLE. He забывайте, что стандарт ANSI для SQL является всего лишь стандартом и не более. Стандарт непосредственно языком не является, а обеспечивает производителям рекомендации, касающиеся разработки их реализаций SQL. Вы обнаружите, что и типы данных тоже зависят от реализации. Во многих отношениях зависят от реализации и подходы к хранению и обработке данных.

Соглашения о присвоении имен

При выборе имен для объектов, в частности для таблиц и столбцов, имя должно соответствовать хранящимся данным. Например, для таблицы, в которой предполагается хранить информацию о служащих, подойдет имя EMPLOYEE_TBL. Той же логике должны следовать и имена столбцов. Для столбца, в котором будет храниться номер телефона служащего, очевидно подходящим именем будет PHONE_NUMBER.

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

Команда ALTER TABLE

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

ALTER TABLE ИМЯ_ТАБЛИЦЫ [MODIFY] [COLUMN ИМЯ_СТОЛБЦА] [ТИП ДАННЫХ|NULL NOT NULL] [RESTRICT|CASCADE]

[DROP] [CONSTRAINT ИМЯ_ОГРАНИЧЕНИЯ]

[ADD] [COLUMN] ОПРЕДЕЛЕНИЕ СТОЛБЦА

Модификация элементов таблицы

Атрибуты столбца задают правила представления данных в столбце. С помощью команды ALTER TABLE можно менять атрибуты столбца. Под атрибутами здесь понимается следующее:

• тип данных в столбце;

• длина, точность или масштаб данных в столбце;

. • разрешение или запрет иметь в столбце значение NULL.

В следующем примере команда ALTER TABLE используется для того, чтобы изменить атрибуты столбца EMP_ID таблицы EMPLOYEE_TBL.

ALTER TABLE EMPLOYEE_TBL MODIFY (EMP_ID VARCHAR2(10));

Изменение таблицы.

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

Добавление столбцов, требующих обязательного ввода данных

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

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

1. Добавьте столбец, задав ему атрибут NULL (это значит, что в столбце не обязательно должны присутствовать данные).

2. Введите данные в каждую строку нового столбца таблицы.

3. Убедившись, что столбец содержит значение в каждой из строк таблицы, можно изменить атрибут столбца на NOT NULL.

Изменение столбцов

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

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

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

• Для столбцов с числовыми данными ширину всегда можно увеличить.

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

• Для числовых данных можно увеличивать или уменьшать число десятичных знаков.

• Тип данных в столбце обычно можно изменить.

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

Создание таблицы на основе уже существующей

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

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

CREATE TABLE ИМЯ_НОВОЙ_ТАБЛИЦЫ AS SELECT [ *|СТОЛБЕЦ!, СТОЛБЕЦ2 ] FROM ИМЯ_ТАБЛИЦЫ [ WHERE ]

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

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

SELECT * FROM PRODUCTSJTBL;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

SELECT * выбирает данные из всех полей данной таблицы Символ * представляет целую сроку данных (т. е. запись) в таблице.

Затем на основе результатов этого запроса создадим таблицу с именем PRODUCTS_TMP.

CREATE TABLE PRODUCTS_TMP AS

SELECT * FROM PRODUCTS_TBL;

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

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

SELECT * FROM PRODUCTS_TMP;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

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

Удаление таблиц

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

DROP TABLE ИМЯ_ТАБЛЙЦЫ [ RESTRICT|CASCADE ]

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

DROP TABLE USER1.PRODUCTSJTMP;

Удаление таблицы.

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

Условия целостности

УСЛОВИЯ целостности обеспечивают правильность и согласованность данных в реляционных базах данных. В основе целостности данных в реляционных базах данных лежит понятие ссылочной целостности. Ссылочная целостность складывается из целого ряда условий целостности, каждое из которых играет свою роль.

Ключевые поля

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

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

CREATE TABLE EMPLOYEEJTBL (EMP_ID CHAR(9) NOT NULL PRIMARY KEY,

EMPJSIAME VARCHAR2(40) NOT NULL,

EMP_ST_ADDR VARCHAR2(20) NOT NULL,

EMP_CITY VARCHAR2(15) NOT NULL,

EMP_ST CHAR(2) NOT NULL,

EMP_ZIP NUMBER(5) NOT NULL,

EMP_PHONE NUMBER(10) NULL,

EMP_PAGER NUMBER(10) NULL);

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

CREATE TABLE EMPLOYEEJTBL

(EMP_ID CHAR(9) NOT NULL,

EMP_NAME VARCHAR2(40) NOT NULL,

EMP_ST_ADDR VARCHAR2(20) NOT NULL,

EMP_CITY VARCHAR2(15) NOT NULL,

EMP_ST CHAR(2) NOT NULL,

EMP_ZIP NUMBER(5) NOT NULL,

EMP_PHONE NUMBER(10) NULL,

EMP_PAGER NUMBER(10) NULL, PRIMARY KEY (EMP_ID));

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

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

CREATE TABLE PRODUCTS (PROD_ID VARCHAR2(10) NOT NULL,

VEND_ID VARCHAR2(10) NOT NULL,

PRODUCT VARCHAR2(30) NOT NULL,

COST NUMBER(8,2) NOT NULL, PRIMARY KEY (PROD__ID, VEND_ID));

ALTER TABLE PRODUCTS "

ADD CONSTRAINT PRODUCTS_PK PRIMARY KEY (PROD_ID, VEND_ID);

Требования уникальности

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

Рассмотрим следующий пример.

CREATE TABLE EMPLOYEE_TBL

(EMP_ID CHAR(9) NOT NULL PRIMARY KEY,

EMP_NAME VARCHAR2(40) NOT NULL,

EMP_ST_ADDR VARCHAR2(20) NOT NULL,

EMP_CITY VARCHAR2(15) NOT NULL,

EMP_ST CHAR(2) NOT NULL,

EMP_ZIP NUMBER(5) NOT NULL,

EMP_PHONE NUMBER(10) NULL UNIQUE,

EMP_PAGER NUMBER(IO) NULL);

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

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

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

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

CREATE TABLE EMPLOYEE_PAY_TBL (EMP_ID CHAR(9) NOT NULL,

POSITION VARCHAP2(15) NOT NULL,

DATE_HIRE DATE NULL,

PAY_RATE NUMBER(4,2) NOT NULL,

DATE_LAST_RAISE DATE NULL,

CONSTRAINT EMP_ID_FK FOREIGN KEY (EMP_!D, REFERENCES EMPLOYEE_TBL (EMP_ID));

Столбец EMP_ID в этом примере назначается внешним ключом таблицы EMPLOYEE PAY_TBL Это! внешний ключ ссылается на столбец EMP_ID таблицы EMPLOYEE_TBL. Наличие внешнего ключа гарантирует, что для, каждого значения ЕМР ID в таблице EMFLOYEE_PAY_TBL найдется соогве!С1вующее значение EMP_ID в таблице EMPLOYEE_TBL. Такую связь называют родителъско-дочерним отношением. Родительской таблицей является таблица EMPLOYEE_TBL, а дочерней - EMPLOYEE_PAY_TBL. Чтобы лучше понять суть родительско-дочерних отношений между таблицами, рассмотрите рис. 3.2.

Рис. 3.2. Родительско-дочерние отношения между таблицами

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

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

ALTER TABLE EMPLOYEE_PAY_TBL

ADD CONSTRAINT ID_FK FOREIGN KEY (EMP_ID)

REFERENCES EMPLOYEE_TBL (EMP_ID);

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

Атрибут NOT NULL

В предыдущих примерах ключевые слова NULL и NOT NULL использовались во всех строках с определениями столбцов после указания типа данных. Атрибут NOT NULL - это ограничение, которое можно назначить столбцу в таблице. Это ограничение не позволяет оставлять столбцы пустыми. Другими словами, для столбца, помеченного как NOT NULL, требуется наличие данных во всех строках таблицы. Если атрибут NOT NULL не назначен для столбца, для такого столбца значением по умолчанию обычно является NULL, что позволяет иметь пустые, значения в столбце.

Использование условий проверки

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

Использование условий проверки показано в следующем примере.

CREATE TABLE EMPLOYEE_TBL (EMP_ID CHAR(9) NOT NULL,

EMP_NAME VARCHAR2(40) NOT NULL,

EMP_ST_ADDR VARCHAR2{20) NOT NULL,

EMP_CITY VARCHAR2(15) NOT NULL,

EMP_ST CHAR(2) NOT NULL,

EMP_ZIP NUMBER(5) NOT NULL,

EMP_PHONE NUMBER(10) NULL,

EMP_PAGER NUMBER(10) NULL), PRIMARY KEY (EMP_ID), CONSTRAINT CHK_EMP_ZIP CHECK ( EMP_ZIP = '46234' );

В этом примере условия проверки назначены столбцу EMP_ZIP и состоят в том, чтобы у всех служащих из этой таблицы был ZIP-код равный ' 46234 '. Наверное, это слишком строгое ограничение, но зато вы можете видеть, как оно работает.

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

CONSTRAINT CHK_EMP_ZIP CHECK (EMP_ZIP in ('46234','46227','46745'));

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

CREATE TABLE EMPLOYEE_PAY_TBL

(EMP_ID CHAR(9) NOT NULL,

POSITION VARCHAR2(15) NOT NULL,

DATE_HIRE DATE NULL,

PAY_RATE NUMBER(4,2) NOT NULL,

DATE_LAST_RAISE DATE NULL,

CONSTRAINT EMP_ID_FK FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEEJTBL (EMP_ID), CONSTRAINT CHK_PAY CHECK (PAY_RATE > 12.50 ) );

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

Удаление условий

Любое из назначенных условий можно удалить с помощью оператора ALTER TABLE с опцией DROP CONSTRAINT. Например, чтобы отменить назначение ключа в таблице EMPLOYEES, можно воспользоваться следующей командой.

ALTER TABLE EMPLOYEES DROP CONSTRAINT EMPLOYEES_PK;

Изменение таблицы.

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

ALTER TABLE EMPLOYEES DROP PRIMARY KEY;

Изменение таблицы.

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

Резюме

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

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

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

Вопросы и ответы

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

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

EMPLOYEE EiMP_TBL EMPLOYEE TBL EMPLOYEE^TABLE WORKER

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

Вот вам непридуманная история о молодом администраторе базы данных, удалившем таблицу. Один программист создал в рамках своей схемы таблицу с именем точно таким же, как у таблицы с производственной информацией. Прошло некоторое время и он из компании уволился. При попытке ликвидации его учетной записи оператор DROP USER вернул ошибку из-за каких-то принадлежащих программисту объектов, оставшихся в базе данных. Исследование проблемы показало, что таблица, созданная тем программистом, не нужна и по отношению к ней был применен оператор DROP TABLE.

Все прошло прекрасно, но возникла другая проблема - оказалось, что администратор применил оператор DROP TABLE, войдя в базу данных под именем производственной схемы. Как было бы хорошо, если бы администратор указал имя схемы или владельца удаляемой таблицы^1 Да, была удалена не та таблица из не той схемы. На восстановление производственной базы данных потребовалось почти восемь часов.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Будет ли работать следующий оператор CREATE TABLE? Если нет, то что нужно в нем исправить?

CREATE TABLE EMPLOYEEJTBL AS (SSN NUMBER(9) NOT NULL,

LAST_NAME VARCHAR2(20) NOT NULL

FIRST_NAME VARCHAR2(20) NOT NULL,

MIDDLE_NAME VARCHAR2(20) NOT NULL, ST ADDRESS VARCHAR2(30) NOT NULL, CITY CHAR(20) NOT NULL, STATE CHAR2) NOT

NULL, ZIP NUMBER(4) NOT NULL, DATE HIRED DATE) STORAGE

(INITIAL 3K, NEXT IK ) ;

2. Можно ли удалить столбец из таблицы?

3. Что будет, если в оператор CREATE TABLE не включить ключевое слово STORAGE?

Упражнения

1. Ознакомьтесь с Приложением В, "Операторы CREATE TABLE для примеров книги" и проанализируйте приведенные там операторы.

4-й час Процесс нормализации

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

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

Основными на этом уроке будут следующие темы.

• Что такое нормализация?

• Преимущества нормализации

• Преимущества денормализации

• Инструкции по проведению нормализации

• Три нормальные формы

• Проектирование баз данных

Нормализация баз данных

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

„Сырая" база данных

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

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

Рис. 4.1. "Сырая" база данных

Логическая организация базы данных

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

Что нужно конечному пользователю?

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

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

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

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

• Какие привилегии получит пользователь?

• Каким образом данные в базе данных должны быть сгруппированы?

• К каким данным доступ будет требоваться чаще всего?

• Как данные будут связаны?

• Какие меры следует принять для того, чтобы обеспечить правильность данных?

Избыточность данных

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

Нормальные формы

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

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

Обычно в процессе нормализации используются следующие три нормальные формы.

• Первая нормальная форма.

• Вторая нормальная форма.

• Третья нормальная форма.

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

Первая нормальная форма

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

Как видите, чтобы прийти к первой нормальной форме, база данных была разбита на несколько логических единиц, в каждой из которых определен ключ и нет повторяющихся групп. Вместо одной большой таблицы теперь имеются более простые таблицы EMPLOYEEJTBL, CUSTOMER_TBL И PRODUCTSJTBL. КЛЮЧИ В Таблицах размещаютася первыми: в данном случае это EMP_ID, CUST_ID и PROD_ID.

Вторая нормальная форма

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

Рис. 4.2. Первая нормальная форма

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

Таблица EMPLOYEE_TBL была разделена на таблицы. EMPLOYEE_TBL и EMPLOYEE_PAY_TBL. Персональная информация о служащем зависит от ключа (EMP_ID), поэтому эта информация осталась в таблице EMPLOYEE_TBL (EMP_ID,

LAST_NAME, MIDDLE_NAME, ADDRESS, CITY, STATE, ZIP, PHONE И PAGER). ОстаВШЭЯ-ся информация, которая только отчасти зависит от EMP_ID (каждого конкретного служащего), размешена в таблице EMPLOYEE_PAY_TBL (EMP_ID, POSITION,

POSITION_DESC, DATE_HIRE, PAY_RATE, DATE_LAST_RAISE). Обратите внимание на то, что обе таблицы содержат столбец EMP_ID. Для каждой из этих таблиц он является ключевым и используется для связывания данных в этих таблицах.

Таблица CUSTOMER_TBL была разделена на две таблицы, названные CUSTOMER_TBL и ORDERSJTBL. При этом было сделано то же самое, что и с таблицей EMPLOYEE_TBL. Столбцы, слабо зависящие от ключа, были выделены в отдельную таблицу. Информация о заказах клиента зависит от CUST_ID, но не зависит напрямую от общей информации о клиенте из исходной таблицы.

Третья нормальная форма

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

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

Рис. 4.3. Вторая нормальная форма

Соглашения о присвоении имен

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

Преимущества нормализации

Нормализация имеет целый ряд. преимуществ. Среди них отметим следующие.

• Лучшая общая организация базы данных.

• Сокращение числа ненужных повторений данных.

• Согласованность данных внутри базы данных.

• Более гибкая структура базы данных.

• Эффективные возможности обеспечения безопасности и надежности базы данных.

Рис, 4.4. Третья нормальная форма Процесс нормализации улучшает организацию базы данных, облегчая работу с базой данных всем, начиная от простых пользователей до администратора, который отвечает за общее управление объектами базы данных. Уменьшается число повторений данных, что упрощает структуру данных и экономит дисковое пространство. Из-за сокращения дублирования данных уменьшается вероятность их несогласованности. Например, в одной таблице имя персоны может храниться в виде STEVE SMITH, а в другой - STEPHEN R. SMITH. Поскольку в результате нормализации база данных разделяется на ряд более мелких таблиц, модифицировать существующие структуры становится проще. Гораздо проще изменить небольшую таблицу с малым количеством данных, чем большую таблицу, содержащую все жизненно важные для базы данных значения. Наконец, повышается безопасность в том смысле, что администратор базы данных получает возможность разрешить различным пользователям доступ только к ограниченному списку таблиц. Нормализация упрощает управление безопасностью.

Целостность данных - это гарантия согласованности и надежности данных в базе данных.

Ссылочная целостность

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

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

КЛЮЧОМ, ССЫЛаЮЩИМСЯ на CUST_ID ТабЛИЦЫ CUSTOMER_TBL.

Недостатки нормализации

Хотя большинство успешно работающих баз данных в некоторой степени нормализованы, нормализация имеет один существенный недостаток: замедление работы базы данных. Выполнение запроса или транзакции предполагает использование центрального процессора компьютера, памяти и операций ввода-вывода. Попросту говоря, в нормализованной базе данных для выполнения транзакций или запросов более интенсивно используется центральный процессор, требуется больше памяти и большее число операций ввода-вывода, чем в ненормализованной. В нормализованной базе данных требуется находить соответствующие таблицы и связывать данные для того, чтобы извлечь нужную информацию или обработать ее. Более подробно вопросы производительности баз данных обсуждаются в ходе урока 18, "Управление доступом к базе данных".

Денормализация базы данных

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

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

Резюме

Относительно структуры базы данных необходимо принять непростое решение: нормализовать или не нормализовать - вот в чем вопрос. Всегда имеет смысл до некоторой степени нормализовать базу данных. Но насколько можно нормализовать базу данных без заметного ухудшения производительности? Ответ на этот вопрос зависит от конкретного приложения. Насколько велика база данных? Каковы ее цели и задачи? Кто будет ее использовать?

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

Вопросы и ответы

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

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

Мне кажется, что нормализация все же предпочтительнее денормализации. Разве не так?

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Верно ли следующее утверждение: "Нормализация - это процесс группировки данных в логически связанные группы?"

2. Верно ли следующее утверждение: "Отсутствие повторяющихся и избыточных данных и, таким образом, нормализация базы данных - в любом случае лучше всего?"

3. Верно ли следующее утверждение: "Если данные находятся в третьей нормальной форме, они автоматически находятся и в первой, и во второй нормальной формах?"

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

5. Каковы основные недостатки денормализации?

Упражнения

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

Служащие:

Анжела Смит, секретарь, 317-545-6789, просп. Широкий, 1, п. я. 73, Гринс-бург, шт. Индиана, 47890, $9,50 в час, приступила к работе 22 января 1996 г., идент. код 323149669.

Джек Ли Нельсон, продавец, ул. Главная, 3334, Браунсбург, шт. Индиана, 45687, 317-852-9901, $35000 в год, идент. код 312567342, работает с 28.10.95. Клиенты:

Дичь и охотничьи аксессуары Роберта, просп. Лафайет, 5612, Индианапо-лис, шт. Индиана, 46224, 317-291-7888, код клиента 432А.

Молочный бар Рида, 10-я Западная улица, Индианаполис, шт. Индиана, 46245, 317-271-9823, код клиента 117А.

Заказы:

Код клиента 117А, дата последнего заказа 20 декабря 1999 г., заказанный товар - салфетки, код товара - 661.

5-й час Манипуляция данными

На этом уроке вы ознакомитесь с той частью SQL, которая называется языком манипуляций данными (Data Manipulation Language - DML). DML является частью SQL, используемой при изменении данных и таблиц в реляционных базах данных

Основными на этом уроке будут следующие темы.

• Обзор языка манипуляций данными

• Инструкции по манипуляции данными в таблицах

• Концепции, лежащие в основе размещения данных в таблицах

• Удаление данных из таблиц

• Изменение данных в таблицах

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

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

В SQL имеется три основных команды DML.

INSERT UPDATE DELETE

Команда SELECT, которую тоже можно использовать с командами DML, будет обсуждаться подробно в ходе урока 7, "Знакомство с запросами".

Заполнение таблиц новыми данными

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

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

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

Ввод данных в таблицу

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

insert into имя схемы.имя таблицы

VALUES ('значение!', 'значение2', [ NULL ] );

Согласно представленному здесь синтаксису оператора INSERT, в список VALUES вы должны поместить значения для всех столбцов соответствующей таблицы. Значения в списке разделяются запятыми. Символьные значения и значения дат должны быть заключены в кавычки. Для числовых значений и пустых значений, задаваемых ключевым словом NULL, кавычки не нужны. Должны быть указаны значения для всех столбцов таблицы.

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

Структура таблицы:

products_tbl

Имя столбца Null? Тип данных

PROD_ID NOT NULL VARCHAR2(10)

PROD_DESC NOT NULL VARCHAR2(25)

COST NOT NULL NUMBER(6,2)

Пример использования оператора INSERT:

INSERT INTO PRODUCTSJTBL

VALUES ('7725','КОЖАНЫЕ ПЕРЧАТКИ',24.99);

1 строка создана.

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

Имя столбца

Null?

Тип данных

PROD ID PROD DESC COST

NOT NULL

NOT NULL

NOT NULL

VARCHAR2 (10)

VARCHAR2 (25)

NUMBER (6, 2)

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

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

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

INSERT INTO EMPLOYEE_TBL

(EMP_ID, LAST_NAME, FIRST_NAME, MIDDLE_NAME, ADDRESS, CITY, STATE, ZIP, PHONE) VALUES

('123456789','SMITH', 'JOHN', 'JAY', •12 BEACON ST', •INDIANAPOLIS', 'IN', '46222', '3172996868');

1 строка создана

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

INSERT INTO ИМЯ_СХЕМЫ.ИМЯ_ТАБЛИЦЫ ('СТОЛБЕЦ!', 'СТОЛБЕЦ2') VALUES ('ЗНАЧЕНИЕ!', 'ЗНАЧЕНИЕ2');

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

Структура таблицы:

ORDERSJTBL

Имя столбца Null? Тип данных

ORD_NUM NOT NULL VARCHAR2(10)

CUST_ID NOT NULL VARCHAR2(10)

PROD_ID NOT NULL VARCHAR2(10)

QTY NOT NULL NUMBER(4)

ORD_DATE DATE

Пример использования оператора INSERT:

insert into orders_tbl (ord_num,cust_id,prod_id,qty)

VALUES ('23A16',409','7725',2);

1 строка создана.

Здесь после имени таблицы в скобках указан список столбцов. Это список всех столбцов, в которые вводятся данные. В данном случае в списке нет только столбца ORD_DATE. Из определения таблицы видно, что столбец ORD_DATE не требует обязательного наличия данных в каждой строке, поскольку в определении таблицы для этого столбца не указано NOT NULL. NOT NULL означает, что пустые значения для столбца не допускаются. Порядок в списке значений должен соответствовать порядку ввода значений в таблицу, задаваемому списком столбцов.

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

Ввод данных из другой таблицы

В таблицу можно вводить данные, полученные в результате запроса к другой таблице, воспользовавшись комбинацией операторов INSERT и SELECT. Коротко говоря, запрос - это обращение к базе данных, имеющее целью получение данных. О запросах будет идти речь в ходе урока 7. Запрос можно сравнить с вопросом пользователя к базе данных, а возвращенные данные - с полученным ответом. Если скомбинировать операторы INSERT и SELECT, имеется возможность ввести в таблицу данные, полученные в результате запроса.

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

insert into имя_схемы.имя_таблицы [('столбец!', 'столбец2')] select [*|('столбец!', 'столбец2')] from имя_таблицы

[where условия] ;

Здесь вы видите три новых ключевых слова SELECT, FROM и WHERE. SELECT является основной командой для построения запросов в SQL. С помощью FROM в запросе указываются имена таблиц, в которых необходимо отыскать данные. С помощью WHERE в запросах задаются условия, определяющие суть запроса. Таким условием может быть, например, WHERE NAME = 'SMITH'. Использование этих трех ключевых слов подробно обсуждается в ходе уроков 7 и 8.

Условие - это способ задания критериев отбора данных, осуществляемого оператором SQL.

В следующем примере используется простой запрос, чтобы увидеть все данные таблицы PRODUCTS_TBL. Здесь SELECT * говорит серверу базы данных, что необходимо получить информацию из всех столбцов таблицы. А отсутствие ключевого слова WHERE означает, что необходимо показать все записи таблицы.

select * from products_tbl;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

2345 ПОЛОЧКА ИЗ ДУБА 59.99

11 строк выбраны.

Теперь данные, полученные в результате этого запроса, введем в таблицу PRODUCTS TMP. Вы увидите, что в этой временной таблице будут созданы 11 строк.

INSERT INTO PRODUCTSJTMP

SELECT * FROM PRODOCTS_TBL;

11 строк создано,

Результат следующего запроса показывает все данные только что созданной таблицы PRODUCTSJTMP.

SELECT * FROM PRODUCTSJTMP;

PROD_ID PROD_DESC COST

Ц235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14-5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1-45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

1234 ЦЕПОЧКА ДПЯ КЛЮЧЕЙ 5.95

2345 ПОЛОЧКА ИЗ ДУБА 59.99

11 строк выбраны.

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

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

Синтаксис оператора для ввода значения NULL следующий.

insert into имя_схемы.имя_таблицы

values ('значение!', NULL, 'значениеЗ'};

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

Рассмотрим следующие два примера.

INSERT INTO ORDERS_TBL

(ORD_NUM,CUST_ID,PROD_ID,QTY,ORD_DATE) VALUES ('23A16','109','7725',2,NULL);

1 строка создана.

Здесь в списке столбцов перечислены все столбцы таблицы ORDERS_TBL. В столбец ORD_DATE вводится значение NULL, означающее, что дата заказа в данный момент либо не известна, либо не доступна.

INSERT INTO ORDERSJTBL

VALUES ('23A16',409','7725',2, 1');

1 строка создана.

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

Обновление уже имеющихся данных

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

Обновление значений одного столбца

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

update имя_таблицы

set имя_столбца = 'значение'

[where условие];

В следующем примере значение столбца QTY таблицы ORDERS_TBL устанавливается равным 1 для записи с ORD_NUM, равным '23А16' (последнее специфицируется с помощью ключевого слова WHERE).

UPDATE ORDERS_TBL

SET QTY

WHERE ORD_NUM = '23A16';

I строка обновлена.

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

UPDATE ORDERSJTBL SET QTY = 1;

11 строк обновлены.

Как видите, здесь было обновлено 11 строк. В данном случае значение столбца QTY было установлено равным 1 для всех строк таблицы ORDERS_TBL. Вы действительно хотели получить такой результат? В отдельных случаях это может быть и так, но на самом деле оператор UPDATE без ключевого слова WHERE используется исключительно редко.

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

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

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

update имя_таблицы

set столбец! = 'значение'

[, столбецЗ = 'значение']

[, столбецЗ = 'значение'] [where условие];

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

UPDATE ORDERSJTBL

SET QTY = 1,

CUST_ID = '221' WHERE ORD_NUM = '23A16';

1 строка обновлена.

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

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

Удаление данных из таблиц

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

Чтобы удалить одну или несколько записей из таблицы, используйте следующий синтаксис оператора DELETE.

delete from имя_схемы.имя_таблицы

[where условие];

DELETE FROM ORDERS_TBL

WHERE ORD_NUM = '23A16';

1 строка удалена.

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

DELETE FROM ORDERS_TBL; 11 строк удалены.

Если ключевое слово WHERE в операторе DELETE опущено, будут удалены все строки таблицы. Поэтому примите за правило всегда использовать ключевое слово WHERE в операторе DELETE.

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

Резюме

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

Очень важные уроки общения с базами данных можно получить, если пренебречь внимательным отношением к ключевому слову WHERE. С помощью ключевого слова WHERE в операторах SQL задаются условия отбора, в частности, в операторах UPDATE и DELETE с его помощью определяются строки данных, которые будут обрабатываться в ходе транзакции. При отсутствии ключевого слова WHERE будут обработаны все строки, что для базы данных может оказаться разрушительным. Защитите свои данные, и будьте внимательны при работе с данными.

Вопросы и ответы

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

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

Является ли использование оператора INSERT единственным способом ввода данных в таблицу?

Нет, просто оператор INSERT определяется стандартом ANSI. Различные реализации SQL предлагают свои средства для ввода данных в таблицы. Например, в Oracle имеется утилита SQL*Loader. Многие реализации SQL для ввода данных имеют утилиту под названием IMPORT. На рынке имеется множество книг, в которых эти утилиты описываются в деталях.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Используйте таблицу EMPLOYEEJTBL с заданной ниже структурой.

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

a insert into employee_tbl '('JACKSON', 'STEVE', '313546078', '3178523443');

б insert into employee_tbl values

('JACKSON^1, 'STEVE', '313546078', '3178523443');

В insert into employee_tbl values

('MILLER', 'DANIEL', '230980012', NULL);

r insert into employee_tbl values

('TAYLOR', NULL, '445761212', '3179221331');

д. delete from employee_tbl;

e. delete from employee_tbl "where last_name = 'SMITH';

X. delete from employee_tbl where last_name = 'SMITH' and first_name = 'JOHN';

з. update employee_tbl

set last_name = 'CONRAD';

и. update employee_tbl

set last_name = 'CONRAD'

where last_name = 'SMITH';

K. update employee_tbl

set last_name = 'CONRAD', first_name = 'LARRY';

Л. update employee_tbl

set last_name = 'CONRAD' first_name = 'LARRY' where ssn = '313546078';

Упражнения

1. Ознакомьтесь с Приложением Г, "Операторы INSERT для данных в примерах книги". Выполните операторы INSERT для заполнения данными тех таблиц, которые были созданы в результате выполнения задания упражнения 1 урока 3. После этого вам будет легче разбираться в примерах и упражнениях книги.

2. Используйте таблицу EMPLOYEE_TBL с заданной ниже структурой.

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

а. Измените SSN для служащего по имени Billy Pierce на 310239857.

б. Добавьте информацию о служащем по имени Ben Moore, тел. 317-5649880, SSN равен 313456789.

в Служащий по имени John Smith уволился, удалите соответствующую запись.

6-й час Управление транзакциями

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

Основными на этом уроке будут следующие темы.

• Определение транзакции

• Команды, используемые для управления транзакциями

• Синтаксис команд для осуществления транзакций и примеры

• Когда следует использовать команды управления транзакциями?

• Последствия недостаточно активного управления транзакциями

Что такое транзакция?

Транзакция - это набор действий, выполняемых по отношению к базе данных и рассматриваемый как единое целое. Транзакции являются единицами активности или, иначе, последовательностями действий, выполняемыми в своем логическом порядке. Они могут выполняться как вручную, так и в автоматическом режиме с помощью соответствующих программ. В реляционных базах данных, управляемых с помощью SQL, транзакции осуществляются с помощью команд DML (INSERT, UPDATE и DELETE), уже обсуждавшихся в ходе урока 5, "Манипуляция данными". Транзакция представляет собой внесение в базу данных некоторых изменений. Например, вы осуществляете транзакцию, когда для изменения информации об имени персоны выполняете оператор UPDATE по отношению к соответствующей таблице.

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

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

• Каждая транзакция имеет начало и конец.

• Любую транзакцию можно либо сохранить, либо отменить.

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

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

Что такое управление транзакциями?

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

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

Управление транзакциями осуществляется с помощью следующих трех команд:

• COMMIT

• ROLLBACK

• SAVEPOINT Все они подробно обсуждаются в следующих разделах.

Команды управления транзакциями используются только с командами DML INSERT, UPDATE и DELETE. Например, оператор COMMIT не используется для подтверждения создания таблицы. При создании таблицы операция ее создания подтверждается автоматически. Точно так же нельзя с помощью команды ROLLBACK вернуть таблицу, только что удаленную из базы данных.

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

Команда COMMIT

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

Рис. 6.1. Область изменений, допускающих отмену Синтаксис команды следующий.

COMMIT [ WORK ];

Здесь обязательным является только ключевое слово COMMIT вместе с зависящим от реализации символом или командой, означающей завершение оператора. Ключевое слово WORK абсолютно необязательно - его единственной целью является придание команде более понятного вида.

Начнем с выбора всех данных из таблицы PRODUCTS_TMP.

SELECT * FROM PRODUCTS_TMP;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

2345 ПОЛОЧКА ИЗ ДУБА 59.99

11 строк выбраны. Затем удалим из таблицы все записи для товаров, стоимость которых меньше $14,00.

DELETE FROM PRODUCTSJTMP

WHERE COST < 14;

8 строк удалено.

Для того чтобы передать базе данных изменения, проведенные транзакцией, применяется оператор COMMIT:

COMMIT;

Передача выполнена.

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

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

Команда ROLLBACK

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

Синтаксис команды ROLLBACK следующий.

rollback [ work ] ;

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

В следующем примере сначала выберем все записи из таблицы PRODUCTS_TMP, оставшиеся в ней после удаления 8 записей.

SELECT * FROM PRODUCTS_TMP;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

90 ФОНАРИ 14.5

2345 ПОЛОЧКА ИЗ ДУБА 59.99

3 строки выбраны.

Затем изменим таблицу, приписав стоимость $39.99 товару с кодом 11235.

UPDATE PRODUCTS_TMP

SET COST = 39.99 WHERE PROD_ID = "11235';

1 строка обновлена.

Запрос к таблице покажет, что изменения как будто бы внесены. SELECT * FROM PRODUCTS_TMP;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 39.99

90 ФОНАРИ 14.5

2345 ПОЛОЧКА ИЗ ДУБА 59.99

3 строки выбраны. Теперь используем команду ROLLBACK, чтобы отменить последние изменения.

ROLLBACK;

Отмена выполнена.

Наконец, проверим, что изменения не были переданы базе данных.

SELECT * FROM PRODUCTS_TMP;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

90 ФОНАРИ 14.5

2345 ПОЛОЧКА ИЗ ДУБА 59.99

3 строки выбраны.

Команда SAVE POINT

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

SAVEPOINT ИМЯ_ТОЧКИ_ОТКАТА;

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

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

Команда ROLLBACK TO SAVEPOINT

Команда возврата к точке отката имеет следующий синтаксис.

ROLLBACK TO ИМЯ_ТОЧКИ_ОТКАТА;

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

Точка отката создана.

DELETE FROM PRODUCTSJTMP WHERE PROD.ZD - '11235';

1 строка удалена.

SAVEPOINT SP2;

Точка отката создана.

DELETE FROM PRODUCTS_TMP WHERE PROD_ID - '90';

1 строка удалена.

SAVEPOINT SP3;

Точка отката создана.

DELETE FROM PRODUCTSJTMP WHERE PROD_ID - '2345';

1 строка удалена.

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

ROLLBACK SP2;

Отмена выполнена.

При откате к точке SP2 оказывается выполненным только первое удаление. SELECT * FROM PRODUCTS_TMP;

PROD_ID PROD_DESC COST

90 ФОНАРИ 14.5 2345 ПОЛОЧКА ИЗ ДУБА 59.99

2 строки выбраны.

Помните, что сама по себе команда ROLLBACK возвращает к состоянию, сложившемуся после применения последнего из операторов COMMIT или ROLLBACK. В нашем случае операторы COMMIT не применялись, поэтому будут отменены все удаления:

ROLLBACK;

Отмена выполнена.

SELECT * FROM PRODUCTS_TMP;

PPOD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

90 ФОНАРИ 14.5

2345 ПОЛОЧКА ИЗ ДУБА 59.99

3 строки выбраны.

Команда RELEASE SAVEPOINT

Команда RELEASE SAVEPOINT используется для удаления точек отката. После удаления точки отката у вас не будет возможности осуществить откат к этой точке с помощью КОМаНДЫ ROLLBACK.

RELEASE SAVEPOINT ИМЯ_ТОЧКИ_ОТКАТА;

Команда SET TRANSACTION

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

SET TRANSACTION READ WRITE; SET TRANSACTION READ ONLY;

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

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

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

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

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

Резюме

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

Не забывайте достаточно часто использовать команды COMMIT и ROLLBACK при выполнении большого числа транзакций, чтобы не вызвать переполнения доступного базе данных пространства. Не забывайте также, что команды управления транзакциями используются только с командами DML (командами INSERT, UPDATE и DELETE).

Вопросы и ответы

Обязательно ли подтверждение после каждого использования команды INSERT?

Нет, не обязательно. Если вам требуется ввести в таблицу несколько сотен тысяч строк, то команду COMMIT рекомендуется использовать после ввода каждых 5000-10000 строк, в зависимости от размера области, предназначенной для хранения временных данных. Помните, что база данных не может работать, когда эта область переполнена.

Каким образом команда ROLLBACK отменяет изменения, сделанные в результате транзакции?

Команда ROLLBACK удаляет информацию о сделанных изменениях из области с временными данными.

Допустим, при выполнении транзакции 99 % ее операторов завершились успешно, а 1 % вернули ошибки, имеется ли возможность отменить только эти ошибочные операторы?

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

Команда COMMIT делает транзакцию перманентной. Можно ли после этого изменить данные?

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

Практикум

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

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

Тесты

1. Верно ли следующее утверждение: "Если вы подтвердили несколько транзакций а затем ввели еще несколько, не подтвердив их, то в результате применения команды ROLLBACK будут отменены вообще все^транзакции, выполненные в течение данного сеанса доступа к базе данных?"

2. Верно ли следующее утверждение: "Команда SAVEPOINT сохраняет транзакции после выполнения определенного количества транзакций?"

3. Кратко охарактеризуйте назначение команд COMMIT, ROLLBACK и SAVEPOINT.

Упражнения

1. Рассмотрите следующие транзакции и создайте точки отката после каждой третьей из них. После этого подтвердите все транзакции.

transaction1;

transaction2;

transaction3;

transaction4;

transaction5,

transaction6,

transaction7;

transaction8;

transaction9;

transaction10;

transaction11;

transaction12;

7-й час Знакомство с запросами

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

Основными на этом уроке будут следующие темы

• Что такое запрос к базе данных

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

• Добавление в запрос условий с помощью ключевого слова WHERE

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

• Получение данных из таблиц других пользователей

Что такое запрос?

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

Оператор SELECT

Оператор SELECT, представляющий язык запросов к данным (Data Query Language - DQL) в SQL, используется для составления запросов к базе данных. Оператор SELECT не используется сам по себе, а требует указания некоторых параметров с помощью ключевых слов. Кроме обязательных, у этого оператора имеется несколько необязательных ключевых слов, расширяющих его возможности. Оператор SELECT является, пожалуй, одним из наиболее полезных операторов SQL. С оператором SELECT должно использоваться ключевое слово FROM, которое для этого оператора является обязательным.

Оператор SELECT состоит из выражений, строящихся на основе следующих четырех ключевых слов.

• SELECT

• FROM

• WHERE

• ORDER BY Использование этих ключевых слов будет подробно рассмотрено в следующих разделах.

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

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

Синтаксис простого оператора SELECT следующий.

SELECT [ * | ALL | DISTINCT СТОЛБЕЦ1, СТОЛБЕЦ2 ]

FROM ТАБЛИЦА1 [ , ТАБЛИЦА2 ];

За ключевым словом SELECT в запросе следует список столбцов, значения которых вы хотели бы видеть в результате запроса За ключевым словом FROM следует список таблиц, из которых должны извлекаться данные. Звездочка (*) используется для указания того, что в результате запроса должны быть показаны значения всех столбцов таблицы. По поводу ее использования обратитесь к документации той реализации SQL, с которой работаете вы. Опция ALL используется тогда, когда нужно показать все значения столбца, включая и повторяющиеся. Опция DISTINCT используется для того, чтобы повторения исключить. Из этих опций используемой по умолчанию опцией является ALL, которую поэтому указывать не обязательно. Обратите внимание на то, что имена столбцов в списке, следующем за ключевым словом SELECT, разделяются запятыми, точно так же, как имена таблиц, следующие за ключевым словом FROM.

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

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

Основные возможности оператора SELECT раскрываются в следующих примерах.

Давайте сначала выполним простой запрос по отношению к таблице PRODUCT S_TBL:

SELECT * FROM PRODUCTSJTBL;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

11 строк выбраны.

Звездочка означает выбор всех столбцов таблицы, которая, как видите, состоит из трех столбцов PROD_ID, PROD_DESC и COST. При выводе столбцы показываются в том порядке, в котором они расположены в таблице. В данной таблице 11 записей, на что указывает последняя строка вывода. Содержимое этой строки зависит от конкретной реализации SQL, например, в Oracle это будет 11 rows selected, а в другой реализации эта строка может выглядеть как 11 rows affected.

Теперь выберем данные из таблицы CANDY_TBL. Создадим эту таблицу из таблицы PRODUCTSJTBL специально для данного примера. Чтобы показать данные только одного столбца, укажем имя столбца после ключевого слова SELECT

SELECT PROD_DESC FROM CANDYJTBL;

PROD_DESC

СЛАДКАЯ КУКУРУЗА

СЛАДКАЯ КУКУРУЗА

ШОКОЛАД HERSHEYS

СНИКЕРС

4 строки выбраны.

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

SELECT ALL PROD_DESC FROM CANDYJTBL;

PROD_DESC

СЛАДКАЯ КУКУРУЗА

СЛАДКАЯ КУКУРУЗА

ШОКОЛАД HERSHEYS

СНИКЕРС

4 строки выбраны.

В следующем операторе использована опция DISTINCT, чтобы подавить вывод повторяющихся строк. Обратите внимание на то, что здесь значение СЛАДКАЯ КУКУРУЗА напечатано только один раз.

SELECT DISTINCT PROD_DESC FROM CANDYJTBL;

PROD_DESC

СЛАДКАЯ КУКУРУЗА

ШОКОЛАД HERSHEYS

СНИКЕРС

3 строки выбраны.

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

SELECT DISTINCT(PROD_DESC) FROM CAHDYJTBL;

PROD_DESC

СЛАДКАЯ КУКУРУЗА

ШОКОЛАД HERSHEYS

СНИКЕРС

3 строки выбраны.

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

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

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

FROM ТАБЛИЦА1 [ , ТАБЛИЦА2 ]

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

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

В выражении WHERE может содержаться несколько условий. Если условий несколько, они связываются операциями AND и OR, обсуждение которых предполагается в ходе урока 8, "Операции в условиях для отбора данных". Из того же урока вы узнаете об использовании логических операций, с помощью которых можно конструировать условия в запросах. В ходе данного урока мы будем рассматривать только запросы с одним условием.

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

Синтаксис оператора SELECT, использующего выражение WHERE следующий.

SELECT [ ALL | * | DISTINCT СТОЛБЕЦ!, СТОЛБЕЦ2 ] FROM ТАБЛИЦА! [ , ТАБЛИЦА2 ] WHERE [ УСЛОВИЕ! | ВЫРАЖЕНИЕ! ] [ AND УСЛОВИЕ2 | ВЫРАЖЕНИЕ2 ];

Вот простой запрос без использования ключевого слова WHERE.

SELECT *

FROM PRODUCTS_TBL;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

2345 ПОЛОЧКА ИЗ ДУБА 59.99

11 строк выбраны.

Добавим в тот же запрос условие.

SELECT * FROM PRODUCTSJTBL WHERE COST < 5;

PROD_ID PROD_DESC COST

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

5 строк выбраны.

Теперь показаны только строки с информацией о товарах стоимостью меньше $5. С помощью следующего запроса извлекается информация о товаре с кодовым номером 119.

SELECT PROD_DESC,

COST FROM PRODUCTS_TBL

WHERE PROD_ID = '119';

PROD_DESC COST

МАСКИ В АССОРТИМЕНТЕ 4.95

1 строка выбрана.

Сортировка вывода

Обычно требуется, чтобы выводимые данные были как-то упорядочены. Выводимые данные можно упорядочить с помощью выражения, связанного с ключевым словом ORDER BY. Упорядочение, задаваемое с помощью ключевого слова ORDER BY, по умолчанию будет упорядочением по возрастанию, обозначается A-Z (А-Я) в случае сортировки имен. Алфавитное упорядочение по убыванию соответствует порядку Z-А (Я-А). Для числовых значений между 1 и 9 упорядочение по возрастанию обозначается 1-9, а по убыванию - 9- 1.

Синтаксис оператора SELECT, использующего выражение ORDER BY, следующий.

SELECT [ ALL | * | DISTINCT СТОЛБЕЦ1, СТОЛБЕЦ2 ]

FROM ТАБЛИЦА1 [ , ТАБЛИЦА2 ]

WHERE [ УСЛОВИЕ1 | ВЫРАЖЕНИЕ1 ] [ AND УСЛОВИЕ2 | ВЫРАЖЕНИЕ2 ]

ORDER BY СТОЛБЕЦ1|ЦЕЛОЕ_ЗНАЧЕНИЕ [ ASC|DESC ];

Для примера использования ключевого слова ORDER BY расширим один из использовавшихся выше операторов. Отсортируем вывод по описаниям товаров в порядке возрастания (алфавитном порядке). Обратите внимание на использование опции ASC. В выражении, задаваемом ключевым словом ORDER BY, эта опция может указываться после имени каждого из столбцов.

SELECT PROD_DESC, PROD_ID, COST

FROM PRODUCTS_TBL

WHERE COST < 20

ORDER BY PROD_DESC ASC;

PROD_DESC PROD_ID COST

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 13 1.1

КОСТЮМЫ В АССОРТИМЕНТЕ 15 10

МАСКИ В АССОРТИМЕНТЕ 119 4.95

ПЛАСТИКОВЫЕ ПАУКИ 87 1.05

ПЛАСТИКОВЫЕ ТЫКВЫ 222 7.75

СЛАДКАЯ КУКУРУЗА 9 1.35

ТЫКВЕННЫЕ КОНФЕТЫ б 1.45

ФОНАРИ 90 , 14.5

8 строк выбраны.

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

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

SELECT PRODJDESC, PROD_ID, COST

FROM PRODUCTS_TBL

WHERE COST < 20

ORDER BY PROD_DESC DESC;

PROD_DESC PROD_ID COST

ФОНАРИ 90 14.5

ТЫКВЕННЫЕ КОНФЕТЫ 6 1.45

СЛАДКАЯ КУКУРУЗА 9 1.35

ПЛАСТИКОВЫЕ ТЫКВЫ 222 7.75

ПЛАСТИКОВЫЕ ПАУКИ 87 1.05

МАСКИ В АССОРТИМЕНТЕ 119 4.95

КОСТЮМЫ В АССОРТИМЕНТЕ 15 10

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 13 1.1

8 строк выбраны.

В SQL предлагаются и некоторые сокращения. Столбец, указанный в списке ключевого слова ORDER BY, можно заменить числом. ЦЕЛОЕ_ЗНАЧЕНИЕ является значением, замещающим действительное имя столбца и соответствующим порядку столбца в списке после ключевого слова SELECT. Вот пример использования числового идентификатора вместо имени столбца.

SELECT PROD_DESC,

PROD_ID,

COST FROM PRODUCTS_TBL

WHERE COST < 20

ORDER BY 1;

PROD_DESC PROD_ID COST

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 13 1.1

КОСТЮМЫ В АССОРТИМЕНТЕ 15 10

МАСКИ В АССОРТИМЕНТЕ 119 4.95

ПЛАСТИКОВЫЕ ПАУКИ 8"? 1.05

ПЛАСТИКОВЫЕ ТЫКВЫ 222 7.75

СЛАДКАЯ КУКУРУЗА 9 1.35

ТЫКВЕННЫЕ КОНФЕТЫ 6 1.45

ФОНАРИ 90 14.5

8 строк выбраны.

В этом запросе целое значение 1 представляет столбец PROD_DESC. Точно так же 2 представляет столбец PROD_ID, 3 - COST и т.д.

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

ORDER BY 1,2,3

Столбцы в выражении ORDER BY не обязательно должны быть в том же порядке, каком они указаны в списке после ключевого слова SELECT, например, как в случае ORDER BY 1,3,2

Учет регистра символов

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

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

Например, данные могут не быть согласованными, если использовать символы верхнего и нижнего регистра одновременно:

SMITH Smith smith

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

SELECT *

FROM EMPLOYEEJTBL

WHERE LAST_NAME = 'SMITH';

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

Примеры простых запросов

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

Выберем все записи в таблице и все ее столбцы.

SELECT FROM EMPLOYEEJTBL;

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

SELECT EMP_ID FROM EMPLOYEE_TBL;

При этом можно разместить весь оператор в одной строке или разделить его на несколько строк.

SELECT EMP_ID FROM EMPLOYEEJTBL;

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

SELECT EMP_ID, LAST_NAME FROM EMPLOYEEJTBL;

Отобразим данные, удовлетворяющие заданному условию.

SELECT EMP_ID, LAST_NAME

FROM EMPLOYEEJTBL

WHERE EMP_ID = '333333333';

Отобразим данные, удовлетворяющие заданному условию,'и отсортируем вывод.

SELECT EMP_ID, LAST_NAME FROM EMPLOYEEJTBL WHERE CITY = 'INDIANAPOLIS' ORDER BY EMP_ID;

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

SELECT EMP_ID, LAST_NAME

FROM EMPLOYEE_TBL

WHERE CITY = ' INDIANAPOLIS '

ORDER BY EMP_ID, LAST_NAME DESC;

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

SELECT EMP_ID, LAST_NAME FROM EMPLOYEEJTBL WHERE CITY = 'INDIANAPOLIS' ORDER BY 1;

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

SELECT EMP_ID, LAST_NAME FROM EMPLOYEEJTBL WHERE CITY = 'INDIANAPOLIS' ORDER BY 2, 1;

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

Подсчет записей в таблице

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

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

SELECT COUNT(*) FROM ИМЯ_ТАБЛИЦЫ;

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

SELECT COUNT(*) FROM PRODUCTS_TBL;

COUNT(*)

--------

9

1 строка выбрана.

Подсчитаем теперь число значений для столбца PROD_ID в таблице PRODUCTS_TBL.

SELECT COUNT(PROD_ID) FROM PRODUCTS_TBL;

COUNT(PROD_ID)

9

1 строка выбрана.

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

Получение данных из таблиц других пользователей

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

SELECT EMP_ID

FROM SCHEMA.EMPLOYEE_TBL

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

Псевдонимы столбцов

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

SELECT ИМЯ_СТОЛБЦА ПСЕВДОНИМ FROM ИМЯ_ТАБЛИЦЫ;

Использование псевдонимов иллюстрируется следующим примером с таблицей PRODUCTS_TBL. Здесь столбец с описаниями товаров отображается дважды, но второй раз столбец отображается с именем ТОВАР (обратите внимание на названия выводимых столбцов).

SELECT PROD_DESC,

PROD_DESC ТОВАР FROM PRODUCTS_TBL;

PROD_DESC ТОВАР

КОСТЮМ ВЕДЬМЫ

КОСТЮМ ВЕДЬМЫ

ПЛАСТИКОВЫЕ ТЫКВЫ

ПЛАСТИКОВЫЕ ТЫКВЫ

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

ФОНАРИ

ФОНАРИ

КОСТЮМЫ В АССОРТИМЕНТЕ

КОСТЮМЫ В АССОРТИМЕНТЕ

СЛАДКАЯ КУКУРУЗА

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ТЫКВЕННЫЕ КОНФЕТЫ

ПЛАСТИКОВЫЕ ПАУКИ

ПЛАСТИКОВЫЕ ПАУКИ

МАСКИ В АССОРТИМЕНТЕ

МАСКИ В АССОРТИМЕНТЕ

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

ПОЛОЧКА ИЗ ДУБА

ПОЛОЧКА ИЗ ДУБА

11 строк выбраны.

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

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

Резюме

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

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

Вопросы и ответы

Почему оператор SELECT не может работать без ключевого слова FROM?

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

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

Предположим, что в выражении для ORDER BY вы указали столбец last_name таблицы EMPLOYEE_TBL. При задании обратного порядка сортировки имена будут отсортированы по буквам от Z до А (и от Я до А). Но если с помощью ORDER BY вы отсортировали столбец с данными о зарплате из таблицы EMPLOYEE_PAY_TBL, то при задании обратного порядка сортировки данные будут упорядочены от самого высокого значения зарплаты до самого низкого.

В чем преимущества возможности переименования столбцов?

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Назовите обязательные составляющие оператора SELECT.

2. Для всех ли данных в выражении ключевого слова WHERE обязательно нужно использовать кавычки?

3. К какому разделу SQL относится оператор SELECT?

4. Можно ли в выражении для ключевого слова WHERE задать несколько условий?

Упражнения

1. Рассмотрите следующие операторы SELECT и выясните, являются ли они правильными с точки зрения синтаксиса. Если нет, то что в них следует исправить? Здесь использовалась таблица EMPLOYEE_TBL.

а. SELECT EMP_ID, LAST_NAME, FIRST_NAME, FROM EMPLOYEE_TBL;

6. SELECT EMP_ID, LAST_NAME ORDER BY EMP_ID FROM EMPLOYEEJTBL;

B. SELECT EMP_ID, LAST_NAME, FIRST_NAME

FROM EMPLOYEEJTBL

WHERE EMP_ID = '333333333'

ORDER BY EMP_ID;

Г. SELECT EMP_ID SSN, FIRST_NAME

FROM EMPLOYEE_TBL

WHERE EMP_ID = '333333333'

ORDER BY 1;

д. SELECT EMP_ID, LAST_NAME, FIRST_NAME FROM EMPLOYEEJTBL WHERE EMP__ID = '333333333' ORDER BY 3, 1, 2;

8-й час Операции в условиях для отбора данных

Основными на этом уроке будут следующие темы.

• Что такое операция?

• Операции в SQL

• Как использовать операции по отдельности?

• Комбинированное использование операций

Что такое операции в SQL?

Операции представляются зарезервированными словами или символами.

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

В ходе этого урока мы обсудим следующие типы операций.

• Операции сравнения

• Логические операции

• Операция отрицания

• Арифметические операции

Операции сравнения

Операции сравнения используются в операторах SQL для сравнивания отдельных значений и представляются знаками =, о, < и >. Эти операции предназначены соответственно для проверки равенства и неравенства значений, проверки выполнения отношений "меньше" и "больше" между ними. Суть операций сравнения раскрывается в следующих разделах.

Равенство

Операция проверки равенства в операторе SQL выясняет равенство одного значения другому. Для этого используется знак равенства (=). При выяснении равенства сравниваемые значения должны совпадать в точности, иначе запрос к базе данных не вернет никаких данных. Если сравниваемые значения равны, соответствующее выражение получает значение TRUE (Истина), иначе - FALSE (Ложь). Это логическое значение (TRUE/FALSE) используется системой для того, чтобы выяснить, должны ли соответствующие данные включаться в ответ запроса.

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

Пример________________________________Значение______

WHERE SALARY = '20000' Зарплата равна 20000

Следующий запрос возвращает все строки данных с PROD_ID равным 2345.

SELECT *

FROM PRODUCTSJTBL

WHERE PROD_ID = '2345';

PROD_ID PROD_DESC COST

2345 ПОЛОЧКА ИЗ ДУБА 59.99

1 строка выбрана.

Неравенство

В противоположность равенству существует неравенство. В SQL для представления проверки неравенства используется знак о (комбинация знаков "меньше" и "больше"). В этом случае условие возвращает TRUE, если обнаруживается неравенство значений, и FALSE - если равенство.

Во многих из основных реализаций SQL эквивалентом знака операции о является комбинация ' = Уточните в документации, является ли эта комбинация применимой в вашем конкретном случае.

Пример________________________________Значение________

WHERE SALARY <> '20000' Зарплата не равна 20000

SELECT *

FROM PRODUCTS_TBL

WHERE PROD_ID <> '2345';

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

10 строк выбраны.

„Меньше" и „больше"

Знаки < ("меньше") и > ("больше") можно использовать по отдельности, и в комбинации с другими операциями.

WHERE SALARY < '20000' Зарплата меньше 20000

WHERE SALARY > '20000' Зарплата больше 20000

В первом случае любое значение, меньшее 20000, вернет TRUE, а равное или большее 20000 - FALSE. Операция "больше" является противоположной к операции "меньше".

SELECT *

FROM PRODUCTS_TBL

WHERE COST > 20;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

2345 ПОЛОЧКА ИЗ ДУБА 59.99

2 строки выбраны.

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

SELECT *

FROM PRODUCTS_TBL

WHERE COST < 24.99;

PROD_ID PROD_DESC COST

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

9 строк выбраны.

Примеры комбинирования операций сравнения

Знак равенства можно комбинировать со знаками "меньше" и "больше", как в следующих примерах.

WHERE SALARY <= '20000' Зарплата меньше или равна 20000

WHERE SALARY >= '20000' Зарплата больше или равна 20000

"Меньше или равно" включает значение 20000 и все значения, меньшие 20000. Любое такое значение вернет TRUE, а любое значение, большее 20000, вернет FALSE. Подобным образом определяется "больше или равно". В данном случае, в отличие от строгих неравенств, значение 20000 возвращает TRUE.

SELECT *

WHERE COST <= 24.99;

PROD__ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 9.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

б ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

10 строк выбраны.

Логические операции

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

• IS NULL . EXISTS

• BETWEEN

• UNIQUE

• IN

• ALL И ANY

• LIKE

IS NULL

Ключевое слово is NULL используется для проверки равенства данного значения значению NULL. Например, если требуется узнать, кто из сотрудников не имеет пейджера, можно искать значения NULL в столбце PAGER таблицы EMPLOYEEJTBL.

Вот пример проверки равенства значения значению NULL.

WHERE SALARY is NULL Для зарплаты не задано значение

Вот пример, в котором значение NULL не будет найдено.

WHERE SALARY = NULL Зарплата имеет значение, равное

строке символов N-U-L-L

SELECT EMP_ID, LAST NAME, FXRST_NAME, PAGER

FROM EMPLOYEE_TBL

WHERE PAGER IS NULL;

EMP_ID LAST_NAME FIRST_NAME PAGER

311549902 STEPHENS TINA

442346889 PLEW LINDA

220984332 WALLACE MARIAH

443679012 SPURGEON TIFFANY

4 строки выбраны.

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

SELECT EMP_ID, LAST_NAME, FIRST_NAME, PAGER

FROM EMPLOYEE_TBL

WHERE PAGER = NULL;

О строк выбрано.

BETWEEN

Ключевое слово BETWEEN используется для поиска значений, попадающих в диапазон, заданный некоторыми минимальным и максимальным значениями. Эти минимальное и максимальное значения включаются в соответствующее условие.

Пример__________________________________Значение___________

WHERE SALARY BETWEEN '20000' Зарплата должна находиться в диапазоне

AND '30000' от 20000 до 30000, включая крайние значения диапазона

SELECT *

FROM PRODUCTS_TBL

WHERE BETWEEN 5.95 AND 14.5;

PROD_ID PROD_DESC COST

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

4 строки выбраны.

Обратите внимание на то, что в вывод включены крайние значения 5. 95 и 14 .5.

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

IN

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

Пример__________________________________________Значение______

WHERE SALARY IN ('20000', Зарплата должна равняться 20000, 30000 или

'30000', '40000') 40000

SELECT *

FROM PRODUCTS_TBL

WHERE PROD_ID IN <'13','9','87','119');

PROD_ID PROD_DESC COST

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

9 СЛАДКАЯ КУКУРУЗА 1.35

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

4 строки выбраны.

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

LIKE

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

• знак процента (%);

• знак подчеркивания (_).

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

Вот несколько примеров.

Пример_________________________Значение_________________

WHERE SALARY LIKE '200%' Любое значение, начинающееся с 200

WHERE SALARY LIKE ' %200% ' Любое значение, имеющее 200 в любой позиции

WHERE SALARY LIKE '_00%' Любое значение, имеющее 00 во второй и третьей

позициях WHERE SALARY LIKE ' 2_%_%' Любое значение, начинающееся с 2 и состоящее

как минимум из трех символов

WHERE SALARY LIKE '%2' Любое значение, заканчивающееся 2

WHERE SALARY LIKE '_2%3' Любое значение, имеющее 2 во второй позиции и

заканчивающееся 3

WHERE SALARY LIKE '2__3' Любое значение длиной 5 символов, начинающееся с 2 и

заканчивающееся 3

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

SELECT PROD_DESC

FROM PRODUCTS_TBL

WHERE PROD_DESC LIKE '%Ы';

PROD_DESC

КОСТЮМ ВЕДЬМЫ

ПЛАСТИКОВЫЕ ТЫКВЫ

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

ТЫКВЕННЫЕ КОНФЕТЫ

4 строки выбраны.

В следующем примере выбираются описания товаров с буквой "Ы" во второй позиции.

SELECT PROD_DESC

FROM PRODUCTS_TBL

WHERE PROD_DESC LIKE '_Ы%';

PROD_DESC

ТЫКВЕННЫЕ КОНФЕТЫ

1 строка выбрана.

EXISTS

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

Пример______________________________Значение______

WHERE EXISTS (SELECT EMP_ID Проверка наличия EMP_ID со значени-

FROM EMPLOYEE_TBL ем 333333333 в таблице EMPLOYEE_TBL

WHERE EMPLOYEE_ID = '333333333') -

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

SELECT COST

FROM PRODUCTSJTBL

WHERE EXISTS ( SELECT COST

FROM PRODUCTS_TBL

WHERE COST > 100 );

О строк выбраны.

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

SELECT COST

FROM PRODUCTSJTBL

WHERE EXISTS ( SELECT COST

FROM PRODUCTS_TBL

WHERE COST < 100 );

COST

--------

29.99

7.75

1.1

14.5

10

1.35

1.45

1.05

4.95

5.95

59.99

11 строк выбраны.

Теперь показаны цены для всех тех строк таблицы, для которых эти цены меньше 100.

UNIQUE

Ключевое слово UNIQUE используется для проверки строк заданной таблицы на уникальность (т. е. отсутствие повторений).

Пример_____________________________Значение____________

WHERE UNIQUE (SELECT SALARY Проверка SALARY на наличие повторе-

FROM EMPLOYEEJTBL ний

WHERE EMPLOYEE_ID = '333333333')

ALL И ANY

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

Пример_____________________________Значение___________

WHERE SALARY > ALL (SELECT SALARY Проверка значения SALARY на предмет

FROM EMPLOYEE_TBL превышения им всех значений зарпла-

WHERE CITY - ' INDIANAPOLIS ' ) ты служащих из Индианаполиса

SELECT *

FROM PRODUCTS_TBL

WHERE COST > ALL ( SELECT COST

FROM PRODUCTS_TBL

WHERE COST < 10 );

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

2345 ПОЛОЧКА ИЗ ДУБА 59.99

4 строки выбраны.

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

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

Пример___________________________________Значение___________

WHERE SALARY > ANY (SELECT SALARY Проверка значения SALARY на Пред-

FROM EMPLOYEE_TBL мет превышения им какого-нибудь из

WHERE CITY = 'INDIANAPOLIS') значений зарплаты для служащих из

Индианаполиса

SELECT *

FROM PRODUCTS_TBL

WHERE COST > ANY ( SELECT COST

FROM PRODUCTS_TBL

WHERE COST < 10 );

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

119 МАСКИ В АССОРТИМЕНТЕ 4.95

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

2345 ПОЛОЧКА ИЗ ДУБА 59.99

10 строк выбраны.

Этот запрос возвращает больше строк, чем предыдущий запрос с использованием ALL, поскольку в данном случае стоимость должна превышать стоимость какого-нибудь товара стоимостью, меньшей 10. Единственной не показанной записью оказалась запись для товара стоимостью 1.05, для которого не нашлось товара с меньшей стоимостью из тех, что стоят меньше 10.

Операции конъюнкции и дизъюнкции

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

AND

Ключевое слово AND позволяет связать логическим умножением два условия в выражении ключевого слова WHERE. Чтобы оператор SQL, представляющий транзакцию или запрос, выполнил заданное действие, оба связанные ключевым словом AND условия должны возвратить TRUE.

Пример_________________________________Значение______________

WHERE EMPLOYEE_ID = '333333333' Значение EMPLOYEE_ID должно быть

AND SALARY = '20000' равным 333333333, а значение SALARY

должно быть равным 20000

SELECT *

FROM PROOCTS_TBL

WHERE COST > 10

AND COST < 30;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

90 ФОНАРИ 14.5

2 строки выбраны.

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

SELECT *

FROM PRODUCTS_TBL

AND PROD_ID = '2345';

О строк выбраны.

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

OR

Ключевое слово OR позволяет связать логическим сложением условия в выражении ключевого слова WHERE. Чтобы оператор SQL, представляющий транзакцию или запрос, выполнил заданное действие, хотя бы одно из связанных ключевым словом AND условий должно возвратить TRUE.

Пример______________________Значение___________________

WHERE SALARY = ' 20000 ' Значение SALARY должно быть равным ли-

OR SALARY = '30000' бо 20000, либо 30000

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

SELECT *

FROM PRODUCTS_TBL

WHERE PROD_ID = '7725'

OR PROD_ID = '2345';

PROD_ID PROD_DESC COST

2345 ПОЛОЧКА ИЗ ДУБА 59.99

1 строка выбрана.

В данном случае для внесения данных в результат запроса хотя бы одно из условий должно возвратить TRUE. Найдена одна подходящая запись.

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

В следующем примере использовано одно ключевое слово AND и два OR. Обратите внимание на размещение скобок.

SELECT *

FROM PRODUCTS_TBL

WHERE COST >10

AND ( PROD_ID = '222'

OR PROD_ID = '90'

OR PROD_ID = '11235' ) ;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

90 ФОНАРИ 14.5

2 строки выбраны.

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

Отрицание условий с помощью операции отрицания

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

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

• NOT BETWEEN

• IS NOT NULL

• NOT IN

• NOT EXISTS

• NOT LIKE

• NOT UNIIQUE

Все эти возможности будут рассмотрены в следующих разделах.

Неравенство

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

Пример_________________________Значение____________

WHERE SALARY о '20000' Зарплата не равна 20000

WHERE SALARY != '20000' Зарплата не равна 20000

Во втором случае для отрицания равенства используется восклицательный знак. В некоторых реализациях SQL в дополнение к стандартному знаку неравенства о используется восклицательный знак ! в совокупности со знаком = как отрицание равенства.

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

NOT BETWEEN

Отрицание операции BETWEEN используется следующим образом.

Пример_____________________Значение___________________

WHERE SALARY NOT BETWEEN Зарплата не должна находиться в диапазоне от

'20000' AND '30000' 20000 до 30000, включая крайние значения

диапазона

SELECT *

FROM PRODUCTS_TBL

WHERE NOT BETWEEN 5.95 AND 14.5;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

2345 ПОЛОЧКА ИЗ ДУБА 59.99

7 строк выбраны.

Не забывайте о том, что BETWEEN предполагает включение в рассмотрение границ диапазона. Именно поэтому в данном примере строки со значениями 5.95 и 14 .5 выведены не были.

NOT IN

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

Пример________________________________Значение______

WHERE SALARY NOT IN ('20000', Зарплата не должна равняться 20000, 30000

'30000', '40000') или 40000

SELECT *

FROM PRODUCTSJTBL

WHERE PROD_ID NOT IN (•13','9•,'87','119');

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

2345 ПОЛОЧКА ИЗ ДУБА 59.99

7 строк выбраны.

В данном случае не показаны строки для товаров с кодами из списка, указанного после NOT IN.

NOT LIKE

Ключевое слово NOT LIKE является отрицанием операции подстановки LIKE для нахождения значений, не похожих на заданное. Вот несколько примеров.

Пример___________________________________Значение __________________

WHERE SALARY NOT LIKE '200%' Любое значение, не начинающееся с 200

WHERE SALARY NOT LIKE '%200%' Любое значение, не имеющее 200 ни в какой

позиции

WHERE SALARY NOT LIKE '_00%' Любое значение, не имеющее 00 во второй и

третьей позициях

WHERE SALARY NOT LIKE '2_%_%' Любое значение, не начинающееся с 2 и

состоящее как минимум из трех символов

SELECT PROD_DESC

FROM PRODUCTS_TBL

WHERE PROD_DESC NOT LIKE 'П%';

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

119 МАСКИ В АССОРТИМЕНТЕ 4.95

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

8 строк выбраны. В этом примере выбираются описания товаров, не начинающиеся на букву "П".

IS NOT NULL

Ключевое слово IS NOT NULL обозначает отрицание операции is NULL и используется, когда нужно убедиться, что заданное значение не является пустым.

Пример__________________________Значение____________________

WHERE SALARY is NOT NULL Выбрать только строки с непустыми значениями.

SELECT EMP_XD, LAST_NAME, FIRST_NAME, PAGER

FROM EMPLOYEEJTBL

WHERE PAGER IS NOT NULL;

EMP_ID LAST_NAME FIRST_NAME PAGER

213764555 GLASS BRANDON 3175709980

313782439 GLASS JACOB 8887345678

2 строки выбраны.

NOT EXISTS

Ключевое слово NOT EXISTS используется как отрицание EXISTS.

Пример___________________________Значение_________________

WHERE NOT EXISTS (SELECT EMP_ID Проверка отсутствия ЕМР ID со зна

FROM EMPLOYEE TBL чением 333333333333 в таблице

WHERE EMPLOYEE_ID = -333333333') EMPLOYEE_TBL

SELECT MAX(COST)

FROM PRODUCTS_TBL

WHERE NOT EXISTS ( SELECT COST

FROM PRODOCTS_TBL

WHERE COST > 100 ) ;

MAX(COST)

---------

59.99

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

NOT UNIQUE

Ключевое слово NOT UNIQUE используется как отрицание UNIQUE.

Пример_____________________________________Значение______

WHERE NOT UNIQUE (SELECT SALARY Проверка SALARY на наличие неуни-

FROM EMPLOYEE_TBL) кальных значений

Арифметические операции

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

• + (сложение);

• * (умножение);

• - (вычитание);

• / (деление).

Сложение

Сложение представлено знаком "+".

Пример_____________________________Значение__________________

SELECT SALARY + BONUS Значение SALARY складывается со значе-

FROM EMPLOYEE_PAY_TBL; нием BONUS для каждой строки данных

SELECT SALARY FROM EMPLOYEE_PAY_TBL Выбор строк, ДЛЯ которых сумма

WHERE SALARY + BONUS > '40000'; SALARY И BONUS Превышает 40000

Вычитание

Вычитание представлено знаком "-".

Пример________________________Значение________________

SELECT SALARY - BONUS Значение BONUS вычитается из зна-

FROM EMPLOYEE_PAY_TBL; чения SALARY

SELECT SALARY FROM EMPLOYEE_PAY_TBL Выбор строк, для которых разность

WHERE SALARY - BONUS > '40000'; SALARY И BONUS Превышает 40000

Умножение

Умножение представлено знаком "*".

Пример_______________________Значение_______________________

SELECT SALARY * 10 Значение SALARY умножается на 10

FROM EMPLOYEE_PAY_TBL;

SELECT SALARY FROM EMPLOYEE_PAY_TBL Выбор строк, для которых значение

WHERE SALARY * 10 > '40000',- SALARY, умноженное на 10, превышает

40000

В следующем примере текущее значение зарплаты умножается на 1.1, что означает увеличение на 10%.

SELECT EMP_ID, PAY_RATE, PAY_RATE * 1.1

FROM EMPLOYEE_PAY_TBL

WHERE PAY_RATE IS NOT NULL;

EMP_ID PAY_RATE PAY_RATE*1.1

44234688Э 14.75 16.225

220984332 11 12.1

443679012 15 16.5

3 строки выбраны.

Деление

Деление представлено знаком "/" (косой чертой).

Пример________________________________Значение_______

SELECT SALARY /10 Значение SALARY делится на 10

FROM EMPLOYEE_PAY_TBL;

SELECT SALARY FROM EMPLOYEE_PAY_TBL Выбор строк, для которых значение

WHERE SALARY / 10 > '40000'; SALARY, деленное на 10, превышает 40000

Комбинирование арифметических операций

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

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

Выражение___________Результат___________

1 + 1*5 6

(1 + 1) * 5 10

10-4/2+1 9

(10 - 4) / (2 + 1) 2

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

Выражение___________Результат_________

4*6/2 12

(4 * 6) / 2 12

4 * (6 / 2) 12

Вот еще несколько примеров.

SELECT SALARY * 10 + 1000

FROM EMPLOYEE_PAY_TBL

WHERE SALARY > 20000;

SELECT SALARY / 52 + BONUS

FROM EMPLOYEE_PAY_TBL;

SELECT (SALARY - 1000 + BONUS) / 52 * 1.1

FROM EMPLOYEE_PAY_TBL;

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

SELECT SALARY

FROM EMPLOYEE_PAY_TBL

WHERE SALARY < BONUS *3+10/2-50;

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

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

Резюме

Вы ознакомились с примерами использования различного типа операций в SQL. Вы узнали, что операции могут использоваться по отдельности и в комбинации одна с другой, включая и операции конъюнкции и дизъюнкции AND и OR. Вы рассмотрели основные арифметические операции - сложение, вычитание, умножение и деление. Операции сравнения используются для проверки равенства, неравенства, отношений "больше" и "меньше". К логическим операциям относятся BETWEEN, IN, LIKE, EXIST, ANY и ALL. Вы уже должны знать, как добавить элементы в условия, заданные в операторах SQL, чтобы извлечь из базы данных именно те данные, которые вам нужны.

Вопросы и ответы

Можно ли иметь несколько ключевых слов AND в выражении, заданном ключевым словом WHERE?

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

SELECT SALARY

FROM EMPLOYEE_PAY_TBL

WHERE SALARY > 20000

AND BONUS BETWEEN 1000 AND 3000

AND POSITION = 'VICE PRESIDENT';

Что будет, если в выражении ключевого слова WHERE поместить некоторое значение типа NUMBER в кавычки?

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты пред-нззнзчены для проверки общего уровня понимания рассмотренного материзлз. Упрзжнения дзют возможность применить нз прзктике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Верно ли следующее утверждение: "При использовании ключевого слова OR оба условия должны возвращэть TRUE?"

2. Верно ли следующее утверждение: "При использовании ключевого слова IN данное значение должно совпадать со всемиуказанными в списке?"

3. Верно ли следующее утверждение: "Ключевое слово AND можно использовать в выражениях ключевых слов SELECT и WHERE?"

4. Какие ошибки (если они есть вообще) допущены в следующих операторах SELECT?

а. SELECT SALARY

FROM EMPLOYEE_PAY_TBL

WHERE SALARY BETWEEN 20000, 30000;

6. SELECT SALARY + DATE_HIRE FROM EMPLOYEE_PAYJTBL;

B. SELECT SALARY, BONUS FROM EMPLOYEE_PAY_TBL WHERE DATE_HIRE BETWEEN 22-SEP-99 AND 23-NOV-99 AND POSITION = 'ПРОДАЖА' OR POSITION = 'МАРКЕТИНГ' AND EMPLOYEE_ID LIKE '%55%;

Упражнения

1. Рассмотрите следующую таблицу CUSTOMERJTBL.

DESCRIBE CUSTQMER_TBL

Имя NULL? Тип

CUST_ID NOT NULL VARCHAR2(10)

CUST_NAME NOT NULL VARCHAR2(30)

CUST_ADDRESS NOT NULL VARCHAR2(20)

CUST_CITY NOT NULL VARCHAR2(12)

CUST_STATE NOT NULL CHAR(2)

CUST_ZIP NOT NULL CHAR(5)

CUST_PHONE NUMBER(10)

CUST_FAX NUMBER(10)

Запишите оператор SELECT, возвращающий коды клиентов (CUST_ID) и их имена (CUST_NAME), отсортированные по алфавиту, для клиентов с именами на "А" и "В", проживающих в штатах Индиана, Огайо, Мичиган и Иллинойс,

2. Рассмотрите следующую таблицу PRODUCTSJTBL.

DESCRIBE PRODUCTS_TBL

Имя NULL? Тип

PROD_ID NOT NULL VARCHAR2(10)

PROD_DESC NOT NULL VARCHAR2(25)

COST NOT NULL NUMBER(6,2)

Запишите оператор SELECT, возвращающий коды товара (PROD_ID), описание товара (PROD_DESC) и цену товара (COST). Ограничьте цену товара диапазоном от $1.00 до $12.50.

9-й час Подведение итогов по данным запроса

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

Основными на этом уроке будут следующие темы.

• Что такое функции?

• Использование функций

• Когда следует использовать функции?

• Использование итоговых функций

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

• Результаты использования функций

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

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

В ходе этого урока мы обсудим следующие итоговые функции.

• COUNT

• SUM

• MAX

• MIN

• AVG

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

SELECT *

FROM PRODUCTS_TBL;

PROD_ID PROD_DESC COST

11235 КОСТЮМ ВЕДЬМЫ 29.99

222 ПЛАСТИКОВЫЕ ТЫКВЫ 7.75

13 ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 1.1

90 ФОНАРИ 14.5

15 КОСТЮМЫ В АССОРТИМЕНТЕ 10

9 СЛАДКАЯ КУКУРУЗА 1.35

6 ТЫКВЕННЫЕ КОНФЕТЫ 1.45

87 ПЛАСТИКОВЫЕ ПАУКИ 1.05

119 МАСКИ В АССОРТИМЕНТЕ 4.95

1234 ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 5.95

2345 ПОЛОМКА ИЗ ДУБА 59.99

11 строк выбраны.

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

SELECT EMP_ID, LAST_NAME, FIRST_NAME, PAGER

FROM EMPLOYEE_TBL;

EKP_ID LAST_NAME FIRST_NAME PAGER

311549902 STEPHENS TINA

4423468b9 PLEW LINDA

213764555 GLASS BRANDON 3175709980

313782439 GLASS JACOB 8887345678

220984332 WALLACE MARIAH

443679012 SPURGEON TIFFANY

6 строк выбраны.

Функция COUNT

Функция COUNT используется для подсчета строк или значений в столбце, отличных от значения NULL При использовании в запросах функция COUNT возвращает числовое значение. При использовании с опцией DISTINCT функция COUNT посчитает только разные строки (т. е строки без учета повторений). По умолчанию используется опция ALL (противоположность DISTINCT), поэтому указывать ALL не обязательно Повторяющиеся значения считаются, когда DISTINCT не указано Другой опцией функции COUNT является звездочка (*) При использовании со звездочкой функция COUNT возвращает число всех строк в таблице, без исключения повторяющихся, не обращая внимания на возможно имеющиеся в столбце значения NULL

Синтаксис оператора функции COUNT следующий

COUNT [ (*) | (DISTINCT | ALL) J (имя_столбца)

Команда DISTINCT не используется с COUNT(*), а используется только с COUNT(имя_столбца)

Пример_______________________________Значение____________________

SELECT COUNT (EMP_ID) Подсчет числа табельных номеров всех слу-

FROM EMPLOYEE__PAY_TBL; жащих

SELECT COUNT (DISTINCT SALARY) Подсчет только разных строк

FROM EMPLOYEE_PAY_TBL;

SELECT COUNT (ALL SALARY; Подсчет всех строк для SALARY

FROM EMPLOYEE_PAY_TBL;

SELECT COUNT (*) Подсчет всех строк таблицы EMPLOYEE_TBL

FROM EMPLOYEE_TBL;

В следующем примере COUNT (*) используется для подсчета всех записей в таблице EMPLOYEE_TBL. В ней оказывается 6 строк с данными о служащих.

SELECT COUNT(*)

FROM EMPLOYEE_TBL;

COUNT (*)

---------

6

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

SELECT COUNT(EMP_ID)

FROM EMPLOYEE_TBL;

COUNT(EMP_ID)

------------

6

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

SELECT COUNT(PAGER)

FROM EMPLOYEEJTBL;

COUNT(PAGER)

------------

2

В следующем примере используется таблица OPDERS_TBL.

SELECT *

FROM ORDERS_TBL;

ORD_NUM CUST_ID PROD__ID QTY ORD_DATE

56A901 232 11235 1 22-OCT-99

56A917 12 907 100 30-SEP-99

32A132 43 222 25 10-OCT-99

16C17 090 222 2 17-OCT-99

18D778 287 90 10 17-OCT-99

23E934 432 13 20 15-OCT-99

90C461 560 1234 2

7 строк выбраны.

Подсчитаем в этой таблице число различных кодов товаров.

SELECT COUNT(DISTINCT(PROD_ID))

FROM ORDERS_TBL;

COUNT(DISTINCT(PROD_ID))

-----------------------

6

Для PROD_ID значение 222 встречается дважды, в результате подсчет различных значений возвращает б, а не 7.

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

Функция SUM

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

Синтаксис оператора функции зим следующий.

SUM ([ DISTINCT ] имя_столбца )

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

Пример_______________________________Значение__________________

SELECT SUM (SALARY) Подсчет суммы зарплат всех служащих

FROM EMPLOYEE_PAY_TBL;

SELECT SUM (DISTINCT SALARY) Подсчет суммы зарплат всех служащих без

FROM EMPLOYEE_PAY_TBL; учета повторяющихся значений

Подсчитаем сумму всех значений стоимости товаров из таблицы PRODUCT S_TBL.

SELECT SUM(COST)

FROM PRODUCTSJTBL;

SUM(COST)

---------------

163.07

Функция AVG

Функция AVG используется для подсчета среднего для значений заданной группы строк. При использовании с ключевым словом DISTINCT повторно встречающиеся значения в среднем не учитываются.

Синтаксис оператора функции AVG следующий.

AVG([ DISTINCT ] имя_столбца )

Для использования функции AVG тип значения в столбце должен быть числовым.

Пример_____________________________Значение______________________

SELECT AVG (SALARY) Подсчет средней зарплаты всех служащих

FROM EMPLOYEE_PAY_TBL;

SELECT AVG (DISTINCT SALARY) Подсчет среднего значения для зарплат всех

FROM EMPLOYEE_PAY_TBL ; служащих без учета повторяющихся значений

Подсчитаем среднее для всех значений стоимости товаров из таблицы PRODUCTS_TBL.

SELECT AVG(COST)

FROM PRODUCTS_TBL;

AVG(COST)

-----------

13.5891667

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

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

SELECT AVG(PAY_RATE), AVG(SALARY)

FROM PRODUCTSJTBL;

AVG(PAY_RATE) AVG(SALARY)

13.5833333 30000

Функция MAX

Функция MAX используется для подсчета максимума для значений заданной группы строк. Значения NULL при этом игнорируются. Можно использовать также ключевое слово DISTINCT, но поскольку повторно встречающиеся значения на значение максимума не влияют, это ключевое слово оказывается в данном случае бесполезным.

МАХ([ DISTINCT ] имя_столбца )

Пример______________________________Значение____________________

SELECT MAX (SALARY) Нахождение максимальной зарплаты

FROM EMPLOYEE_PAY_TBL;

SELECT MAX (DISTINCT SALARY) Нахождение максимальной зарплаты без учета

FROM EMPLOYEE_PAY_TBL; повторяющихся значений

Подсчитаем максимум всех значений стоимости товаров из таблицы PRODUCT SJTBL.

SELECT MAX(COST)

FROM PRODUCTS_TBL;

MAX(COST)

------------------

59.99

Функция MIN

Функция MIN используется для подсчета минимума для значений заданной группы строк. Значения NULL при этом игнорируются. Можно использовать также ключевое слово DISTINCT, но поскольку повторно встречающиеся значения на значение минимума не влияют, это ключевое слово оказывается в данном случае бесполезным.

MIN([ DISTINCT ] имя_столбца )

Пример_________________________________Значение_____________________

SELECT MIN (SALARY) Нахождение минимальной зарплаты

FROM EMPLOYEE_PAY_TBL;

SELECT MIN (DISTINCT SALARY) Нахождение минимальной зарплаты без уче-

FROM EMPLOYEE_PAY_TBL; та повторяющихся значений

Подсчитаем минимум всех значений стоимости товаров из таблицы PRODUCTSJTBL.

SELECT MIN(COST)

FROM PRODUCTS_TBL;

MIN(COST)

-----------

1.05

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

Наконец, рассмотрим пример комбинирования итоговых функций с арифметическими операциями.

SELECT COUNT(ORD_NUM), SUM(QTY),

SUM(QTY) / COUNT(ORD_NUM) AVG_QTY

FROM ORDERS_TBL;

COUNT(ORD_NUM) SUM(QTY) AVG_QTY

------------- ------- -------

7 160 22.85743

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

Резюме

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

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

Вопросы и ответы

Почему при использовании функций MIN и МАХ значение NULL игнорируется?

Значение NULL означает, что в поле ничего нет.

Почему при использовании функции COUNT тип данных не играет значения?

Функция COUNT просто считает строки.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Верно ли следующее утверждение: "Функция AVG возвращает среднее для значений всех строк, включая значения NULL?"

2. Верно ли следующее утверждение: "Функция зим используется для суммирования итоговых значений по столбцам?"

3. Верно ли следующее утверждение: ''Функция COUNT (* ) подсчитывает число всех строк в таблице?"

4. Будут ли работать следующие операторы SELECT? Если нет, то что в них следует исправить?

а. SELECT COUNT *

FROM EMPLOYEE_PAY_TBL;

6. SELECT COUNT(EMPLOYEE_ID), SALARY

FROM EMPLOYEE_PAYJFBL;

B. SELECT MIN(BONUS), MAX(SALARY)

FROM EMPLOYEE_PAY_TBL

WHERE SALARY > 20000;

Упражнения

1. Рассмотрите следующую таблицу PRODUCTS_TBL.

EMP_ID POSITION DATE_HIRE PAV_RATE DATE_LAST SALARY BONUS

311549902 МАРКЕТИНГ 23-МАЙ-89 01-МАЙ-99 30000 2000

442346889 РУК.ГРУППЫ 17-ИЮН-90 14.75 01-ИЮН-99

213764555 МЕНЕДЖЕР 14-АВГ-94 01-АВГ-99 40000 3000

313782439 ПРОДАВЕЦ 28-ИЮН-97 20000 1000

220984332 ДОСТАВКА 22-ИЮЛ-96 11 01-ИЮЛ-99

443679012 ДОСТАВКА 14-ЯНВ-91 15 01-ЯНВ-99

6 строк выбраны.

Постройте операторы SQL, позволяющие найти следующее.

а. Среднюю зарплату (SALARY).

б. Максимальную премию (BONUS).

в. Сумму всех выплат по зарплате.

г. Минимальную почасовую оплату (PAY_RATE).

д. Общее число строк в таблице.

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

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

Основными на этом уроке будут следующие темы.

• Зачем группировать данные?

• Выражение GROUP BY

• Функции группирования значений

• Использование итоговых функций

• Группирование по столбцам

• GROUP BY в сравнении с ORDER BY

• Выражение HAVING

Зачем группировать данные?

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

Предположим, что вам необходимо найти среднюю зарплату служащих по каждому из городов. Это можно сделать, применив к столбцу SALARY итоговую функцию AVG, а затем использовав GROUP BY для группирования выводимых данных по городам.

Группирование данных осуществляется с помощью выражения GROUP BY в операторе SELECT. На предыдущем уроке были рассмотрены итоговые функции. В ходе данного урока мы с вами научимся использовать итоговые функции в совокупности с выражением GROUP BY, чтобы лучше организовать представляемые данные.

Ключевое слово GROUP BY

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

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

SELECT FROM WHERE GROUP BY ORDER BY

Ключевое слово GROUP BY должно следовать за условиями в выражении ключевого слова WHERE и предшествовать ключевому слову ORDER BY, если последнее имеется.

SELECT столбец1, столбец2

FROM таблица1, таблица2 WHERE условия

GROUP BY столбец1, столбец2

ORDER BY столбец1, столбец2

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

Группирование выбранных данных

Группировать данные просто. В выражении ключевого слова GROUP BY могут использоваться только выбранные столбцы (т. е. столбцы из списка ключевого слова SELECT в операторе запроса). Если имя столбца не указано в списке ключевого слова SELECT, то имя этого столбца в выражении ключевого слова GROUP BY использовать нельзя. Это логично - как группировать в отчете данные, которых в нем нет?

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

К функциям группирования - функциям, используемым в выражении ключевого слова GROUP BY для объединения данных в группы, - относятся AVG, MAX, MIN, зим и COUNT. Это итоговые функции, о которых вы узнали из урока 9, "Подведение итогов по данным запроса" В ходе урока 9 итоговые функции использовались по отношению ко всем данным столбца, а здесь мы рассмотрим использование итоговых функций для группирования повторяющихся значений.

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

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

Пример

SELECT EMP_ID, CITY

FROM EMPLOYEEJTBL

GROUP BY CITY, EMP_ID;

В этом операторе SQL из таблицы EMPLOYEE_TBL выбираются столбцы EMP_ID и CITY, а данные последних выводятся сгруппированными сначала по CITY, а затем по EMP_ID.

Обратите внимание на порядок выбора столбцов и на порядок столбцов в выражении ключевого слова GROUP BY

Пример

SELECT EMP_ID, SUM(SALARY)

FROM EMPLOYEE_PAY_TBL

GROUP BY SALARY, EMP_ID;

Этот оператор SQL возвращает данные столбца EMP_ID и сумму по группам зарплат, созданным по величине зарплаты (SALARY) и табельному номеру (EMP_ID).

Пример

SELECT SUM(SALAPY)

FROM EMPLOYEE_PAY_TBL;

Здесь оператор SQL возвращает сумму всех выплат по зарплате из таблицы

ЕМ PLOYEE_PAY_TBL.

Пример

SELECT SUM(SALARY)

FROM EMPLOYEE_PAY_TBL

GROUP BY SALARY;

Здесь оператор SQL возвращает суммы по группам, созданным по всем уровням зарплаты.

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

SELECT CITY

FROM EMPLOYEEJTBL ;

CITY

GREENWOOD

INDIANAPOLIS

WHITELAND

INDIANAPOLIS

INDIANAPOLIS

INDIANAPOLIS

6 строк выбраны.

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

SELECT CITY, COUNT(*)

FROM EMPLOYEE_TBL

GROUP BY CITY;

CITY COUNT(*)

GREENWOOD 1

INDIANAPOLIS 4

WHITELAND 1

3 строки выбраны.

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

SELECT *

FROM EMP_PAY_TMP;

CITY LAST_NAME FIRST_NAME PAY_RATE SALARY

GREENWOOD STEPHENS TINA 30000

INDIANAPOLIS PLEW LINDA 14.75

WHITELAND GLASS BRANDON 40000

INDIANAPOLIS GLASS JACOB 20000

INDIANAPOLIS WALLACE MARIAH 11

INDIANAPOLIS SPURGEON TIFFANY 15

6 строк выбраны.

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

SELECT CITY, AVG(PAY_RATE), AVG(SALARY)

FROM EMP_PAY_TMP

GROUP BY CITY;

CITY AVG(PAY_RATE) AVG(SALARY}

GREENWOOD 30000

INDIANAPOLIS 13.5833333 20000

WHITELAND 40000

3 строки выбраны.

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

SELECT CITY, AVG(PAY_RATE), AVG(SALARY)

FROM EMP_PAY_TMP

WHERE CITY IN ('INDIANAPOLIS','WHITELAND')

GROUP BY CITY

ORDER BY 2,3;

CITY AVG(PAY_RATE) AVG(SALARY)

INDIANAPOLIS 13.5833333 20000

WHITELAND 40000

Значения сортируются так, что значения NULL оказываются в конце. Поэтому запись для города Индианаполис представлена первой. Город Гринвуд не был выбран, но если бы был, то соответствующая ему запись была бы представлена перед записью для Уайтленда, поскольку для Гринвуда средняя зарплата (SALARY) равна 30000, а средняя зарплата является вторым параметром сортировки в выражении ключевого слова ORDER BY.

В завершение раздела рассмотрим использование в выражении ключевого слова ORDER BY итоговых функций МАХ и MIN.

SELECT CITY, MAX(PAY_RATE), MIN(SALARY)

FROM EMP_PAY_TMP

GROUP BY CITY;

CITY MAX(PAY_RATE) MIN(SALARY)

GREENWOOD 30000

INDIANAPOLIS 15 20000

WHITELAND 40000

3 строки выбраны.

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

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

SELECT EMP_ID, SUM(SALARY)

FROM EMPLOYEE_PAY_TBL

UNION

SELECT EMP_ID, SUM(PAY_RATE)

FROM EMPLOYEE_PAY_TBL

GROUP BY 2, 1;

Этот оператор SQL возвращает табельный номер служащего (EMP_ID) и группирует суммы по значениям зарплаты. При использовании ключевого слова UNION результаты двух операторов SELECT объединяются. Группирование выполняется сначала по столбцу 2Б, представляющем зарплату (SALARY), а затем по столбцу 1, представляющем табельный номер служащего (EMP_ID).

GROUP BY И ORDER BY

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

Вот несколько особенностей использования ключевого слова GROUP BY для сортировки.

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

• В отличие от выражения ключевого слова ORDER BY, в выражении ключевого слова GROUP BY имена столбцов нельзя заменить числами.

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

Вот пример использования для сортировки данных ключевого слова GROUP BY вместо ключевого слова ORDER BY:

SELECT LAST_NAME, FIRST_NAME, CITY

FROM EMPLOYEE_TBL

GROUP BY LAST_NAME;

SELECT LAST_NAME, FIRST_NAME, CITY

*

ERROR at line 1:

ORA-00979: not a GROUP BY expression

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

В следующем примере проблема предыдущего оператора решена путем добавления в список ключевого слова GROUP BY недостающих имен из списка ключевого слова SELECT.

SELECT IAST_NAME, FIRST_NAME, CITY

FROM EMPLOYEE_TBL

GROUP BY LAST_NAME, FIRST_NAME, CITY;

LAST_NAME FIRST_NAME CITY

GLASS BRANDON WHITELAND

GLASS JACOB INDIANAPOLIS

PLEW LINDA INDIANAPOLIS

SPURGEON TIFFANY INDIANAPOLIS

STEPHENS TINA GREENWOOD

WALLACE MARIAH INDIANAPOLIS

6 строк выбраны.

В этом примере выбираются те же данные из той же таблицы, но уже все столбцы перечислены в выражении ключевого слова GROUP BY в том же порядке, в каком они указаны в списке ключевого слова SELECT. В результате данные показаны отсортированными сначала по столбцу LAST_NAME, затем по столбцу FIRST_NAME и наконец, по столбцу CITY. С помощью ключевого слова ORDER BY то же самое получить легче, но для правильного использования ключевого слова GROUP BY, наверное, будет полезно разобраться, как с его помощью сортируются данные, перед тем, как выполнить группирование результатов.

В следующем примере получается выборка из таблицы EMPLOYEE_TBL и используется ключевое слово GROUP BY для упорядочения данных по значениям столбца CITY.

SELECT CITY, LAST_HAME

FROM EMPLOYEEJTBL

GROUP BY CITY, LAST_NAME;

CITY LAST_NAME

GREENWOOD STEPHENS

INDIANAPOLIS GLASS

INDIANAPOLIS PLEW

INDIANAPOLIS SPURGEON

INDIANAPOLIS WALLACE

WHITELAND GLASS

6 строк выбраны.

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

SELECT CITY, COUNT(*)

FROM EMPLOYEEJTBL

GROUP BY CITY

ORDER BY 2,1;

CITY COUNT(*)

GREENWOOD 1

WHITELAND 1

INDIANAPOLIS 4

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

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

Ключевое слово GROUP BY можно использовать для сортировки данных в операторе CREATE VIEW, а вот ключевое слово ORDER BY использовать в операторе CREATE VIEW нельзя. Оператор CREATE VIEW будет подробно рассматриваться в ходе урока 20, "Создание и использование представлений и синонимов".

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

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

Ключевое слово HAVING в операторе SELECT должно следовать за выражением ключевого слова GROUP BY и тоже предшествовать ключевому слову ORDER BY, если последнее используется.

Синтаксис оператора SELECT, в котором используется ключевое слово HAVING, следующий.

SELECT столбец1, столбец2

FROM таблица1, таблица2

WHERE условия

GROUP BY столбец1, столбец2

HAVING условия

ORDER BY столбец1, столбец2

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

SELECT CITY, AVG(PAY_RATE), AVG(SALARY)

FROM EMP_PAY_TMP

WHERE CITY <> 'GREENWOOD'

GROUP BY CITY

HAVING AVG(SALARY) > 20000

ORDER BY 3;

CITY AVG(PAY_RATE) AVG(SALARY)

WHITELAND 40000

1 строка выбрана.

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

• Город Гринвуд исключен выражением ключевого слова WHERE.

• Данные по городу Индианаполис не представлены ввиду того, что средняя зарплата для этого города равна 20000, что не превышает необходимые 20000.

Резюме

Итак, вы теперь знаете, как группировать результаты запроса с помощью ключевого слова GROUP BY. Ключевое слово GROUP BY используется, главным образом, с итоговыми функциями SQL типа SUM, AVG, MAX, MIN и COUNT. Ключевое слово GROUP BY подобно ключевому слову ORDER BY в том смысле, что оба они сортируют выводимые данные. Ключевое слово GROUP BY предназначено для сортировки данных по группам, но может использоваться и для обычной сортировки данных, хотя последнее проще сделать с помощью ключевого слова ORDER BY.

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

Вопросы и ответы

При использовании ключевого слова ORDER BY в операторе SELECT обязательно ли использовать ключевое слово GROUP BY?

Нет. Ключевое слово GROUP BY в операторе SELECT является необязательным, но оно может оказаться очень полезным при использовании ORDER BY.

Что такое групповое значение?

Рассмотрим столбец CITY таблицы EMPLOYEE_TBL. Если выбрать имена служащих (LAST_NAME) и города (CITY) и эти данные сгруппировать по городам, строки для одинаковых названий городов будут отображены вместе.

Чтобы сгруппировать данные запроса по некоторому столбцу в выражении ключевого слова GROUP BY, должен ли этот столбец быть указан в списке ключевого слова SELECT?

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Будут ли работать следующие операторы SELECT? Если нет, то что в них следует исправить?

а. SELECT SUM(SALARY), EMP_ID FROM EMPLOYEE_PAY_TBL GROUP BY 1 AND 2;

6. SELECT EMP_ID, MAX(SALARY) FROM EMPLOYEE_PAY_TBL GROUP BY SALARY, EMP_ID;

B. SELECT EMP_ID, COUNT(SALARY) FROM EMPLOYEE_PAY_TBL ORDER BY EMP_ID GROUP BY SALARY; -

2. Верно ли следующее утверждение: "При использовании ключевого слова HAVING необходимо использовать также и ключевое слово GROUP BY?"

3. Верно ли следующее утверждение: "Следующий оператор SQL возвратит суммы зарплат по группам"

SELECT SUM(SALARY) FROM EMPLOYEE_PAY_TBL

4. Верно ли следующее утверждение' "Выбранные в запросе столбцы должны присутствовать в списке ключевого слова GROUP BY в том же порядке?"

5. Верно ли следующее утверждение: "Выражение ключевого слова HAVING говорит GROUP BY о том, какие группы следует включить в вывод?"

Упражнения

1. Запишите оператор SQL, возвращающий табельный номер служащего (EMP_ID), имя служащего (LAST_NAME) и название города (CITY) из таблицы EMPLOYEE_TBL, сгруппированные по значениям столбца CITY.

2. Запишите оператор SQL, возвращающий из таблицы EMPLOYEEJTBL названия городов и число проживающих в них служащих. Добавьте в оператор ключевое слово HAVING, чтобы в выводе отобразить только те города, в которых проживает более двух служащих из числа тех, информация о которых имеется в таблице.

11-й час Изменение представления данных при выводе

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

Основными на этом уроке будут следующие темы.

• Обзор функций для работы со строками символов

• Как и когда используются функции для работы со строками

• Примеры функций, определяемых ANSI SQL

• Примеры функций, общих для основных реализаций SQL

• Обзор функций преобразования

• Как и когда используются функции преобразования

Функции стандарта ANSI для работы со строками

Функции для работы с символьными строками используются в SQL для представления данных в формате, отличном от того, в котором эти данные хранятся в таблице базы данных. Сначала мы обсудим те функции, которые включены в стандарт ANSI, а затем рассмотрим примеры использования функций, предлагаемых основными реализациями SQL. Из функций, определяемых стандартом ANSI, мы рассмотрим CONCATENATION, SUBSTRING, TRANSLATE, REPLACE, UPPER И LOWER.

Конкатенация

Конкатенация - это соединение двух строк в одну. Например, можно соединить имя и фамилию персоны в одну строку.

В результате конкатенации строк джон и СМИТ получается строка джон СМИТ.

Выделение частей строки

Подстрока (substring) - это строка символов, входящая в данную строку, другими словами, часть данной строки Например, следующие строковые значения являются подстроками строки ДЖОНСОН

Д ДЖОН ДЖО ОН СОН

Трансляция

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

Общие функции для работы со строками

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

В следующих разделах мы рассмотрим использование концепций ANSI в основных реализациях SQL, к которым относятся Oracle, Sybase, SQLBase, Informix и SQL Server

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

Конкатенация

Конкатенация, как и многие другие функции, в разных реализациях SQL представлена по-разному Вот примеры использования конкатенации в Oracle и SQL Server

Oracle__________

SELECT 'ДЖОН' || 'СОН' возвратит ДЖОНСОН

SQL Server_____

SELECT 'ДЖОH' + 'СОН' возвратит ДЖОНСОН

Синтаксис использования конкатенации в Oracle следующий

ИМЯ_СТРОКИ || ["II] ИМЯ_СТРОКИ [ ИМЯ_СТРОКИ ]

Синтаксис использования конкатенации в SQL Server следующий.

ИМЯ_СТРОКИ + [ " + ] ИМЯ_СТРОКИ [ ИМЯ_СТРОКИ ]

Пример_______________________________Значение________

SELECT CITY + STATE Этот оператор SQL Server объединяет названия

FROM EMPLOYEEJTBL; города и штата в одну строку

SELECT CITY ||', '|| STATE Этот оператор Oracle объединяет названия го-

FROM EMPLOYEE_TBL; рода и штата в одну строку, помещая междуними запятую

SELECT CITY + ' ' + STATE Этот оператор SQL Server объединяет названия

FROM EMPLOYEE_TBL; города и штата в одну строку, помещая между ними пробел

Пример

SELECT LAST_NAME || ', ' || FIRST_NAME

FROM EMPLOYEEJTBL;

NAME

STEPHENS, TINA

PLEW, LINDA

GLASS, BRANDON

GLASS, JACOB

WALLACE, MARIAH

SPURGEON, TIFFANY

6 строк выбраны.

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

Функция TRANSLATE

Функция TRANSLATE заменяет символы в строке символов в соответствии с указанным правилом замены Правило замены определяется посимвольным соответствием пары заданных буквальных символьных значений Синтаксис оператора функции TRANSLATE Следующий

TRANSLATE(МНОЖЕСТВО СТРОК, ЗНАЧЕНИЕ1, ЗНАЧЕНИЕ2)

Пример______________________Значение_____________________

SELECT TRANSLATE Этот оператор SQL заменяет все имеющиеся в строке

(CITY, ' IND ' , 'ABC' символы I на А, N на В и D на С

FROM EMPLOYEEJTBL;

Вот пример использования функции TRANSLATE с реальными данными.

SELECT CITY, TRANSLATE(CITY,'IND",'ABC')

FROM EMPLOYEE_TBL;

CITY TRANSLATE(CI

GFEENWOOD GREEBWOOC

INDIANAPOLIS ABCAABAPOLAS

WHITELAND WHATELABC

INDIANAPOLIS ABCAABAPOLAS

INDIANAPOLIS ABCAABAPOLAS

INDIANAPOLIS ABCAABAPOLAS

6 строк выбраны.

Здесь все встречающиеся символы I заменены на А, N - на в и D - на с. В названии города INDIANAPOLIS подстрока IND была заменена на ABC, а в названии города GREENWOOD символ D был заменен на с. Обратите также внимание на то, каким образом транслировалось название города WHITELAND.

Функция REPLACE

Функция REPLACE используется для замены в строке некоторого заданного символа (или строки символов) другим заданным символом (строкой символов). Используется эта функция подобно функции TRANSLATE, только здесь заданный символ или строка заменяется другим заданным символом или строкой.

Синтаксис соответствующего оператора следующий.

REPLACE''ЗНАЧЕНИЕ', 'ЗНАЧЕНИЕ', [ NULL ] 'ЗНАЧЕНИЕ'}

Пример_______________________Значение________________________

SELECT Этот оператор возвращает список имен, заменив в

REPLACE (FIRST_NAME, них все встречающиеся буквы т на в

'T' , 'B')

FROM EMPLOYEEJTBL;

SELECT CITY, REPLACE(CITY, 'I' , 'Z')

FROM EMPLOYEE_TBL;

CITY TRANSLATE(CI

GREENWOOD GREENWOOD

INDIANAPOLIS ZNDZANAPOLZS

WHITELAND WHZTELAND

INDIANAPOLIS ZNDZANAPOLZS

INDIANAPOLIS ZNDZANAPOLZS

INDIANAPOLIS ZNDZANAPOLZS

6 строк выбраны.

Функция UPPER

В большинстве реализаций SQL имеются средства для изменения регистра символов с помощью функций. Функция UPPER используется для изменения регистра символов заданной строки с нижнего на верхний.

Синтаксис соответствующего оператора следующий.

UPPER(строка символов)

Пример___________________________Значение_____________________

SELECT UPPER (LAST_NAME) Этот оператор изменяет регистр всех символов

FROM EMPLOYEE_TBL, в заданном столбце с нижнего на верхний

SELECT UPPER(CITY)

FROM EMPLOYEE_TBL;

UPPER(CITY)

GREENWOOD

INDIANAPOLIS

WHITELAND

INDIANAPOLIS

INDIANAPOLIS

INDIANAPOLIS

б строк выбраны.

Функция LOWER

В противоположность функции UPPER, функция LOWER используется для изменения регистра символов заданной строки с верхнего на нижний. Синтаксис соответствующего оператора следующий.

LOWER(строка символов)

Пример____________________________Значение____________________

SELECT LOWER (LAST_NAME) Этот оператор изменяет регистр всех символов в

FROM EMPLOYEEJTBL, заданном столбце с верхнего на нижний

SELECT LOWER(CITY)

FROM EMPLOYEEJTBL;

LOWER(CITY)

greenwood

Indianapolis

whiteland

Indianapolis

indianapolis

indianapolis

6 строк выбраны.

Функция SUBSTR

Функции для выделения подстрок из строк имеются во всех реализациях SQL, но имена таких функций могут отличаться, как видно из следующих примеров для Oracle и SQL Server.

В Oracle синтаксис соответствующего оператора следующий.

SUBSTR(имя столбца, начальная позиция, длина)

В случае SQL Server синтаксис соответствующего оператора будет следующим.

SUBSTRING(имя столбца, начальная позиция, длина)

Как видите, отличаются только имена функций.

Пример__________________________________Значение___________

SELECT SUBSTRING (EMP_ID,1,3) Этот оператор SQL возвращает первые три

FROM EMPLOYEE_TBL; символа строки EMP_ID

SELECT SUBSTRING (EMP_ID,4,2) Этот оператор SQL возвращает четвертый

FROM EMPLOYEE_TBL; ипятый символы строки EMP_ID

SELECT SUBSTRING (EMP_ID,6,4) Этот оператор SQL возвращает символы

FROM EMPLOYEE_TBL; с шестого по девятый включительно

строки EMP_ID

Вот пример использования данной функции в SQL Server.

SELECT EMP_ID, SUBSTRING(EMP_ID,1,3)

FROM EMPLOYEE_TBL;

EMP__ID SUB

311549902 311

442346889 442

213764555 213

313782439 313

220984332 220

443679012 443

6 rows affected.

А вот пример использования данной функции в Oracle.

SELECT EMP_ID, SUBSTR(EMP_ID,1, 3)

FROM EMPLOYEEJTBL;

EMP_ID SUB

311549902 311

442346889 442

213764555 213

313782439 313

220984332 220

443679012 443

6 rows selected.

Обратите внимание на выводимые в этих двух случаях сообщения базы данных. В первом случае это 6 rows affected, а во втором - 6 rows selected. Оба сообщения имеют одинаковый смысл (6 строк выбраны), но такого рода отличия нередко можно увидеть при сравнении различных реализаций SQL.

Функция INSTR

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

INSTR(имя строки, 'множество символов',

[ начальная позиция поиска [ , номер появления ] ]);

Пример______________________________Значение_______________

SELECT INSTR (STATE, ' I ', 1, 1) Этот оператор SQL для каждого названия

FROM EMPLOYEE_TBL; штата из таблицы EMPLOYEE_TBL возвраща-

ет номер позиции, в которой первый раз

встречается буква I

SELECT PROD_DESC,

INSTR(PROD_DESC,'A',1,1)

FROM PRODUCTSJTBL;

PROD_DESC INSTR(PROD_DESC, 'A',1,1)

КОСТЮМ ВЕДЬМЫ О

ПЛАСТИКОВЫЕ ТЫКВЫ 3

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 16

ФОНАРИ 4

КОСТЮМЫ В АССОРТИМЕНТЕ 11

СЛАДКАЯ КУКУРУЗА 3

ТЫКВЕННЫЕ КОНФЕТЫ О

ПЛАСТИКОВЫЕ ПАУКИ 3

МАСКИ В АССОРТИМЕНТЕ 2

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 7

ПОЛОЧКА ИЗ ДУБА 7

11 строк выбраны.

Обратите внимание на то, что в том случае, когда символ А в строке не найден, для позиции возвращается значение 0.

Функция LTRIM

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

Синтаксис соответствующего оператора следующий.

LTRIM(строка символов, [ , 'множество символов' ]);

Пример_________________________________Значение___________

SELECT LTRIM(FIRST_NAME, ' LES') Этот оператор SQL обрезает символы

LES FROM CUSTOMERJTBL в начале всех имен LESLIE

WHERE FIRST_NAME = 'LESLIE';

SELECT POSITION, LTRIM(POSITION,'SALES')

FROM EMPLOYEE_PAY_TBL;

POSITION LTRIM(POSITION,

MARKETING MARKETING

TEAM LEADER TEAM LEADER

SALES MANAGER MANAGER

SALESMAN MAN

SHIPPER HIPPER

SHIPPER HIPPER

6 строк выбраны.

В строке SHIPPER была обрезана буква S, хотя эта строка и не содержит подстроку SALES. В данном случае первые четыре символа строки SALES были проигнорированы. Искомые символы должны встречаться в строке именно в заданном порядке и находиться с самого левого края строки. Другими словами, функция LTRIM срезает в строке все символы слева до последнего символа искомой строки включительно.

Функция RTRIM

Подобно LTRIM, функция RTRIM обрезает заданное множество символов в конце строки.

Синтаксис соответствующего оператора следующий.

RTRIM(CTpoKa символов, [ , 'множество символов' ]);

Пример_______________________________________Значение______

SELECT RTRIM(FIRST_NAME, 'ON' ) Этот оператор SQL возвращает имя

FROM EMPLOYEEJTBL BRANDON и обрезает символы ON в конце,

WHERE FIRST_NAME = ' BRANDON ' ; остается только BRAND

SELECT POSITION, RTRIM(POSITION,'ER')

FROM EMPLOYEE_PAY_TBL;

POSITION RTRIM(POSITION,

MARKETING MARKETING

TEAM LEADER TEAM LEAD

SALES MANAGER SALES MANAG

ALESMAN SALESMAN

SHIPPER SHIPP

SHIPPER SHIPP

6 строк выбраны.

Здесь строка ER была обрезана в конце всех подходящих строк.

Функция DECODE

Функция DECODE к стандартным функциям ANSI не относится - по крайней мере, на момент написания данной книги, - но ее использование обсуждается здесь ввиду предоставляемых ею больших возможностей. Эта функция имеется в SQLBase, Oracle и, возможно, других реализациях SQL. Функция DECODE используется для поиска строк по заданному значению или строке, и если строка найдена, в результатах запроса отображается другая заданная строка.

Синтаксис соответствующего оператора следующий.

DECODE(имя столбца, 'искомая1', 'возвращаемая1'

[,'искомая2', 'возвращаемая2', 'значение по умолчанию']);

Пример____________________________Значение________________

SELECT DECODE (LAST_NAME, Этот запрос извлекает все фамилии из таблицы

'СМИТ', 'ДЖОНС', 'ДРУГОЕ') EMPLOYEE_TBL, причем вместо фамилии

FROM EMPLOYEE_TBL; СМИТ отображается ДЖОНС, а вместо любой

другой - значение по умолчанию, которым в данном

случае является значение ДРУГОЕ

В следующем примере функция DECODE используется по отношению к значениям столбца CITY таблицы EMPLOYEEJTBL.

SELECT CITY,

DECODE(CITY,'INDIANAPOLIS', 'INDY',

'GREENWOOD', 'GREEN', 'OTHER')

FROM EMPLOYEE _TBL;

CITY DECOD

GREENWOOD GREEN

INDIANAPOLIS INDY

WHITELAND OTHER

INDIANAPOLIS INDY

INDIANAPOLIS INDY

INDIANAPOLIS INDY

6 строк выбраны.

В результате вместо названия Индианаполиса отображается INDY, вместо Гринвуда отображается GREEN, а для любого другого города - OTHER.

Другие функции для работы со строками

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

Выяснение длины значения

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

Синтаксис соответствующего оператора следующий.

LENGTH(строка символов)

Пример____________________________Значение________________

SELECT LENGTH (LAST_NAME) Этот оператор SQL возвращает длину фами-

FROM EMPLOYEE_TBL; лии для каждого из служащих

SELECT PROD_DESC, LENGTH(PROD_DESC)

FROM PRODXCTS_TBL;

PROD_DESC LENGTH(PROD_DESC)

КОСТЮМ ВЕДЬМЫ 13

ПЛАСТИКОВЫЕ ТЫКВЫ 17

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 30

ФОНАРИ 6

КОСТЮМЫ В АССОРТИМЕНТЕ 22

СЛАДКАЯ КУКУРУЗА 16

ТЫКВЕННЫЕ КОНФЕТЫ 17

ПЛАСТИКОВЫЕ ПАУКИ 17

МАСКИ В АССОРТИМЕНТЕ 20

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 18

ПОЛОЧКА ИЗ ДУБА 15

11 строк выбраны.

Функция NVL (замещение значения NULL)

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

Синтаксис соответствующего оператора следующий.

NVL('значение', 'замещающее значение')

Пример______________________________Значение______________

SELECT NVL (SALARY, '00000') Этот оператор SQL находит пустые значения

FROM EMPLOYEE_PAY_TBL; для зарплаты и заменяет их значением 00000

SELECT PAGER, NVL(PAGER,9999999999)

FROM EMPLOYBE_TBL;

PAGER NVL(PAGER,

9999999999

9999999999

3175709980 3175709980

8887345678 8887345678

9999999999

9999999999

6 строк выбраны.

Значение 9999999999 было подставлено только вместо значений NULL

Функция LPAD

Функция LPAD используется для добавления символов или пробелов в начало строки. Синтаксис соответствующего оператора следующий

LPAD(множество строк, число, символ)

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

SELECT LPAD(PROD_DESC,33,'.')

PRODUCT FROM PRODICTS_TBL;

PRODUCT

.................... КОСТЮМ ВЕДЬМЫ

................ ПЛАСТИКОВЫЕ ТЫКВЫ

...ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

........................... ФОНАРИ

........... КОСТЮМЫ В АССОРТИМЕНТЕ

................. СЛАДКАЯ КУКУРУЗА

................ ТЫКВЕННЫЕ КОНФЕТЫ

................ ПЛАСТИКОВЫЕ ПАУКИ

............ .МАСКИ В АССОРТИМЕНТЕ

............... ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

.................. ПОЛОЧКА ИЗ ДУБА

11 строк выбраны.

Функция RPAD

Функция RPAD используется для добавления символов или пробелов в конец строки Синтаксис соответствующего оператора следующий.

RPAD(множество строк, число, символ)

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

SELECT RPAD(PROD_DESC,33,'.')

PRODUCT FROM PRODICTSJTBL;

PRODUCT

КОСТЮМ ВЕДЬМЫ....................

ПЛАСТИКОВЫЕ ТЫКВЫ................

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ...

ФОНАРИ...........................

КОСТЮМЫ В АССОРТИМЕНТЕ...........

СЛАДКАЯ КУКУРУЗА.................

ТЫКВЕННЫЕ КОНФЕТЫ................

ПЛАСТИКОВЫЕ ПАУКИ................

МАСКИ В АССОРТИМЕНТЕ.............

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ...............

ПОЛОЧКА ИЗ ДУБА..................

11 строк выбраны.

Функция ASCII

Функция ASCII возвращает ASCII-код самого левого символа в строке (ASCII расшифровывается как American Standard Code for Information Interchange - американский стандартный код для обмена информацией).

Синтаксис соответствующего оператора следующий.

ASCII(строка)

Например,

ASCII ('A') возвратит 65,

ASCII (' в') возвратит 66,

ASCII (' с') возвратит 67.

Математические функции

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

Абсолютное значение ABS Округление ROUND Квадратный корень SQRT Знак числа SIGN Возведение в степень POWER Целая часть и ближайшее целое сверху FLOOR, CEIL Экспонента ЕХР Тригонометрические функции SIN, cos, TAN Общий синтаксис большинства математических функций следующий.

ФУНКЦИЯ(выражение)

Функции преобразования

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

Абсолютное значение

Округление

Квадратный корень

Знак числа

Возведение в степень

Целая часть и ближайшее целое сверху

Экспонента

Тригонометрические функции

ABS

ROUND

SQRT

SIGN

POWER

FLOOR,

CEIL EXP

SIN, COS, TAN

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

• символьного типа данных в числовой;

• числового типа данных в символьный;

• символьного типа данных в тип даты и времени;

• типа даты и времени в символьный.

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

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

Преобразование символьных строк в числа

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

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

2. При неформатированном выводе числовые значения выравниваются по правому краю, а символьные строки - по левому.

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

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

SELECT SUM(LENGTH(LAST_NAME) + LENGTH{FIRST_NAME)) TOTAL

FROM EMPLOYEE_TBL;

TOTAL

--------

71

1 строка выбрана.

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

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

Резюме

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

Вопросы и ответы

Все ли функции относятся к стандарту ANSI?

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

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

Нет. При использовании функций сами данные не меняются. Функции используются в запросах для изменения только представления данных при выводе.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Свяжите описания с подходящими функциями.

Описания______________________________Функции_____

а. Используется для | |I

извлечения части строки RPAD

из данной строки LPAD

б. Используется для LENGTH

обрезания части строки UPPER

в ее начале или конце

в. Используется для LTRIM

изменения регистра RTRIM

всех символов строки на нижний LOWER

г. Используется для SUBSTR

выяснения длины строки

д. Используется для объединения строк

2. Верно ли следующее утверждение: "При использовании в запросе функций для изменения отображения выводимых данных изменяется также и пред* ставление данных в самой базе данных?"

3. Верно ли следующее утверждение: "При использовании в запросах сложных выражений, где одни функции оказываются вложенными в другие, внешняя функция всегда выполняется первой?"

Упражнения

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

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

3. С помощью подходящей функции соедините строки Джон и СОН в одну.

12-й час Работа с датами и временем

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

Основными на этом уроке будут следующие темы.

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

• В каком виде хранятся значения дат и времени

• Типичные форматы дат и времени

• Использование функций дат и времени

• Преобразования дат и времени

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

Как хранятся даты?

В каждой реализации языка есть формат хранения дат, принятый по умолчанию. Такие форматы для различных реализаций SQL часто оказываются разными, но то же самое можно сказать и о форматах хранения других типов данных. В следующих разделах рассматривается стандартный формат и его составляющие для данных типа DATETIME- После этого мы с вами ознакомимся с особенностями представления дат и времени в основных реализациях SQL, таких как Oracle, Sybase и Microsoft SQL Server.

Стандартные типы данных для дат и времени

Имеется три стандартных типа данных SQL, предназначенных для хранения дат и времени (DATETIME).

Тип данных____ Использование

DATE Для хранения значений дат

Т1МЕ Для хранения значений времени

TIMESTAMP Для хранения значений дат и времени

Формат и диапазон допустимых значений для этих типов данных следующий.

DATE_______________

Формат: гпт-ММ-дд

Диапазон допустимых значений: от 0001-01-01 до 9999-12-31

TIME___________

Формат: чч: мм: сс.пп

Диапазон допустимых значений: от 00:00:00... до 23:59:61.999...

TIMESTAMP_________

Формат: гггг-ММ-ДД чч: мм: сс.пп

Диапазон допустимых значений: от 0001-01-01 ОО'ОО'ОО ' до 9999-12-31 23:59:61.999...

Компоненты типа DATETIME

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

YEAR (ГОД) ОТ 0001 ДО 9999

MONTH (месяц) от 01 до 12

DAY (день) от 01 до 31

HOUR (час) от оо до 23

MINUTE (минута) от оо До 59

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

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

Как и для других типов данных, разные реализации SQL предлагают свои представления и синтаксис. В этом разделе мы поговорим о том, как с датами и временем обращаются Oracle, Sybase и SQLBase.

Продукт___Тип данных_____Использование_______________________

Oracle DATE Хранит дату и время вместе

Sybase DATETIME Хранит дату и время вместе

SMALLDATETIME Хранит дату и время вместе, но допускает более

узкий диапазон для дат, чем DATETIME

SQLBase DATETIME Хранит дату и время вместе

TIMESTAMP Хранит дату и время вместе

DATE Хранит дату

TIME Хранит время

Каждая реализация языка предлагает свои типы данных для дат и времени, но чаще всего реализации поддерживают стандарт ANSI в том смысле, что все компоненты даты и времени включены в соответствующие типы данных Но то, в каком внутреннем формате хранятся значения дат и времени, зависит от конкретной реализации языка

Функции для работы с датами

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

Текущая дата

Наверное, вы уже подумали: "Как получить из базы данных информацию о текущем времени?" Такая необходимость может возникнуть в самых разных ситуациях, но обычно текущая дата бывает необходима для сравнения со значениями дат, хранящимися в базе данных, или для использования текущей даты в качестве временной метки.

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

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

В Sybase для получения системной даты используется функция GETDATE() • В запросах эта функция используется следующим образом (в данном случае текущей датой оказался новогодний вечер конца 1999 года).

SELECT GETDATEO

Dec 31, 1999

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

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

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

SELECT SYSDATE FROM ИМЯ_ТАБЛИЦЫ;

31-DEC-99

Часовые пояса

При работе с датами и временем может возникнуть необходимость учитывать различия во времени для разных часовых поясов. Например, 6 часов вечера в США не соответствует 6 часам вечера в Австралии, хотя с точки зрения мирового времени рассматривается один момент. Там, где используется летнее и зимнее время, приходится корректировать показания часов дважды в год. Если это необходимо, имеется возможность учесть различия во времени или осуществить необходимую корректировку времени с помощью подходящих операторов SQL, если таковые соответствующей реализацией языка предусмотрены.

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

Сокращение____ Расшифровка_________

AST, ADT Атлантическое (нью-йоркское) поясное время, летнее время

BST, ВDT Берингово поясное время, летнее время

СSт, CDT Центральное поясное время, летнее время

EST, EDT Восточное пояснее время, летнее время

GMT Всемирное (гринвичское среднее) время или время по Гринвичу

HST, НОТ Гавайское поясное время, летнее время

NST Ньюфаундлендское поясное время

PST, PDT Тихоокеанское время, летнее время

YST, YDT Юкона поясное время, летнее время

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

Добавление интервалов времени к датам

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

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

DATE 4999-12-31' + INTERVAL Ч' DAY

'2000-01-01'

DATE 4999-12-31' + INTERVAL '!' MONTH

'2000-01-31'

В следующем примере используется функция DATEADD SQL Server.

SELECT DATEJHIRE, DATEADD(MONTH, 1, DATE_HIRE)

FROM EMPLOYEE_PAY_TBL

DATE_HIRE DATEADD(M)

23-MAY-89 23-JUN-89

17-JUN-90 17-JUL-90

14-AUG-94 14-SEP-94

28-JUN-97 28-JUL-97

22-JUL-96 22-AUG-96

14-JAN-91 14-FEB-91

6 rows affected.

В следующем примере используется функция ADD_MONTH Oracle.

SELECT DATEJHIRE, ADD_MONTH(DATE_HIRE,1)

FROM EMPLOYEE_PAY_TBL;

DATE_HIRE ADD_MONTH

23-MAY-89 23-JUN-89

17-JUN-90 17-JUL-90

14-AUG-94 14-SEP-94

28-JUN-97 28-JUL-97

22-JUL-96 22-AUG-96

14-JAN-91 14-FEB-91

6 rows selected.

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

SELECT DATE_HIRE, DATE_HIRE + 1

FROM EMPLOYEE_PAY_TBL

WHERE EMP_ID = '311549902';

DATE_HIRE DATE_HIRE

23-MAY-89 24-MAY-89 1 row selected.

Обратите внимание на то, что эти примеры из Oracle и SQL Server хотя и отличаются синтаксически от стандарта ANSI, по сути базируются на тех же принципах, что и стандарт SQL.

Сравнение дат и значений времени

Очень полезным условным оператором стандарта SQL для значений типа DATETIME является оператор OVERLAPS. Оператор OVERLAPS используется для сравнения двух отрезков времени и возвращает TRUE (Истина), если эти отрезки времени пересекаются, и FALSE (Ложь) - если нет. Например, в результате следующего сравнения возвращается значение TRUE:

(TIME '01:00:00', TIME '05:59:00')

OVERLAPS

(TIME '05:00:00', TIME '07:00:00')

В результате следующего сравнения возвратится значение FALSE:

(TIME '01:00:00', TIME '05:59:00')

OVERLAPS

(TIME '06:00:00', TIME '07:00:00')

Другие функции для работы с датами

В следующем списке представлены некоторые полезные функции для работы с датами, предлагаемые реализациями Oracle и SQL Server.

DATE PART Возвращает числовое (целое) значение DATE PART для даты

DATENAME Возвращает текстовое значение DATEPART для даты

GETDATE () Возвращает системную дату

DATEDIFF Возвращает разность двух дат для указанных компонентов,

таких как дни, минуты или секунды

NEXT_DAY Возвращает для указанной даты следующий день недели в

заданном виде(например, ПЯТНИЦА)

MONTH_BETWEEN Возвращает число месяцев между двумя заданными датами

Преобразования дат

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

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

• необходимость сравнения значений дат разных типов;

• необходимость представления значений дат в виде строк заданного формата;

• необходимость конвертирования символьных строк в формат даты.

Для конвертирования одних типов данных в другие используется ANSI-оператор CAST. Его базовый синтаксис следующий.

CAST ( выражение AS новый тип данных )

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

Шаблоны представления дат

Шаблон представления даты (date picture) состоит из элементов форматирования и используется для извлечения из базы данных информации о дате и времени в требуемом виде. В некоторых реализациях SQL использование шаблонов представления дат не предусмотрено.

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

1999-12-31

31-DEC-99

1999-12-31 23:59:01.11

Но как быть, если дату нужно представить, например, в следующем виде?

December 31, 1999

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

Шаблоны представления дат Sybase

УУ год

qq квартал

mm месяц

dy день года

wk неделя

dw день недели

hh час

mi минута

ss секунда

ms миллисекунда

Шаблоны представления дат Oracle_____________________________

AD Н. Э.

AM ДО ПОЛУДНЯ

ВС ДО Н. Э.

CC столетие

D номер дня недели

DD номер дня месяца

DDD номер дня года

DAY название дня недели (MONDAY)

Day название дня недели (Monday)

day название дня недели (monday)

Шаблоны предстявления дат Oracle

DY

Dy

dy

HH

НН12

НН24

J

MI

MM

MON

Mon

mon

MONTH

Month

month

PM

Q

KM

RR

3

SSSSS

SYYYY

W

WW

Y

YY

YYY

YYYY

YEAR

Year

year

трехбуквенное сокращение для дня недели (MON)

трехбуквенное сокращение для дня недели (Моп)

трехбуквенное сокращение для дня недели (топ)

час дня

час дня

час дня в 24-часовом формате

день по юлианскому календарю с 12-31-4713 до н. э.

минута часа

номер месяца

трехбуквенное сокращение для месяца (JAN)

трехбуквенное сокращение для месяца (Jan)

трехбуквенное сокращение для месяца (Jan)

название месяца (JANUARY)

название месяца (January)

название месяца (January)

после полудня

номер квартала

римский номер месяца

две цифры года

секунда минуты

число секунд со времени полуночи

год со знаком: например, 500 г. до н. э. = -500

номер недели месяца

номер недели года

последняя цифра года

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

последние три цифры года

год

год словами (NINETEEN-NINETY-NINE)

год словами (Nineteen-Ninety-Nine)

год словами (nineteen-ninety-nine)

Преобразование дат в строки символов

Значения типа DATETIME конвертируют (преобразуют) в символьные строки для того, чтобы иметь возможность изменить представление дат при выводе данных запроса. Для этого используются функции преобразования. Вот пример преобразования значения даты и времени в символьную строку в запросе SQL Server:

SELECT DATE_HIRE = DATENAME(MONTH, DATE_HIRE)

FROM EMPLOYEE_PAY__TBL

DATE_HIRE

May

June

August

June

July

January

6 rows affected.

В следующем примере для преобразования используется функция TO_CHAR из Oracle:

SELECT DATE_HIRE, TO_CHAR(DATE_HIRE,'Month dd, yyyy') HIRE

FROM EMPLOYEE_PAY_TBL;

DATE_HIRE HIRE

23-MAY-89 May 23, 1989

17-JUN-90 June 17, 1990

14-AUG-94 August 14, 1994

28-JUN-97 June 28, 1997

22-JUL-96 July 22, 1996

14-JAN-91 January 14, 1991

6 rows selected.

Преобразование символьных строк в даты

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

SELECT TO_DATE('JANUARY 01 1999','MONTH DD YYYY')

FROM EMPLOYEE_PAY_TBL;

TO_DATE('

Ol-JAN-99

Ol-JAN-99

Ol-JAN-99

Ol-JAN-99

Ol-JAN-99

Ol-JAN-99

6 rows selected.

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

Резюме

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

Вопросы и ответы

По каким причинам в различных реализациях наблюдаются отклонения от стандартного набора типов данных и функций?

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

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

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Откуда извлекаются системные дата и время?

2. Назовите стандартные компоненты значения типа DATETIME.

3. Какой фактор может оказаться важным при представлении и сравнении значений дат и времени, если ваша компания имеет статус международной организации?

4. Можно ли сравнить значение даты в виде символьной строки со значением даты типа DATETIME?

Упражнения

Запишите операторы SQL для представленных ниже упражнений, основываясь на следующей информации.

Используйте SYSDATE для получения текущих даты и времени. Используйте таблицу с именем DATES.

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

TO_CHAR('выражение','шаблон представления даты')

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

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

Шаблон представления дат___Описание___________________

MONTH название месяца

DAY название дня недели

DD номер дня месяца

мм номер месяца года

YY последние две цифры года

YYYY ГОД

MI минута часа ss секунда минуты

1. Предположив, что сегодняшней датой является 1999-12-31, преобразуйте текущую дату в формат December 31 1999.

2. Преобразуйте строку 'DECEMBER 31 1999' в формат DATE.

3. Запишите оператор, возвращающий день недели, на который выпадает новогодний вечер конца 1999 года. Предположите, что дата хранится в виде 31-DEC-99, являясь значением типа DATETIME.

13-й час Объединение таблиц в запросах

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

Основными на этом уроке будут следующие темы.

• Основные подходы к связыванию таблиц

• Различные типы связей

• Как и когда следует использовать связывание таблиц

• Ряд практических примеров связывания таблиц

• Последствия неправильного связывания таблиц

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

Отбор данных из нескольких таблиц

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

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

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

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

Типы связывания

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

• связывание по равенству (EQU JOINS):

• естественное связывание (NATURAL JOINS);

• связывание по неравенству (NON-FQUUOINS);

• внешнее связывание (OUTEP JCINS);

• рекурсивное связывание (SELF JOINS).

Компоненты условия связывания

Как вы уже знаете из предыдущих уроков, ключевые слова SELECT и FROM являются необходимыми элементами оператора SQL, определяющего запрос. При связывании таблиц необходимым элементом оператора SQL является ключевое слово WHERE. Имена таблиц для связывания указываются в списке ключевого слова FROM. Связь определяется в выражении ключевого слова WHERE В выражении для связывания таблиц можно использовать операции =, <, >, <>, -.-, >-, '=, BETWEEN, LIKE и NOT. Но наиболее часто для связывания используется знак равенства

Связывание по равенству

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

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

SELECT таблица1.столбец1, таблица2.столбец2...

FROM таблица1, таблица2 [, таблицаЗ ]

WHER3 таблица1.имя_столбца = таблица2.имя_столбца

[ AND таблица1.имя_столбца - таблицаЗ.имя столбца ]

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

Рассмотрим пример.

SELECT EMPLOYF,E_TBL.EMP_ID,

EMPLOYEE_PAY_TBL.DATE_HIRE FROM EMPLOYEEJTBL,

EMPLOYEE_PAY_TBL WHERE EKPLOYEE_TBL.EMP_ID = EMPLOYEE_PAY_TBL . EMP__ ID;

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

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

SELECT EMPLOYEE_TBL.EMP_ID, EMPLOYEE_TBL.LAST_NAME,

EMPLOYEE_PAY_TBL.POSITION

FROM EMPLOYEEJTBL, EMPLOYEE_PAY_TBL

WHEREEMPLOYEE_TBL.EMP_ID = EMPLOYEE_PAY_TBL.EMP_ID;

EMP_ID LAST_NAM POSITION

311549902 STEPHENS MARKETING

442346889 PLEW TEAM LEADER

213764555 GLASS SALES MANAGER

313782439 GLASS SALESMAN

220984332 WALLACE SHIPPER

443679012 SPURGEON SHIPPER

6 строк выбраны.

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

Естественное связывание

Естественное связывание почти эквивалентно связыванию по равенству, но при естественном связывании таблиц повторения эквивалентных столбцов исключаются. Условие связывания оказывается таким же, но столбцы выбираются иначе.

Синтаксис соответствующего оператора следующий.

SELECT таблица1.*, таблица2.имя_столбца

[, таблицаЗ.имя_столбца ]

FROM таблица1, таблица2 [,таблицаЗ ]

WHERE таблица1.имя_столбца = таблица2.имя_столбца

[ AND таблица1.имя_столбца = таблицаЗ.имя~столбца ]

Например,

SELECT EMPLOYEEJTBL.*, EMPLOYEE_PAY_TBL.SALARY FROM EMPLOYEEJTBL,

EMPLOYEE_PAY_TBL WHERE EMPLOYEE_TBL.EMP_ID = EMPLOYEE_PAY_TBL.EMP_ID;

Этот оператор SQL возвращает данные всех столбцов из таблицы EMPLOYEE_TBL и значения SALARY из таблицы EMPLOYEE_PAY_TBL. Столбец EMP_ID имеется в обеих таблицах, но извлекается только из таблицы EMPLOYEE_TBL, поскольку во второй таблице соответствующий столбец содержит точно такую же информацию и поэтому извлекать ее нет смысла.

В следующем примере выбираются все столбцы из таблицы EMPLOYEE_TBL и один столбец из таблицы EMPLOYEE_PAY_TBL. He забывайте о том, что звездочка (*) представляет все столбцы таблицы

SELECT EMPLOYEE_TBL.*, EMPLOYEE_PAY_TBL.POSITION

FROM EMPLOYEEJTBL, EMPLOYEE_PAY_TBL

WHERE EMPLOYEE_TBL.EMP_ID = EMPLOYEE_PAY_TBL.EMP_ID;

EMP_ID LAST_NAM FIRST_NAM ADDRESS CITY ST ZIP PHONE PAGER POSITION

311549902 STEPHENS TINA D RR 3 BOX 17A GREENWOOD IN 47890

3178784465 MARKETING

442346889 PLEW LINDA С 3301 BEACON INDIANAPOLIS IN 46224

3172978990 TEAM LEADER

213764555 GLASS BRANDON S 1710 MAIN ST WHITELAND IN 47885

3178984321 3175709980 SALES MANAGER

313782439 GLASS JACOB 3789 RIVER BLVD INDIANAPOLIS IN 45734

3175457676 8887345678 SALESMAN

220984332 WALLACE MARIAH 7789 KEYSTONE INDIANAPOLIS IN 46741

3173325986 SHIPPER

443679012 SPURGEON TIFFANY 5 GEORGE COURT INDIANAPOLIS IN 46234

3175679007 SHIPPER

6 строк выбраны.

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

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

Использование псевдонимов для имен таблиц означает переименование таблицы в рамках используемого оператора SQL. При этом истинное имя таблицы в базе данных не меняется. Как мы с вами увидим ниже, назначение таблице псевдонима необходимо при рекурсивном связывании (SELF JOIN). Часто псевдонимы назначаются таблицам с целью сокращения объема печатания, в результате чего операторы SQL становятся короче и проще для понимания. Кроме того, чем меньше печатать, тем меньше будет ошибок При назначении таблицам псевдонимов псевдонимы должны использоваться и при точном определении столбцов. Вот пример использования псевдонимов таблиц и соответствующее использование столбцов.

SELECT E.EMP_ID, EP.SALARY, EP.DATE_HIRE, E.LAST_NAME

FROM EMPLOYEEJTBL E,

EMPLOYEE_PAY_TBL EP

WHERE E.EMP_ID = EP.EMP_ID

AND EP.SALARY > 20000;

В этом примере таблицам назначаются псевдонимы. Вместо имени EMPLOYEE_TBL используется Е, поскольку имя этой таблицы начинается с Е. Имя второй таблицы, EMPLOYEE_PAY_TBL, тоже начинается с Е, но для нее используется псевдоним ЕР, поскольку псевдонимы разных таблиц в одном операторе должны быть разными. Выбранные столбцы приравниваются с использованием псевдонимов таблиц. Обратите внимание на то, что для используемого в выражении ключевого слова WHERE имени столбца SALARY тоже должен использоваться псевдоним соответствующей таблицы.

Связывание по неравенству

При связывании по неравенству (NON-EQUIJOINS) две или несколько таблиц объединяются по условию неравенства значения столбца таблицы значению из столбца другой таблицы.

Синтаксис соответствующей части оператора следующий.

FROM таблица1, таблица2 [,таблицаЗ ]

WHERE таблица1.имя_столбца != таблица2.имя_столбца

[ AND таблица1.имя_столбца != таблицаЗ.имя_столбца ]

Например,

SELECT EMPLOYEE_TBL.EMP_ID, EMPLOYEE_PAY TBL.DATE_HIRE

FROM EMPLOYEE_TBL,

EMPLOYEE_PAY_TBL

WHERE EMPLOYEE_TBL.EMP_ID != EMPLOYEE_PAY_TBL.EMP_ID;

Этот оператор SQL возвратит табельный номер служащего и даты поступления на работу для всех служащих с несоответствующими табельными номерами Вот пример связывания по неравенству из реальной базы данных

SELECT E.EMP_ID, E.LAST_HAME, P.POSITION

FROM EMPLOYEE_TBL E,

EMPLOYEE_PAY_TBL P

WHERE E.EMP_ID = P.EMP_ID;

EMP_ID LAST_NAM POSITION

442346889 PLEW MARKETING

213764555 GLASS MARKETING

313782439 GLASS MARKETING

220984332 WALLACE MARKETING

443679012 SPURGEON MARKETING

311549902 STEPHENS TEAM LEADER

213764555 GLASS TEAM LEADER

313782439 GLASS TEAM LEADER

220984332 WALLACE TEAM LEADER

443679012 SPURGEON TEAM LEADER

311549902 STEPHENS SALES MANAGER

442346889 PLEW SALES MANAGER

313782439 GLASS SALES MANAGER

220984332 WALLACE SALES MANAGER

443679012 SPURGEON SALES MANAGER

3115499C2 STEPHENS SALESMAN

442346889 PLEW SALESMAN

213764555 GLASS SALESMAN

220984332 WALLACE SALESMAN

443679012 SPURGEON SALESMAN

311549902 STEPHENS SHIPPER

442346889 PLEW SHIPPER

213764555 GLASS SHIPPER

313782439 GLASS SHIPPER

30 строк выбраны.

Вы, наверное, удивитесь, что в данном случае из базы данных были извлечены 30 строк данных, хотя в таблице имеется всего 6 записей Объяснение этому следующее. Каждой записи из таблицы EMPLOYEE_TBL соответствует запись из таблицы EMPLOYEE_PAY_TBL. Но по причине связывания по неравенству каждой записи из первой таблицы сопоставляются все записи второй таблицы, за исключением той самой единственной соответствующей записи Значит, каждая строка первой таблицы оказывается связанной с пятью строками второй. Записей всего 6, поэтому в результате мы получаем 30 строк.

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

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

Внешнее связывание

Внешнее связывание (OUTER JOIN) используется, когда вывод должен содержать все записи одной таблицы, даже если некоторые из ее записей не имеют соответствующих записей в другой таблице. В запросе для задания внешнего связывания используется (+). Символ (+) помещается в конце имени таблицы в выражении ключевого слова WHERE. Таблицей с символами ( + ) должна быть та таблица, записям которой нет соответствующих записей из другой таблицы. Во многих реализациях языка внешнее связывание разбито на левое внешнее связывание (LEFT OUTER JOIN), правое внешнее связывание (RIGHT OUTER JOIN) и полное внешнее связывание (FULL OUTER JOIN). В таких реализациях внешнее связывание (OUTER JOIN) обычно является опцией.

Обязательно проверьте правила использования внешнего связывания и синтаксис соответствующих операторов по документации той реализации языка, с которой вы работаете Символы ( + ) используются в большинстве основных реализаций SQL, но стандартом они не задаются

Общий синтаксис следующий.

FROM таблица1

{RIGHT | LEFT | FULL} [OUTER] JOIN

ON таблица2

В Oracle используется следующий синтаксис.

FROM таблица1, таблица2 [,таблицаЗ ]

WHERE таблица1.имя_столбца[(+)] = таблица2.имя_столбца[(+)]

[ AND таблица!.имя_столбца[(+)] = таблицаЗ.имя_столбца[(+)]]

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

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

SELECT P.PROD_DESC, О. QTY

FROM PRODUCTS_TBL P,

ORDERS_TBL О

WHERE P.PROD_ID = O.PROD_ID;

PRODJ3ESC QTY

КОСТЮМ ВЕДЬМЫ 1

ПЛАСТИКОВЫЕ ТЫКВЫ 25

ПЛАСТИКОВЫЕ ТЫКВЫ 2

ФОНАРИ 10

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 20

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 1

6 строк выбраны.

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

В следующем примере эта задача решается с помощью внешнего связывания. Для соответствующего оператора используется синтаксис Oracle.

SELECT P.PROD_DESC, О.QTY

FROM PRODUCTS_TBL P,

ORDERS_TBL О

WHERE P . PROD_ID = О . PROD_ID (+);

PROD_DESC QTY

КОСТЮМ ВЕДЬМЫ 1

МАСКИ В АССОРТИМЕНТЕ

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ 20

КОСТЮМЫ В АССОРТИМЕНТЕ

ПЛАСТИКОВЫЕ ТЫКВЫ 25

ПЛАСТИКОВЫЕ ТЫКВЫ 2

ТЫКВЕННЫЕ КОНФЕТЫ

ПЛАСТИКОВЫЕ ПАУКИ

СЛАДКАЯ КУКУРУЗА

ФОНАРИ 10

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ 1

ПОЛОЧКА ИЗ ДУБА

12 строк выбраны.

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

Рекурсивное связывание

Рекурсивное связывание (SELF JOIN) предполагает связывание таблицы с ней же самой, как будто бы это были две таблицы, применяя временное переименование таблицы в операторе SQL. Синтаксис такого оператора следующий.

SELECT А.имя_столбца, В.имя_столбца [, С.имя_столбца ]

FROM таблица1 А, таблица2 В [, таблицаЗ С ]

WHERE А.имя_столбца = В.имя_столбца

[ AND А.имя_столбца = С.имя_столбца ]

Например,

SELECT A.LASTJJAME, B.LAST_NIME, A.FIRST_NAME

FROM EMPLOYEE_TBL A,

EMPLOYEEJTBL В

WHERE A.LAST_NAME = B.LAST_NAME;

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

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

SELECT FROM EMP;

ID NAME MNGR_ID

1 JOHN 0

2 MARY 1

3 STEVE 1

4 JACK 2

5 SUE 2

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

SELECT El.NAME, E2.NAME

FROM EMP El, EMP E2

WHERE E1.MGR_ID = E2.ID;

NAME NAME

MARY JOHN

STEVE JOHN

JACK MARY

SUE MARY

Связывание по нескольким ключам

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

Рассмотрим для примера следующие таблицы.

SQL> desc prod

Имя NULL? Тип данных

SERIAL_NUMBER NOT NULL NUMBER(10)

VENDOR_NUMBER NOT NULL NUMBER(10)

PRODUCT_NAME NOT NULL VARCHAR2OO)

COST NOT NULL NITMBER (8,2)

SQL> desc prod NULL? Тип данных

ORD_NO NOT NULL NUMBER(10)

SERIAL_NUMBER NOT NULL NUMBER(10}

VENDOKJMUMBER NOT NULL NUMBER(10)

QUANTITY NOT NULL NUMBERt5)

ORD_DATE NOT NULL DATE

Ключом в таблице PROD является комбинация столбцов SERTAL_NUMBER и VENDOR_NUMBER Верояшо, в данной торговой компании некоторые товары имеют один серийный номер, но различаются по коду производителя

Внешним ключом в таблице ORD тоже является комбинация столбцов

SERIAL_NUMBER И VENDOR_NUMBER.

При выборе данных из обеих таблиц (PROD и ORD) оператор связывания может выглядеть следующим образом:

SELECT Р.PRODUCT_NAME, O.ORD_DATE, О.QUANTITY

FROM PROD P, ORD О

WHERE P.SERIAL_NUMBER = 0.SER1AL_NUMBER

AND P.VENDOR_NUMBER = О.VENDOR_NUMBER;

Вопросы связывания

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

Использование связующей таблицы

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

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

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

CUSTOMER_TBL

CUST_IDVARCHAR2(10) NOT NULL Ключевое поле

CUST_NAME VARCHAR2(30) NOT NULL

CUST_ADDRESS VARCHAR2(20) NOT NULL

CUST_CITY VARCHAR2U5) NOT NULL

CUST_STATE CHAR(2) NOT NULL

CUST_ZIP NUMBER(5) NOT NULL

CUST_PHONE NUMBER(10)

CUST_FAX NUMBER(10)

ORDERS_TBL

ORD_NUMVARCHAR2(10) NOT NULL Ключевое поле

CUST_ID VARCHAR2(10) NOT NULL

PROD_ID VARCHAR2(10) NOT NULL

QTY NUMBER(6) NOT NULL

ORD_DATE DATE

PRODUCTS_TBL

PROD_ID VARCHAR2UO) NOT NULL Ключевое поле

PROD_DESC VARCHAR2(40) NOT NULL

COST NUMBER (6,2) NOT NULL

Необходимо использовать таблицы CUSTOMERJTBL и pfi ODUCTS_TBL. У этих таблиц нет общих столбцов, по которым можно было бы выполнить связывание. Приходится использовать таблицу ORDERS_TBL, в которой имеется поле CUST_ID, присутствующее и в таблице CUSTOMER_TBL, и в таблице PRODUCTS_TBL. Условия связывания и результаты выглядят следующим образом.

SELECT C.CUST_NAME, P.PROD_DESC FROM CUSTOMER_TBL С,

PRODUCTS_TBL P,

ORDERS_TBL О

WHERE C.CUST_ID = O.CUST_ID AND P.PROD_ID = O.PROD_ID;

CUST_NAME PROD_DESC

LESLIE GLEASON КОСТЮМ ВЕДЬМЫ

SCHYLERS NOVELTIES ПЛАСТИКОВЫЕ ТЫКВЫ

WENDY WOLF ПЛАСТИКОВЫЕ ТЫКВЫ

GAVINS PLACE ФОНАРИ

SCOTTYS MARKET ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

ANDYS CANDIES ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

6 строк выбраны.

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

Декартово произведение

Декартово произведение является результатом декартова связывания (CARTESIAN JOIN) или отсутствия связывания таблиц в запросе. Если в запросе указываются две или более таблиц и не используется их связывание, то в выводе будут присутствовать все возможные комбинации строк выбранных таблиц. Если таблицы большие, в результате получится, может быть, сотни, тысячи или даже миллионы записей. При использовании в запросе декартова произведения таблиц настоятельно рекомендуется использовать ключевое слово WHERE. Декартово произведение таблиц иначе называется кросс-связыванием (cross join).

Синтаксис соответствующей части оператора следующий.

FROM таблица1, таблица2 [,таблицаЗ ]

WHERE таблица1, таблица2 [,таблицаЗ ]

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

SELECT E.EMP_ID, E.LAST_NAME, P.POSITION

FROM EMPLOYEE_TBL E,

EMPLOYEE_PAY_TBL P;

EMP ID

LAST NAM

POSITION

311549902 442346889 213764555 313782439 220984332 443679012 311549902 442346889 213764555 313782439 220984332 443679012 311549902 442346889 213764555 313782439 220984332 443679012 311549902 442346889 213764555 313782439 220984332 443679012 311549902 442346889 213764555 313782439 220984332 443679012 311549902 442346889 213764555

STEPHENS PLEW GLASS GLASS WALLACE SPURGEON STEPHENS PLEW GLASS GLASS WALLACE SPURGEON STEPHENS PLEW GLASS GLASS WALLACE SPURGEON STEPHENS PLEW GLASS GLASS WALLACE SPURGEON STEPHENS PLEW GLASS GLASS WALLACE SPURGEON STEPHENS PLEW GLASS

MARKETING MARKETING MARKETING MARKETING MARKETING MARKETING TEAM LEADER TEAM LEADER TEAM LEADER TEAM LEADER TEAM LEADER TEAM LEADER SALES MANAGER SALES MANAGER SALES MANAGER SALES MANAGER SALES MANAGER SALES MANAGER SALESMAN SALESMAN SALESMAN SALESMAN SALESMAN SALESMAN SHIPPER SHIPPER SHIPPER SHIPPER SHIPPER SHIPPER SHIPPER SHIPPER SHIPPER

313782439 220984332 443679012

GLASS WALLACE SPORGEON

SHIPPER SHIPPER SHIPPER

36 строк выбраны.

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

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

SQL> SELECT X FROM TABLE1;

X

-

A

В

С

D

4 строки выбраны

SQL> SELECT X FROM TABLE2;

X

-

A

В

С

D

4 строки выбраны.

SQL> SELECT TABLE1.X, TABLE2.X

2* FROM TABLE1, TABLE2;

X X

_ _

A A

В А

С А

D A

А В

в в

с в

D В

А С

в с

с с

D С

A D

В D

С D

D D

16 строк выбраны.

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

Резюме

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

Вопросы и ответы

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

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

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

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

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

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

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

2. Какая часть оператора SQL задает условия связывания таблиц?

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

4. Что будет, если в запросе указать выборку из двух таблиц, но не связать их?

5. Рассмотрите следующие таблицы.

ORDERS_TBL

ORD_NUM VARCHAR2(10) NOT NULL Ключевое поле

CUST_ID VARCHAR2(10) NOT NULL

PROD_ID VARCHAR2(10) NOT NULL

QTY NUMBER(6) NOT NULL

ORD_DATE DATE

PRODUCTS TBL

PROD_ID VARCHAR2CLO) NOT NULL Ключевое поле

PROD_DESC VARCHAR2(40) NOT NULL

COST NUMBER (6,2) NOT NULL

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

SELECT C.CUST_ID, C.CUST_NAME, О.ORD_NUM

FROM CUSTOMERJTBL С, ORDERS_TBL 0

WHERE C.CUST_ID{+) = O.CUST_ID(+)

Упражнения

Выполните упражнения для следующих таблиц.

EMPLOYEE TBL

EMP ID VARCHAR2(9) NOT NULL Ключевое поле

LAST NAME VARCHAR2(i5) NOT NULL

FIRST NAME VARCHAR2(15) NOT NULL

MIDDLE NAME VARCHAR2 ( 15 }

ADDRESS VARCHAR2(30) NOT NULL

CITY VARCHAR2(15) NOT NULL

STATE CHAR (2) NOT NULL

ZIP NUMBER (5) NOT NULL

PHONE CHAR (10)

PAGER CHAR (10)

EMPLOYEE PAY TBL

EMP ID VARCHAR2O) NOT NULL Ключевое поле

POSITION VARCHAR2U5) NOT NULL

DATE HIRE DATE PAY RATE NUMBER (4,2) NOT NULL

DATE LAST-RAISE DATE SALARY NUMBER (6,2)

BONUS NUMBER (4,2)

CONSTRAINT EMP FK FOREIGN KEY (EMP ID) REFERENCED EMPLOYEE TBL (EMP ID)

CUSTOMERS TBL

CUST ID CUST NAME CUST ADDRESS CUST CITY

CUST STATE CUST ZIP CUST PHONE CUST_FAX

VARCHAR2 (10) VARCHAR2 (30) VARCHAR2 (20) VARCHAR2 (15) CHAR ( 2 ) NUMBER (5) NUMBER (10) NUMBER (10)

NOT NULL NOT NULL NOT NULL NOT NULL NOT NULL NOT NULL

Ключевое поле

ORDERS TBL

ORD NUM CUST ID PROD ID QTY ORD DATE

VARCHAR2 (10) VARCHAR2 (10) VARCHAR2(10) NUMBER (6) DATE

NOT NULL NOT NULL NOT NULL NOT NULL

Ключевое поле

PRODUCTS TBL

PROD ID PROD DESC COST

VARCHAR2 (10) VARCHAR2 (40) NUMBER (6, 2)

NOT NULL NOT NULL NOT NULL

Ключевое поле

1. Запишите оператор SQL, возвращающий EMP_ID, LAST_NAME и FIRST NAME из таблицы EMPLOYEE_TBL; SALARY и BONUS из таблицы EMPLOYEE_PAYJTBL.

2. Выберите из таблицы CUSTOMERS_TBL столбцы CUST_ID и CUST "NAME из таблицы PRODUCTS_TBL - столбцы PROD_ID и COST, а из таблицы ORDERS_TBL - ORD_NUM и QTY. Объедините три эти таблицы в одном оператопе SOL.

14-й час Использование подзапросов

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

• Что такое подзапрос?

• Выравнивание выводимых данных с помощью подзапросов

• Примеры типичных подзапросов к базе данных

• Использование подзапросов с операторами языка манипуляций данными

• Вложенные подзапросы

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

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

В некоторых случаях подзапрос можно использовать вместо связывания таблиц, тем самым связывая данные таблиц неявно. При использовании в запросе подзапроса сначала выполняется подзапрос, а только потом - содержащий его запрос, причем с учетом условий выполнения подзапроса. Результаты выполнения подзапроса используются при обработке условий в выражении ключевого слова WHERE основного запроса Подзапрос можно использовать либо в выражении ключевого слова WHERE, либо в выражении ключевого слова HAVING главного запроса. Логические операции и операции сравнения типа =, >, <, о, IN, NOT IN, AND, OR и т п. можно использовать как в подзапросе, так и для обработки результатов подзапроса в выражениях ключевых слов WHERE и HAVING.

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

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

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

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

• Ключевое слово ORDER BY использовать в подзапросе нельзя, хотя в главном запросе ORDER BY использоваться может. Вместо ORDER BY в подзапросе можно использовать GROUP BY.

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

• В списке ключевого слова SELECT не допускаются ссылки на значения типа

BLOB, ARRAY, CLOB ИЛИ NCLOB.

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

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

SELECT имя_столбиа

FROM таблица

WHERE имя_столбца = (SELECT имя__столбца

FROM таблица

WHERE условия);

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

Рассмотрим примеры правильного и неправильного использования операции BETWEEN в операторе с подзапросом.

Вот пример правильного использования BETWEEN:

SELECT имя_столбца

FROM таблица

WHERE имя_столбца ОПЕРАЦИЯ (SELECT имя_столбца

FROM таблица

WHERE значение BETWEEN значение);

Вот пример неправильного использования BETWEEN:

SELECT имя_столбца FROM таблица

WHERE имя_столбца BETWEEN значение AND (SELECT имя_столбца

FROM таблица);

Подзапросы в операторе SELECT

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

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

SELECT имя_столбца [, имя_столбца ]

FROM таблица1 [, таблица2 ]

WHERE имя_столбца ОПЕРАЦИЯ

(SELECT имя_столбца [, имя_столбца ]

FROM таблица1 [, таблица2 ]

[ WHERE ]);

Например,

SELECT E.EMP_ID, E.LAST_NAME, E.FIRST_NAME EP.PAY__RATE

FROM EMPLOYEEJTBL E, EMPLOYEE_PAY_TBL EP

WHERE E.EMP_ID = EP.EMP_ID

AND E?.PAY_RATE > (SELECT PAY_RATE

FROM EMPLOYEE_PAY_TBL

WHERE E.EMP_ID = '313782439');

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

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

SELECT PAY_RATE

FROM EMPLOYEE_PAY_TBL

WHERE E.EXP_IC - ' 220S84332');

PAY_RATE 11

1 строка выбрана.

Теперь используем этот запрос в качестве подзапроса в следующемзапросе.

SELECT E.EMP_ID, E.LAST_NAME, E.FIRST_NAME EP.PAY_RATE

FROM EMPLOYEEJTBL E, EMPLOYEE_PAY_TBL EP

WHERE E.EMP_ID = EP.EMP_ID

AND EP.PAY_RATE > (SELECT PAY_RATE

FROM EMPLOYEE_PAY_TBL

WHERE E.EMP_ID = '220984332');

EMP_ID LAST_NAM FIRST_NAM PAY_RATE

442346889 PLEW LINDA 14.75

443679012 SPURGEON TIFFANY 15

2 строки выбраны.

Результатом подзапроса будет 11 (это видно из предыдущего примера), поэтому второе из условий в выражении ключевого слова WHERE главного запроса преобразуется в условие

AND EP.PAY_RATE > 11

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

ЕМР ID

LAST NAM

FIRST NAM

PAY_RATE

442346889 443679012

PLEW SPURGEON

LINDA TIFFANY

14.75 15

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

Подзапросы в операторе INSERT

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

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

INSERT INTO имя_таблицы [ (столбец! [, столбец2 ]) ]

SELECT [ *| столбец1 [, столбец2 ]]

FROM таблица1 [, таблица2 ]

[ WHERE значение ОПЕРАЦИЯ значение ]

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

INSERT INTO RICH_EMPLOYEES

SELECT E.EMP_ID, E.LAST_NAME, E.FIRST_NAME EP.PAY_RATE

FROM EMPLOYEE_TBL E, EMPLOYEE_PAY_TBL EP

WHERE E.EMP_ID = EP.EMP_ID

AND EP.PAY_RATE > (SELECT PAY_RATE

FROM EMPLOYEE_PAY_TBL

WHERE E.EMP_ID = '220984332');

2 строки созданы.

Этот оператор INSERT вставляет значения EMP_ID, LAST_NAME, FIRST_NAME и PAY_RATE в таблицу RICH_EMPLOYEES для всех служащих, норма оплаты труда которых превышает норму оплаты труда служащего с табельным номером 220984332.

При использовании команд DML типа INSERT не забывайте об использовании команд COMMIT и ROLLBACK

Подзапросы в операторе UPDATE

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

Базовый синтаксис оператора следующий.

UPDATE таблица

SET имя_столбца [, имя_столбца ] =

(SELECT имя_столбца [,имя_столбца ] FROM таблица

[ WHERE ])

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

SELECT EMP_ID

FROM EMPLOYEE_TBL

WHERE CITY = 'INDIANAPOLIS';

EMP_ID

442346889

313782439

220984332

443679012

4 строки выбраны.

Этот запрос будет использован в качестве подзапроса в следующем операторе UPDATE. Вот этот оператор UPDATE с подзапросом.

UPDATE EMPLOYEE_PAY_TBL

SET PAY_RATE = PAY_RATE * 1.1

WHERE EMP_ID IN (SELECT EMP_ID

FROM EMPLOYEE_TBL

WHERE CITY = 'INDIANAPOLIS');

4 строки обновлены.

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

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

Подзапросы в операторе DELETE

Подзапросы можно использовать в операторе DELETE. Базовый синтаксис оператора следующий.

DELETE FROM имя_таблицы

[ WHERE ОПЕРАЦИЯ [ значение ]

(SELECT имя_столбца

FROM имя_таблицы

[ WHERE ])

В следующем примере из таблицы EMPLOYEE_PAY_TBL удаляется запись с информацией о служащем по имени BRANDON GLASS. Табельный номер этого служащего не известен, но можно создать подзапрос, который найдет этот номер в таблице EMPLOYEEJTBL по значениям столбцов с именами (FIRST_NAME) и фамилиями (LAST_NAME) служащих.

DELETE FROM EMPLOYEE_PAY_TBL WHERE EMP_ID = (SELECT EMP_ID

FROM EMPLOYEE_PAY_TBL

WHERE LAST_NAME a 'GLASS'

AND FIRST_NAME = 'BRAHDON');

1 строка обновлена.

He забывайте использовать в операторах UPDATE и DELETE ключевое слово WHERE. Если последнее не использовать, будут обновлены или удалены данные всех столбцов^1 За подробностями обратитесь к уроку 5, "Манипуляция данными"

Подзапросы внутри подзапросов

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

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

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

SELECT имя_столбца [, имя_столбца ]

FROM таблица1 [, таблица2 ]

WHERE имя_столбца ОПЕРАЦИЯ (SELECT имя__столбца

FPOM таблица

WHERE имя_столбца ОПЕРАЦИЯ (SELECT имя_столбца FROM таблица

[WHEREимя_столбца ОПЕРАЦИЯ значение]))

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

SELECT CUST_ID, CUST_NAME

FROM CUSTOMER_TBL

WHERE CUST_ID IN (SELECT O.CUST_ID

FROM ORDERS_TBL O, PRODUCTS_TBL P WHERE 0 PROD_ID = P.PROD_ID

AND O.QTY * P.COST > (SELECT STJM(COST)

FROM PRODUCTS_TBL));

CUST_ID CUST_NAME

287 GAVINS PLACE

43 SCHYLERS NOVELTIES

2 строки выбраны.

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

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

SELECT SUM(COST) FROM PRODUCTS_TBL));

SUM(COST)

138.08 1 строка выбрана.

SELECT O.CUST_ID

FROM ORDERS_TBL O, PRODUCTSJTBL P

WHERE О PROD_ID = P.PROD_ID

AND O.QTY * P.COST > 138.08;

CUST_ID

287

43

2 строки выбраны.

После подстановки в главный запрос результатов внутреннего подзапроса главный запрос принимает следующий вид

SELECT CUST_ID, CUST_NAME

FROM CUSTOMER_TBL

WHERE CUST_ID IN (SELECT O.CUST_ID

FROM ORDERS_TBL O, PRODUCTS_TBL P WHERE О PROD_ID = P.PROD_ID

AND O.QTY * P.COST > 138.08);

А вот что получается после выполнения следующего подзапроса

SELECT CUST_ID, CUST_NAME

FROM CUSTOMER_TBL

WHERE CUST_ID IN '287•,'43');

Поэтому в результате имеем

CUST_ID CUST_NAME

287 GAVINS PLACE

43 SCHYLERS NOVELTIES

2 строки выбраны.

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

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

Связанные подзапросы допускаются во многих реализациях SQL. Концепция связанного подзапроса определяется стандартом ANSI SQL и поэтому рассматривается здесь. Связанный подзапрос - это подзапрос, зависящий от информации, предоставляемой главным запросом.

В следующем примере в подзапросе определение связи между таблицами CUSTOMER_TBL И ORDERSJTBL использует псевдоним таблицы CUSTOMERJTBL (С), определенный в главном запросе. Этот оператор возвращает имена всех покупателей, заказавших более 10 единиц товара.

SELECT C.CUST_NAME

FROM CUSTOMER_TBL С

WHERE 10 < (SELECT SUM(O.QTY)

FROM ORDERS_TBL О

WHERE O.CUST_ID =C.CUST_ID);

CUST_NAME

SCOTTYS MARKET

SCHYLERS NOVELTIES

MARYS GIFT SHOP

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

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

SELECT C.CUST_NAME, SUM(O.QTY)

FROM CUSTOMER_TBL С,

ORDERS_TBL О GROUP BY CUST_NAME;

CUSTJMAME SUM(O.QTY)

GAVINS PLACE 10

LESLIE GLEASON 1

MARYS GIFT SHOP 100

SCHYLERS NOVELTIES 25

SCOTTYS MARKET 20

WENDY WOLF 2

6 строк выбраны.

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

Резюме

Попросту говоря, подзапрос представляет собой запрос, выполняемый в рамках другого запроса для задания дополнительных условий на выводимые данные. Подзапрос можно использовать в выражениях ключевых слов WHERE и HAVING. Подзапросы обычно используют в других запросах (операторах DQL - языка запросов к данным), но подзапросы можно использовать и в операторах DML (языка манипуляций данными) таких, как INSERT, UPDATE и DELETE. Все основные правила использования операторов языка манипуляций данными применимы и при использовании в них подзапросов.

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

Вопросы и ответы

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

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

Имеются ли ограничения на число вложений подзапросов в запросы?

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

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

Лучше всего для отладки выделить из сложного запроса составляющие его запросы. Сначала следует проверить внутренний подзапрос самого низшего уровня и постепенно продвигаться по уровням до главного запроса (точно так же, как запрос обрабатывается базой данных). На каждом шагу после обработки выделенного из сложного оператора подзапроса можно подставить возвращенные этим подзапросом значения в исходный оператор, чтобы проверить правильность работы последнего. Чаще всего ошибки возникают из-за выражений, содержащих неправильное использование знаков операций для оценки результатов подзапроса, таких как =, IN, >, < и т. п.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. В чем состоит назначение подзапроса при использовании его в операторе SELECT?

2. Можно ли одновременно обновить несколько столбцов таблицы с помощью оператора UPDATE с подзапросом?

3. Будут ли работать следующие операторы? Если нет, то что в них следует исправить?

a. SELECT CUST_ID, CUST_NAME FROM CUSTOMER_TBL WHERE CUST_ID =

(SELECT CUST_ID FROM ORDERS_TBL WHERE ORD_NUM = ' 16C17' ) ;

6. SELECT EMP_ID, SALARY FROM EMPLOYEE_PAY_TBL WHERE SALARY BETWEEN '20000'

AND (SELECT SALARY

FROM EMPLOYEE_ID

WHERE SALARY = '40000');

B. UPDATE PRODUCTS_TBL SET COST = 1.15 WHERE CUST_ID =

(SELECT CUST_ID FROM ORDERS_TBL WHERE ORD_NUM = '32A132');

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

DELETE FROM EMPLOYEE_TBL WHERE EMP_ID IN

(SELECT EMP_ID FROM EMPLOYEE_PAY_TBL};

Упражнения

Выполните упражнения для следующих таблиц.

EMPLOYEE TBL

ЕМР ID LAST NAME FIRST NAME MIDDLE NAME ADDRESS CITY STATE ZIP PHONE PAGER

VARCHAR2 ( 9 ) VARCHAR2 (15) VARCHAR2 (15) VARCHAR2 (15) VARCHAR2 (30) VARCHAR2 (15) CHAR ( 2 ) NUMBER (5) CHAR (10) CHAR (10)

NOT NULL NOT NULL NOT NULL

NOT NULL NOT NULL NOT NULL NOT NULL

Ключевое поле

EMPLOYEE_PA Y_ TBL

EMP ID POSITION DATE HIRE PAY RATE DATE LAST-RAISE

VARCHAR2 ( 9 ) VARCHAR2 (15) DATE NUMBER (4,2) DATE

NOT NULL NOT NULL

NOT NULL

Ключевое поле

CONSTRAINT EMP EMPLOYEEJTBL (]

FK FOREIGN KEY EMP_ID)

(EMP ID) REF

ERENCED

CUSTOMERS_TBL

CUST ID CUST NAME CUST ADDRESS CUST CITY CUST STATE CUST ZIP CUST PHONE CUST_FAX

VARCHAR2 (10) VARCHAR2 (30) VARCHAR2 (20) VARCHAR2 (15) CHAR ( 2 ) NUMBER (5) NUMBER (10) NUMBER (10)

NOT NULL NOT NULL NOT NULL NOT NULL NOT NULL NOT NULL

Ключевое поле

ORDERS TBL

ORD NUM CUST ID PROD ID QTY ORD DATE

VARCHAR2 (10) VARCHAR2 (10) VARCHAR2 (10) NUMBER (6) DATE

NOT NULL NOT NULL NOT NULL NOT NULL

Ключевое поле

PRODUCTS_TBL

PROD ID PROD DESC COST

VARCHAR2 (10) VARCHAR2 (40) NUMBER (6, 2)

NOT NULL NOT NULL NOT NULL

Ключевое поле

1. Используя подзапрос, запишите оператор SQL, который в таблице CUSTOMER_TBL заменит имя заказчика, разместившего заказ с номером 23Е934, На DAVIDS MARKET.

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

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

15-й час Объединение запросов

Из этого урока вы узнаете, как объединить несколько запросов SQL в один с помощью команд UNION, UNION ALL, INTERSECT И EXCEPT. опять же особенности использования UNION, UNION ALL, INTERSECT и EXCEPT в случае используемой вами конкретной реализации SQL вы должны выяснить по соответствующей документации Основными на этом уроке будут следующие темы.

• Обзор команд для объединения запросов

• Когда следует использовать команды объединения запросов

• Использование GROUP BY с составными операторами

• Использование ORDER BY с составными операторами

• Обеспечение правильности результатов

Обычные и составные запросы

Обычный запрос состоит из одного оператора SELECT, а составной - из двух или более.

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

Например, оператор SQL может выглядеть следующим образом.

SELECT EMP_ID, SALARY, PAY_RATE

FROM EMPLOYEE_PAY_TBL

WHERE SALARY IS NOT NULL OR

PAY_RATE IS NOT NULL;

Тот же оператор с помощью UNION можно записать по-другому.

SELECT EMP_ID, SALARY

FROM EMPLOYEE_PAY_TBL

WHERE SALARY IS NOT NULL

UNION

SELECT EMP_ID, PAY_RATE

FROM EMPLOYEE_PAY_TBL

WHERE PAY_RATE IS NOT NULL;

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

В случае второго оператора в выводе будет присутствовать два столбца - EMP_ID и SALARY и нормы почасовой оплаты (PAY_RATE) тоже будут помещены ~ в столбец SALARY При использовании команды UNION названия (или псевдонимы) столбцов в выводе определяются первым из операторов SELECT

Зачем использовать составные запросы?

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

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

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

Команды, использующиеся для построения сложных запросов, зависят от конкретной реализации языка. Стандарт ANSI определяет команды UNION, UNION ALL, INTERSECT и EXCEPT. Все они обсуждаются ниже.

Команда UNION

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

Синтаксис оператора должен быть следующим.

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, таблица2 ]

[ WHERE ]

UNION

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, таблица2 ]

[ WHERE ]

Рассмотрим пример.

SELECT EMP_ID FROM EMPLOYEEJTBL

UNION

SELECT EMP_ID FROM EMPLOYEE_PAY_TBL;

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

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

SELECT PROD_DESC FROM PRODUCTS_TBL;

PROD_DESC

КОСТЮМ ВЕДЬМЫ

ПЛАСТИКОВЫЕ ТЫКВЫ

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

ФОНАРИ

КОСТЮМЫ В АССОРТИМЕНТЕ

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ПЛАСТИКОВЫЕ ПАУКИ

МАСКИ В АССОРТИМЕНТЕ

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

ПОЛОЧКА ИЗ ДУБА

11 строк выбраны.

SELECT PROD_DESC FROM PRODUCTS_TMP;

PROD_DESC

КОСТЮМ ВЕДЬМЫ

ПЛАСТИКОВЫЕ ТЫКВЫ

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

ФОНАРИ

КОСТЮМЫ В АССОРТИМЕНТЕ

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ПЛАСТИКОВЫЕ ПАУКИ

МАСКИ В АССОРТИМЕНТЕ

9 строк выбраны.

Таблица PRODUCTS_TMP была создана в ходе урока 3 Обратитесь к уроку 3 снова, если вам необходимо воссоздать эту таблицу

Теперь объединим эти два запроса с помощью команды UNION, чтобы получить следующий составной запрос

SELECT PROD_DESC FROM PRODUCTS_TBL

UNION

SELECT PROD_DESC FROM PRODUCTS_TMP;

PROD_DESC

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

КОСТЮМ ВЕДЬМЫ

КОСТЮМЫ В АССОРТИМЕНТЕ

МАСКИ В АССОРТИМЕНТЕ

ПЛАСТИКОВЫЕ ПАУКИ

ПЛАСТИКОВЫЕ ТЫКВЫ

ПОЛОЧКА ИЗ ДУБА

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ФОНАРИ

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

11 строк выбраны.

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

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

SELECT PROD_DESC FROM PRODDCTS_TBL

UNION

SELECT LAST_NAME FROM EMPLOYEE_TBL;

PROD_DESC

GLASS

GLASS

PLEW

SPURGEON

STEPHENS

WALLACE

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

КОСТЮМ ВЕДЬМЫ

КОСТЮМЫ В АССОРТИМЕНТЕ

МАСКИ В АССОРТИМЕНТЕ

ПЛАСТИКОВЫЕ ПАУКИ

ПЛАСТИКОВЫЕ ТЫКВЫ

ПОЛОЧКА ИЗ ДУБА

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ФОНАРИ

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

16 строк выбраны.

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

Команда UNION ALL

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

Синтаксис оператора с использованием команды UNION ALL должен быть следующим.

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, габлица2 ]

[ WHERE ]

UNION ALL

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, таблица2 ]

[ WHERE ]

Рассмотрим пример.

SELECT EMP_ID FROM EMPLOYEE_TBL

UNION ALL

SELECT EMP_ID FROM EMPLOYEE_PAY_TBL;

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

Следующий составной запрос отличается от составного запроса из предыдущего раздела только использованием команды UNION ALL вместо UNION.

SELECT PROD_DESC FROM PRODUCTS_TBL

UNION ALL

SELECT PROD_DESC FROM PRODUCTSJTMP;

PROD__DESC

КОСТЮМ ВЕДЬМЫ

ПЛАСТИКОВЫЕ ТЫКВЫ

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

ФОНАРИ

КОСТЮМЫ В АССОРТИМЕНТЕ

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ПЛАСТИКОВЫЕ ПАУКИ

МАСКИ В АССОРТИМЕНТЕ

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

ПОЛОЧКА ИЗ ДУБА

КОСТЮМ ВЕДЬМЫ

ПЛАСТИКОВЫЕ ТЫКВЫ

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

ФОНАРИ

КОСТЮМЫ В АССОРТИМЕНТЕ

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ПЛАСТИКОВЫЕ ПАУКИ

МАСКИ В АССОРТИМЕНТЕ

20 строк выбраны.

Обратите внимание на то, что возвращены 20 строк (11+9), поскольку команда UNION ALL предполагает включение в вывод повторения строк.

Команда INTERSECT

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

Синтаксис оператора с использованием команды INTERSECT должен быть следующим.

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, таблица2 ]

[ WHERE ]

INTERSECT

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, таблица2 ]

[ WHERE ]

Рассмотрим пример.

SELECT CUST_ID FROM CUSTOMERJTBL

INTERSECT

SELECT CUST_ID FROM ORDERSJTBL;

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

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

SELECT PROD_DESC FROM PRODUCTS_TBL

INTERSECT

SELECT PROD_DESC FROM PRODUCTS_TMP;

PROD_DESC

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

КОСТЮМ ВЕДЬМЫ

КОСТЮМЫ В АССОРТИМЕНТЕ

МАСКИ В АССОРТИМЕНТЕ

ПЛАСТИКОВЫЕ ПАУКИ

ПЛАСТИКОВЫЕ ТЫКВЫ

ПОЛОЧКА ИЗ ДУБА

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

9 строк выбраны.

Здесь снова возвращены только 9 строк, поскольку 9 строк идентичны в выводе обоих запросов.

Команда EXCEPT

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

Синтаксис оператора с использованием команды EXCEPT должен быть следующим.

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, таблица2 ]

[ WHERE ]

EXCEPT

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, таблица2 ]

[ WHERE ]

Рассмотрим пример.

SELECT PROD_DESC FROM PRODUCTS_TBL

EXCEPT

SELECT PROD_DESC FROM PRODUCTS_TMP;

PROD_DESC

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ ПОЛОЧКА ИЗ ДУБА

2 строки выбраны.

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

В некоторых реализациях SQL вместо команды EXCEPT используется команда MINUS Проверьте по документации используемой вами реализации языка, какая именно команда используется в нем для представления функции команды EXCEPT

SELECT PROD_DESC FROM PRODUCTS_TBL

MINUS

SELECT PROD_DESC FROM PRODUCTS_TMP;

PROD_DESC

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ ПОЛОЧКА ИЗ ДУБА

2 строки выбраны

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

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

Синтаксис оператора с использованием ORDER BY должен быть следующим

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, таблица2 ]

[ WHERE ]

КОМАНДА{UNION | EXCEPT INTERSECT | UNION ALL}

SELECT столбец1 [, столбец2 ] FROM таблица1 [, таблица2 ]

[ WHERE ]

[ ORDER BY ]

Рассмотрим пример

SELECT EMP_ID FROM EMPLOYEE_TBL

UNION

SELECT EMP_ID FROM EMPLOYEE_PAY_TBL

ORDER BY 1;

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

Этот оператор SQL возвращает упорядоченный список табельных номеров служащих ИЗ таблиц EMPLOYEEJTBL И EMPLOYEE_PAY_TBL без повторений

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

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

SELECT PROD_DESC FROM PRODUCTSJTBL

ONION

SELECT PROD_DESC FROM PRODUCTS_TBL

ORDER BY PROD_DESC;

PROD_DESC

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

КОСТЮМ ВЕДЬМЫ

КОСТЮМЫ В АССОРТИМЕНТЕ

МАСКИ В АССОРТИМЕНТЕ

ПЛАСТИКОВЫЕ ПАУКИ

ПЛАСТИКОВЫЕ ТЫКВЫ

ПОЛОЧКА ИЗ ДУБА

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ФОНАРИ

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

11 строк выбраны.

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

SELECT PROD_DESC FROM PRODUCTS_TBL

UNION

SELECT PROD_DESC FROM PRODUCTS_TBL

ORDER BY 1,

PROD_DESC

ИСКУССТВЕННЫЕ ПАРАФИНОВЫЕ ЗУБЫ

КОСТЮМ ВЕДЬМЫ

КОСТЮМЫ В АССОРТИМЕНТЕ

МАСКИ В АССОРТИМЕНТЕ

ПЛАСТИКОВЫЕ ПАУКИ

ПЛАСТИКОВЫЕ ТЫКВЫ

ПОЛОЧКА ИЗ ДУБА

СЛАДКАЯ КУКУРУЗА

ТЫКВЕННЫЕ КОНФЕТЫ

ФОНАРИ

ЦЕПОЧКА ДЛЯ КЛЮЧЕЙ

11 строк выбраны.

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

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

Синтаксис оператора с использованием GROUP BY должен быть следующим.

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, таблица2 ]

[ WHERE ]

; GROUP BY ]

t HAVING ]

КОМАНДА{UNION | EXCEPT | INTERSECT | UNION ALL}

SELECT столбец1 [, столбец2 ]

FROM таблица1 [, таблица2 ]

[ WHERE ]

[ GROUP BY ]

[ HAVING ]

[ ORDER BY ]

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

SELECT 'ЗАКАЗЧИКИ' TYPE, COUNT(*)

FROM CUSTOMERJTBL

UNION

SELECT 'СЛУЖАЩИЕ' TYPE, COUNT(*)

FROM EMPLOYEEJTBL

UNION

SELECT 'ТОВАРЫ' TYPE, COUNT(*)

FROM PRODUCTS_TBL

GROUP BY 1;

TYPE COUNT(*)

ЗАКАЗЧИКИ 15

СЛУЖАЩИЕ 6

ТОВАРЫ 11

3 строки выбраны.

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

SELECT 'ЗАКАЗЧИКИ' TYPE, COUNT(*)

FROM CUSTOMER_TBL

UNION

SELECT 'СЛУЖАЩИЕ' TYPE, COUNT(*)

FROM EMPLOYEEJTBL

UNION

SELECT 'ТОВАРЫ' TYPE, COUNT(*) FROM PRODUCTS_TBL

GROUP BY 1 ORDER BY 2;

TYPE COUNT(*)

СЛУЖАЩИЕ 6

ТОВАРЫ 11

ЗАКАЗЧИКИ 15

3 строки выбраны.

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

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

При использовании составных операторов следует быть предельно внимательными. Например, если в составном операторе с использованием команды INTERSECT неправильно задать первый из операторов SELECT, в результате можно получить либо неполные, либо вообще неверные данные. Кроме того, всегда ли нужно исключать повторения, как это делает команда UNION, или наоборот, отображать все повторения, как это делает команда UNION ALL Необходимо ли видеть все строки, не входящие в результат второго запроса при использовании команды EXCEPT? Как видите, неправильно составленный составной запрос или неправильный порядок запросов, входящих в составной, легко может привести к неправильным результатам

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

Резюме

Вы ознакомились с принципами использования составных запросов. На всех предыдущих уроках операторы SQL содержали только по одному запросу. В составных запросах комбинируется несколько запросов, чтобы получить требуемое множество данных. Командами связывания запросов являются команды UNION, UNION ALL, INTERSECT И EXCEPT (или MINUS). При использовании UNION В результате присутствуют данные двух запросов без повторений совпадающих строк данных. При использовании UNION ALL выводятся результаты обоих запросов, не смотря на повторения данных. При использовании INTERSECT возвращаются совпадающие в двух запросах строки данных. А команда EXCEPT (или, что то же самое, MINUS) используется тогда, когда необходимо получить результаты одного запроса, не представленные в другом. Составные запросы обеспечивают исключительную гибкость при составлении самых разных запросов, поскольку без использования составных запросов результирующие операторы могут получаться очень сложными.

Вопросы и ответы

Как используются ссылки на столбцы в выражении ключевого слова GROUP BY при использовании этого ключевого слова в операторе составного запроса?

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

Принцип работы команды EXCEPT понятен, но поменяется ли вывод, если поменять местами запросы, входящие в оператор составного запроса?

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

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

Нет. Одинаковыми должны быть только типы данных. Длины столбцов могут отличаться.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Правильно ли составлены приведенные ниже составные запросы? Если нет, то что в них следует исправить? В операторах используются следующие таблицы EMPLOYEE PAY TBL И EMPLOYEE PAY TBL.

EMPLOYEE_TBL

EMP ID LAST NAME FIRST NAME MIDDLE NAME ADDRESS CITY STATE ZIP PHONE PAGER

VARCHAR2 ( 9 ) VARCHAR2 (15) VARCHAR2 (15) VARCHAR2 (15) VARCHAR2 (30) VARCHAR2 (15) CHAR ( 2 ) NUMBER (5) CHAR (10) CHAR (10)

NOT NULL NOT NULL NOT NULL

NOT NULL NOT NULL NOT NULL NOT NULL

CONSTRAINT EMP

_PK PRIMARY KEY

(EMP_ID)

EMPLOYEE PAY TBL

EMP ID POSITION DATE HIRE PAY RATE

VARCHAR2 ( 9 ) VARCHAR2 (15) DATE NUMBER (4,2)

NOT NULL NOT NULL

NOT NULL

Ключевое поле

DATE_LAST-RAISE DATE SALARY NUMBER(8,2) BONUS NUMBER(6,2)

CONSTRAINT EMP_FK FOREIGN KEY (EMP_ID) REFERENCED

EMPLOYEE_TBL (EMP_ID)

a. SELECT EMP_ID, LAST_NAME, FIRST_NAME FROM EMPLOYEEJTBL UNION SELECT EMP_ID, POSITION, DATE_HIRE

FROM EMPLOYEE_PAY_TBL;

6. SELECT EMP_ID FROM EMPLOYEEJTBL UNION ALL

SELECT EMP_ID FROM EMPLOYEE_PAY_TBL ORDER BY EMP_ID;

B. SELECT EMP_ID FROM EMPLOYEE_PAY_TBL INTERSECT

SELECT EMP_lD FROM EMPLOYEEJTBL ORDER BY 1;

2. Свяжите описания задач операторов с подходящими командами.

_______Задача оператора______________Команда

а. Показать совпадающие данные UNION

б. Вернуть только те строки первого за- INTERSECT

проса, которым имеются эквивааенты UNION ALL

во втором запросе FXPFPT

в. Показать данные без повторений

г. Вернуть строки первого запроса, не

возвращаемые вторым

Упражнения

Выполните упражнения для следующих таблиц.

Задача оператора

Команда

а. Показать совпадающие данные

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

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

UNION

INTERSECT UNION ALL EXCEPT

CUSTOMER_TBL

CUST ID CUST NAME CUST ADDRESS CUST CITY COST STATE CUST ZIP CUST PHONE CUST_FAX

VARCHAR2 (10) VARCHAR2 (30) VARCHAR2 (20) VARCHAR2 (15) CHAR ( 2 ) NUMBER ( 5 ) NUMBER (10) NUMBER (10)

NOT NULL NOT NULL NOT NULL NOT NULL NOT NULL NOT NULL

Ключевое поле

ORDERS TBL

ORD NUM CUST ID PROD ID QTY ORD DATE

VARCHAR2 (10) VARCHAR2 (10) VARCHAR2 (10) NUMBER (6) DATE

NOT NULL NOT NULL NOT NULL NOT NULL

Ключевое поле

1. Запишите составной запрос, возвращающий имена всех покупателей (C(JST_NAME), разместивших заказы.

2. Запишите составной запрос, возвращающий имена всех покупателей (CUST_NAME), не разместивших заказы.

16-й час Использование индексов для ускорения поиска данных

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

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

Основными на этом уроке будут следующие темы.

• Создание индексов

• Принципы работы индексов

• Различные типы индексов

• Когда следует использовать индексы?

• Когда не следует использовать индексы?

Что такое индекс?

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

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

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

Принцип работы индексов

При создании индекса таблицы в него заносится информация о размещении данных того столбца, по которому происходит индексирование. Когда в таблицу добавляются записи, в индекс тоже заносятся соответствующие данные. При выполнении запроса, в котором либо в условии этого запроса, либо в выражении ключевого слова WHERE присутствует столбец, по которому выполнено индексирование, сначала происходит поиск в индексе. Если подходящее значение в индексе будет найдено, индекс возвратит точное местоположение нужных данных в таблице. На рис. 16.1 показано, как функционирует индекс.

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

SELECT *

FROM TABLE_NAME

WHERE NAME = 'SMITH';

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

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

Рис. 16.1. Доступ к таблице с помощью индекса

Команда CREATE INDEX

Форма оператора CREATE INDEX, как формы многих других операторов SQL, может варьироваться в зависимости от конкретной реализации языка. Многие реализации поддерживают следующий синтаксис оператора.

CREATE INDEX имя_индекса ON имя_таблицы

Очень большие отличия для различных реализаций языка наблюдаются в допустимых опциях оператора CREATE INDEX. Некоторые реализации SQL допускают опции управления памятью (как в операторе CREATE TABLE), опции упорядочения (DESC | ASC), а также использование кластеров. Чтобы выяснить корректный синтаксис, необходимо обратиться к документации по той конкретной реализации языка, которую вы используете.

Типы индексов

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

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

Простые индексы

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

CREATE INDEX имя_индекса

ON имя_таблицы (имя_столбца)

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

CREATE INDEX NAME_IDX

ON EMPLOYEEJTBL (LAST__NAME) ;

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

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

Уникальные индексы

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

CREATE UNIQUE INDEX имя_индекса

ON имя_таблицы (имя__столбца)

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

CREATE UNIQUE INDEX NAME__IDX

ON EMPLOYEEJTBL (LAST_NAME);

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

У вас может возникнуть вопрос: "А если идентификационный код не является в таблице ключом?" Индекс неявно создается при определении ключа таблицы. Но в конкретной компании данные могут обрабатываться по внутреннему табельному номеру, а идентификационные коды служащих использоваться только для документов, связанных с отчислениями по налогам. Тогда логичнее будет создать индекс по табельному номеру и обеспечить его уникальность.

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

Составные индексы

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

CREATE INDEX имя_индекса

ON имя_таблицы (столбец1, столбец2)

Вот пример создания составного индекса.

CREATE INDEX ORD_IDX

ON ORDERS_TBL (CUST_ID, PROD_ID);

В этом примере создается составной индекс по значениям двух столбцов таблицы ORDERSJTBL - столбцов CUST_ID и PROD_ID. Предполагается, что значения этих столбцов будут часто одновременно использоваться в условиях ключевого слова WHERE в запросах.

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

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

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

Неявные индексы

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

Когда следует создавать индекс?

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

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

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

Когда не следует создавать индекс?

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

• Не следует использовать индексы для небольших таблиц.

• Не следует использовать индексы по столбцам, возвращающим большой процент данных таблицы при использовании их в качестве фильтров в условиях ключевого слова WHERE. Например, в предметный указатель книги нет смысла помещать ссылки на слова типа "поэтому" или "для".

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

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

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

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

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

SELECT *

FROM ИМЯ_ТАБЛИЦЫ

WHERE GENDER = 'ЖЕН';

Взглянув на рис 16.2, вы увидите, что этот запрос вызывает непрерывный поток обращений от таблицы к индексу и наоборот. Из-за того, что условием WHERE GENDER = 'ЖЕН' (или МУЖ) возвращается большой объем данных, серверу базы данных придется постоянно читать сначала данные из индекса, затем соответствующую строку из таблицы и т. д. В данном случае гораздо более эффективным было бы простое сканирование всех данных таблицы, поскольку значительная ее часть все равно должна быть прочитана.

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

Рис. 16.2. Случай, когда создавать индекс не следует

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

Удаление индексов

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

Резюме

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

Вопросы и ответы

Увеличивает ли индекс объем дискового пространства, необходимый для хранения данных таблицы?

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

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

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

Должны ли все индексы быть уникальными?

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих урйков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Каковы главные недостатки использования индексов?

2. Почему важен порядок столбцов в составном индексе?

3. Следует ли создавать индекс по столбцу, в котором часто встречается значение NULL?

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

5. Верно ли следующее утверждение: "Главной причиной использования составных индексов является использование в таких индексах значений, по отношению к которым используются итоговые функции?"

Упражнения

1. Следует ли создавать индекс в следующих случаях, и если да, то какого типа индекс будет предпочтительнее?

а. Таблица имеет не много записей и несколько столбцов.

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

в. Очень большая таблица, несколько столбцов которой используется в фильтрахключевого слова WHERE.

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

17-й час Повышение эффективности работы с базой данных

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

Основными на этом уроке будут следующие темы.

• Что означает оптимизация операторов SQL?

• Оптимизация базы данных и оптимизация операторов SQL

• Форматирование операторов SQL

• Правильное связывание таблиц

• Наиболее ограничительные условия

• Полное сканирование таблиц

• Необходимость использования индексов

• Как избежать использования OR и HAVING

• Как избежать долгих операций сортировки

Что означает оптимизация операторов SQL?

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

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

Оптимизация базы данных и оптимизация операторов SQL

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

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

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

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

Форматирование операторов SQL

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

• Форматирование операторов SQL для лучшего восприятия

• Порядок перечисления таблиц в выражении ключевого слова FROM

• Размещение наиболее ограничительных условий в выражении ключевого слова WHERE

• Размещение условий связывания в выражении ключевого слова WHERE

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

Форматирование операторов для лучшего восприятия

Форматировать операторы SQL для лучшего восприятия вполне естественно, но, тем не менее, многие программисты не очень заботятся о виде создаваемых ими операторов. И хотя от внешнего вида оператора его скорость работы не зависит (база данных на красоту оператора внимания не обращает), правильное форматирование является первым шагом на пути оптимизации оператора SQL. При рассмотрении оператора SQL с точки зрения ускорения его работы прежде всего удобно сделать оператор максимально простым для чтения. Но как определить, является оператор удобным для чтения или нет?

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

• Каждое ключевое слово со своим выражением следует начинать с новой строки. Например, выражение с ключевым словом FROM не следует размещать в той же строке, что и выражение с ключевым словом SELECT. Точно также выражение с ключевым словом WHERE не следует размещать в той же строке, что и выражение с ключевым словом FROM и т. д.

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

• Отступы должны быть согласованными.

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

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

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

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

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

Вот пример трудного для чтения оператора.

SELECT CUSTOMER_TBL.CUST_ID, CUSTOMERJTBL.CUST_NAME,

CUSTOMERJTBL.CUST_PHONE, ORDERSJTBL.ORD_NUM, ORDERS_TBL.QTY

FROM CUSTOMER_TBL, ORDERS_TBL

WHERE CUSTOMER_TBL.CUST_ID = ORDERSJTBL.CUST_ID

AND ORDERSJTBL.QTY > 1 AND CUSTOMERJTBL.CUST_NAME LIKE 'G%'

ORDER BY CUSTOMERJTBL.CUST_NAME;

CUST_ID CUST_NAME CUST_PHONE ORD_NUM QTY

----------------------------------------

287 GAVINS PLACE 3172719991 18D778 10

1 строка выбрана.

А вот пример того же оператора после форматирования с целью улучшения его восприятия.

SELECT C.CUST_ID,

С.CUST_NAME,

С.CUST_PHONE,

O.ORD_NUM,

О.QTY

FROM CUSTOMERJTBL С,

ORDERSJTBL О

WHERE C.CUST_ID = 0.CUST_ID

AND O.QTY > 1

AND С.CUST_NAME LIKE 'G%'

ORDER BY 2;

CUST_ID CUST_NAME CUST_PHONE ORD_NUM QTY

----------------------------------------------

287 GAVINS PLACE 3172719991 18D778 10

1 строка выбрана.

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

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

Правильный порядок таблиц в выражении FROM

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

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

Правильный порядок условий связывания

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

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

FROM таблица1, Наименьшая из таблиц

таблица2,

таблица3 Наибольшая из таблиц или связующая таблица

WHERE таблица1.столбец - таблицаЗ.столбец Условие связывания

AND таблица2.столбец = таблицаЗ.столбец Условие связывания

[ AND условие1 ] Условие фильтра [ AND условие2 ] Условие фильтра

В этом случае таблицаЗ используется В качестве связующей, а таблица! и таблица2 оказываются связанными с ней.

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

Наиболее ограничительное условие

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

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

FROM таблица!. Наименьшая из таблиц таблица2,

таблицаЗ Наибольшая из таблиц или связующая таблица

WHERE таблица1.столбец = таблицаЗ.столбец Условие связывания

AND таблица2.столбец = таблицаЗ.столбец Условие связывания

[ AND условие1 ] Наименее ограничительное

[ AND условие2 ] Наиболее ограничительное

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

Для примера рассмотрим следующую тестовую таблицу.

Имя таблицы TEST

Число строк 95867

УСЛОВИЯ WHERE LAST_NAME_= 'SMITH'

Возвращает 2000 строк

WHERE CITY = 'INDIANAPOLIS'

Возвращает 30000 строк

Наиболее ограничительное условие WHERE LAST_NAME = 'SMITH'

Запрос1

SELECT COUNT(*)

FROM TEST

WHERE LAST_NAME = 'SMITH'

AND CITY = 'INDIANAPOLIS';

COUNT(*)

--------

1024

3anpoc2

SELECT COUNT<*)

FROM TEST

WHERE CITY = 'INDIANAPOLIS'

AND LAST_NAME = 'SMITH';

COUNT(*)

--------

1024

Предположим, что Запрос! выполнялся 20 секунд, а Запроса - 10 секунд. Поскольку Запрос2 был выполнен быстрее и при этом наиболее ограничительное условие было последним, то можно смело предположить, что оптимизатор обрабатывает выражение ключевого слова WHERE от конца к началу.

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

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

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

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

Когда и как избегать полного сканирования таблиц

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

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

Вот список данных, которые следует индексировать.

• Столбцы, используемые в качестве ключевых.

• Столбцы, используемые в качестве внешних ключей.

• Столбцы, часто используемые для связывания таблиц.

• Столбцы, часто используемые в условиях запросов.

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

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

Другие аспекты оптимизации

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

• Использование ключевого слова LIKE и знаков подстановки

• Замена операций OR выражением с ключевым словом IN

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

• Как избежать долгих операций сортировки

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

Использование LIKE и знаков подстановки

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

Предположим, вам нужно составить запрос с использованием таблицы EMPJ.OYEJTBL, из которой необходимо выбрать данные столбцов EMP^ID, LAST_NAME, FIRST_NAME и STATE. Точнее, получить табельные номера, фамилии, имена и информацию о месте проживания всех служащих по фамилии Стивене. Следующие три оператора SQL представляют собой различные примеры соответствующих запросов с использованием знаков подстановки.

Запрос1:

SELECT EMP__ID, LAST NAME, FIRST__NAME, STATE

FROM EMPLOYEEJTBL

WHERE LAST_NAME LIKE '%И%';

Запрос2:

SELECT EMP_ID, LAST_NAME, FIRST_NAME, STATE

FROM EMPLOYEEJTBL

WHERE LAST_NAME LIKE '%ИВЕНС%';

ЗапросЗ:

SELECT EMP_ID, LAST_NAME, FIRST_NAME, STATE

FROM EMPLOYEEJTBL

WHERE LAST_NAME LIKE 'CT%';

Эти операторы SQL не обязательно возвратят одинаковые результаты. Вероятнее всего, Запрос! возвратит больше строк, чем другие два запроса. Запрос2 и ЗапросЗ более специфичны в отношении извлекаемых данных, отсеивая больше данных и тем самым сокращая время выполнения запроса. Кроме того, ЗапросЗ скорее всего будет выполнен быстрее, чем Запрос2, поскольку поиск проводится по первым буквам (и, кроме того, столбец LAST_NAME, скорее всего, индексирован, так что ЗапросЗ может использовать преимущества индекса).

Замена операций OR выражением с ключевым словом IN

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

По поводу использования ключевых слов OR и IN см. урок 8, "Операции в условиях для отбора данных".

Вот пример запроса с использованием операций OR.

SELECT EMP_ID, LAST_NAME, FIRST_NAME

FROM EMPLOYEE_TBL

WHERE CITY = 'INDIANAPOLIS'

OR CITY = 'BROWNSBURG'

OR CITY = 'GREENFIELD';

А вот тот же запрос с использованием выражения с ключевым словом IN.

SELECT EMP_ID, LAST_NAME, FIRST_NAME

FROM EMPLOYEEJTBL

WHERE CITY IN ('INDIANAPOLIS', 'BROWNSBURG^1, 'GREENFIELD');

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

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

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

Долгие операции сортировки

Долгие операции сортировки являются следствием использования выражений с ключевыми словами ORDER BY, GROUP BY и HAVING. При выполнении сортировки соответствующие подмножества данных сохраняются в оперативной памяти или на диске (когда оперативной памяти для этого не хватает). Сортировать данные приходится часто. Здесь главным моментом является то, что операции сортировки увеличивают время выполнения запроса.

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

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

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

Отмена использования индексов в больших пакетных операциях

При выполнении пользователем транзакций (INSERT, UPDATE или DELETE) происходят обращения как к таблице, так и ко всем ее индексам, которые должны быть в результате транзакций изменены. Это значит, что если пользователь изменяет данные таблицы EMPLOYEE и у этой таблицы имеется индекс, то автоматически изменяется и этот индекс. В рамках оператора транзакции тот факт, что при каждом изменении таблицы изменяется и ее индекс, не отражается.

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

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

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

Многие базы данных предлагают специальные средства, позволяющие ускорить оптимизацию операторов SQL, а также работу базы данных в целом. Например, в Oracle имеется средство EXPLAIN PLAN, с помощью которого пользователь может ознакомиться с планом, по которому сервер базы данных собирается осуществить выполнение конкретного оператора SQL. С помощью другого средства Oracle - TKPROF - можно оценить ожидаемое время выполнения оператора. SQL Server предлагает целый ряд команд SET, с помощью которых можно оценить как скорость работы отдельных операторов SQL, так и скорость работы базы данных в целом. По поводу средств, доступных в вашем конкретном случае, обратитесь к соответствующей документации и проконсультируйтесь у своего администратора базы данных.

Резюме

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

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

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

Вопросы и ответы

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

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

Какие существуют способы проверки операторов SQL на оптимальность?

Каждая реализация языка предлагает свои средства проверки оптимальности операторов SQL. Для проверки на оптимальность операторов этой книги использовались средства Oracle?. В Oracle для этого предусмотрен ряд возможностей. Среди них средства EXPLAIN PLAN, TKPROF и команды SET. Поищите информацию о подобных средствах в документации по той реализации языка, которую вы используете.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Нужно ли использовать уникальный индекс в случае маленькой таблицы?

2. Что происходит, когда оптимизатор принимает решение не использовать индекс таблицы при выполнении запроса?

3. Где в выражении ключевого слова WHERE следует разместить наиболее ограничительные условия - до или после условий связывания таблиц?

Упражнения

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

EMPLOYEE_TBL_____

EMP_ID VARCHAR2(9) NOT NULL Ключевое поле

LAST_NAME VARCHAR2U5) NOT NULL

FIRST_NAME VARCHAR2(15) NOT NULL

MIDDLE_NAME VARCHAR2(15)

ADDRESS VARCHAR2(30) NOT NULL

CITY VARCHAR2(15) NOT NULL

STATE CHAR (2) NOT NULL

ZIP NUMBER(5) NOT NULL

PHONE CHAR(10)

PAGER CHAR(10)

CONSTRAINT EMP_PK PRIMARY KEY (EMP_ID)

EMPLOYEE__PAY_ TBL

EMP_ID VARCHAR2(9) NOT NULL Ключевое поле

POSITION VARCHAR2(15) NOT NULL

DATE_HIRE DATE

PAY_RATE NUMBER(4,2) NOT NULL

DATE_LAST-RAISE DATE

CONSTRAINT EMP_FK FOREIGN KEY (EMP_ID) REFERENCED

EMPLOYEE_TBL (EMP_ID)

a. SELECT EMP_ID, LAST_NAME, FIRST_NAME, PHONE

FROM EMPLOYEE_TBL

WHERE SUBSTR(PHONE,1,3) = '317' OR

SUBSTR(PHONE,1,3) = '812' OR

SUBSTR(PHONE,1,3) = '765';

б. SELECT LAST_NAME, FIRST_NAME

FROM EMPLOYEE_TBL

WHERE LAST_NAME LIKE '%ALL%';

в. SELECT E.EMP_ID, E.LAST_NAME, E.FIRST_NAME, EP.SALARY

FROM EMPLOYEE_TBL E,

EMPLOYEE_PAY_TBL EP

WHERE LAST_NAME LIKE 'S%'

AND E.EMP_ID EP.EMP_ID;

18-й час Управление доступом к базе данных

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

Основными на этом уроке будут следующие темы.

• Типы пользователей

• Управление пользователями

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

• Имена пользователей и имена схем

• Сеансы доступа пользователей к базе данных

• Изменение атрибутов пользователя

• Пользовательские профили

• Удаление учетной записи пользователя из базы данных

• Средства, доступные пользователю

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

Пользователь превыше всего

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

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

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

Типы пользователей

Различают следующие типы пользователей базы данных.

• Клерки, осуществляющие ввод данных

• Программисты

• Системные инженеры

• Администраторы баз данных

• Системные аналитики

• Разработчики

• Специалисты по тестированию

• Управляющий персонал

• Конечные пользователи

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

Кто управляет пользователями?

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

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

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

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

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

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

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

О пользователях и схемах

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

Процесс управления

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

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

Создание учетных записей пользователей

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

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

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

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

Создание учетной записи пользователя в Oracle

Процесс создания учетной записи пользователя в Oracle состоит из двух шагов.

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

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

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

CREATE USER ИМЯ_ПОЛЬЗОВАТЕЛЯ

IDENTIFIED BY [ ПАРОЛЬ | EXTERNALLY ]

[ DEFAULT TABLESPACE №1Я_ОБЛАСТИ ]

[ TEMPORARY TABLESPACE ИМЯ_ОБЛАСТИ ]

[ QUOTA (ЦЕЛОЕ_ЗНАЧЕНИЕ (К | М) | UNLIMITED) ON ИМЯ_ОБЛАСТИ ]

[ PROFILE ТИП_ПРОФИЛЯ ]

[PASSWORD EXPIRE | ACCOUNT [LOCK UNLOCK]]

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

Если вы не используете Oracle, не следует слишком вникать в смысл некоторых из предлагаемых данным синтаксисом опций. TABLESPACE означает логическую область, в которой размещаются объекты базы данных, в частности, таблицы и индексы. DEFAULT TABLESPACE задает область, используемую для объектов, создаваемых данным пользователем. TEMPORARY TABLESPACE задает область хранения данных для операций сортировки, осуществляемых в ходе выполнения запросов пользователя. QUOTA ограничивает сверху доступный пользователю объем конкретной логической области. PROFILE определяет профиль базы данных, предлагаемый пользователю.

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

GRANT PRIV1 [ , PRIV2, ... ] TO USERNAME | ROLE [, USERNAME ]

С помощью одного оператора GRANT можно наделить одной или несколькими привилегиями одного или нескольких пользователей одновременно.

Создание учетных записей пользователей в Sybase и Microsoft SQL Server

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

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

2. Добавление пользователя в соответствующую базу данных.

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

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

SP_ADDLOGIN ИМЯ_ПОЛЬЗОВАТЕЛЯ, ПАРОЛЬ, [, БАЗА_ДАННЫХ ]

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

SP_ADDUSER ИМЯ_ПОЛЬЗОВАТЕЛЯ [, ИМЯ_В_БД [, ИМЯ_ГРУППЫ } ]

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

GRANT PRIV1 [ , PRIV2, ... ] ТО ИМЯ_ПОЛЬЗОВАТЕЛЯ

Оператор CREATE SCHEMA

Схемы создаются с помощью оператора CREATE SCHEMA. Синтаксис этого оператора следующий.

CREATE SCHEMA [ ИМЯ_СХЕМЫ ] ( ИМЯ_ПОЛЬЗОВАТЕЛЯ ]

[ DEFAULT CHARACTER SET НАБОР_СИМВОЛОВ ]

[ PATH ИМЯ_СХЕМЫ [ , ИМЯ_СХЕМЫ ] ]

[ СПИСОК_ЭЛЕМЕНТОВ_СХЕМЫ ]

Вот пример:

CREATE SCHEMA USER1 CREATE TABLE TBL1

(Столбец1 ТИП_ДАННЫХ [NOT NULL],

Столбец2 ТИП_ДАННЫХ [NOT NULL]...)

CREATE TABLE TBL2

(Столбец1 ТИП_ДАННЫХ [NOT NULL],

Столбец2 ТИП_ДАННЫХ [NOT NULL]...)

GRANT SELECT ON TBLl TO USER2

GRANT SELECT ON TBL2 TO USER2

[ Другие команды DDL ... ]

В реальности оператор CREATE SCHEMA может быть применен, например, следующим образом.

CREATE SCHEMA AUTHORIZATION USER1

CREATE TABLE EMP

(ID NUMBER NOT NULL,

NAME VARCHAR2(10) NOT NULL)

CREATE TABLE CUST

(ID NUMBER NOT NULL,

NAME VARCHAR2(10) NOT NULL)

GRANT SELECT ON TBLl TO USER2

GRANT SELECT ON TBL2 TO USER2

Схема создана.

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

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

Удаление схем

Схема может быть удалена из базы данных с помощью оператора DROP SCHEMA. Этот оператор имеет две опции. Применение первой из них, опции RESTRICT, заставит сервер базы данных при удалении схемы выдать сообщение об ошибке, если эта схема содержит какие-нибудь объекты. Чтобы такое сообщение не появлялось, следует применить другую опцию, а именно опцию CASCADE. Помните о том, что при удалении схемы из базы данных удаляются все связанные с этой схемой объекты.

Синтаксис соответствующего оператора следующий.

DROP SCHEMA ИМЯ__СХЕМЫ { RESTRICT | CASCADE }

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

Изменение атрибутов пользователей

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

Вот пример изменения текущего состояния атрибутов пользователя в рамках одной из реализаций SQL (Oracle).

ALTER USER ИМЯ_ПОЛЬЗОВАТЕЛЯ [ IDENTIFIED BY ПАРОЛЬ | EXTERNALLY | GLOBALLY AS 'CN=USER' ]

[ DEFAULT TABLESPACE ИМЯ_ОБЛАСТИ ]

[ TEMPORARY TABLESPACE ИМЯ_ОБЛАСТИ ]

[ QUOTA ЦЕЛОЕ_ЗНАЧЕНИЕ К|М [UNLIMITED ON ИМЯ_ОБЛАСТИ }

[ PROFILE ТИП_ПРОФИЛЯ }

[PASSWORD EXPIRE]

[ACCOUNT [LOCK | UNLOCK]]

[ DEFAULT ROLE РОЛЫ [ , РОЛЬ2 } | ALL

[ EXCEPT РОЛЫ [, РОЛЬ2 | NONE ] ]

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

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

Пользователь может изменить имеющийся у него пароль Точный синтаксис оператора для изменения пароля можно узнать из документации той реализации языка, которую вы используете. В Oracle для этого обычно используется оператор ALTER USER.

Сеансы доступа к базе данных

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

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

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

CONNECT TO DEFAULT | CTPOKA1 [ AS CTPOKA2 ] [ USER CTPOKA3 ]

DISCONNECT DEFAULT | CURRENT | ALL | СТРОКА

SET CONNECTION DEFAULT | СТРОКА

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

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

Удаление учетных записей пользователей базы данных

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

К методам ликвидации возможности доступа пользователя к данным можно отнести следующие

• Изменение пароля пользователя

• Удаление учетной записи пользователя из базы данных

• Отмена ранее разрешенных пользователю привилегий доступа к данным

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

DROP USER ИМЯ_ПОЛЬЗОВАТЕЛЯ [ CASCADE ]

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

REVOKE PRIV1 [, PRIV2, ... ] FROM ИМЯ_ПОЛЬЗОВАТЕЛЯ

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

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

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

Резюме

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

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

Вопросы и ответы

Имеются ли стандартные команды SQL для добавления пользователей в базу данных?

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

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

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

Может ли пользователь изменить предложенный ему пароль?

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. С помощью какой команды инициируется сеанс доступа к данным базы данных?

2. С помощью какой команды можно удалить схему, все еще содержащую объекты?

3. С помощью какого оператора можно отменить назначенные пользователю привилегии?

4. Какая команда создает группу таблиц, представлений и привилегий?

Упражнения

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

19-й час Обеспечение сохранности данных

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

Основными на этом уроке будут следующие темы.

• Защита данных

• Защита данных и управление доступом

• Привилегии доступа к системе

• Привилегии доступа к объектам

• Предоставление привилегий пользователям

• Отмена привилегий

• Особенности системы защиты в базах данных

Что такое защита данных?

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

Различия между защитой данных и управлением пользователями

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

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

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

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

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

Что такое привилегии?

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

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

1. Привилегии доступа к системе.

2. Привилегии доступа к данным.

Привилегии доступа к системе

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

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

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

CREATE DATABASE

CREATE DEFAULT

CREATE PROCEDURE

CREATE RULE

DUMP DATABASE

DUMP TRANSACTION

EXECUTE

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

CREATE TABLE

CREATE ANY TABLE

ALTER ANY TABLE

DROP TABLE

CREATE USER

DROP USER

ALTER USER

ALTER DATABASE

ALTER SYSTEM

BACKUP ANY TABLE

SELECT ANY TABLE

Привилегии доступа к объектам

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

Стандарт ANSI определяет следующие привилегии доступа к объектам.

USAGE. Разрешает использование заданной области.

SELECT. Разрешает доступ к заданной таблице.

INSERT (имя_столбца). Позволяет разместить данные в указанном столбце заданной таблицы.

INSERT. Позволяет поместить данные во все столбцы заданной таблицы.

UPDATE {имя_столбца). Позволяет изменить данные в указанном столбце заданной таблицы.

UPDATE. Позволяет изменить данные во всех столбцах заданной таблицы.

REFERENCES (имя_столбца). Позволяет сослаться в условиях целостности на указанный столбецзаданной таблицы; требуется для всех условий целостности.

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

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

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

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

Обычно право использовать команды GRANT и REVOKE имеет администратор базы данных, но если есть администратор по безопасности, то он тоже может иметь право использовать эти команды. Конкретные инструкции по поводу того, кому и какие именно привилегии следует назначить или отменить, должны исходить от руководства и желательно в письменном виде.

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

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

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

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

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

GRANT

REVOKE

Команда GRANT

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

Синтаксис оператора следующий.

GRANT Привилегия1 [, Привилегия2 ] [ ON Объект ]

ТО Имя_Пользователя [ WITH GRANT OPTION | ADMIN OPTION ]

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

GRANT SELECT ON EMPLOYEE_TBL TO USERI;

Право предоставлено.

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

GRANT SELECT, INSERT ON EMPLOYEE_TBL TO USER1;

Право предоставлено.

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

Нескольким пользователям привилегии предоставляются следующим образом.

GRANT SELECT, INSERT ON EMPLOYEE_TBL TO USER1, USER2;

Grant succeeded.

Обратите внимание на фразу Grant succeeded (Право предоставлено) в выводе оператора в последнем примере. Такая фраза будет получена при успешном выполнении оператора в той реализации языка (Oracle), которая использовалась для примеров этой книги. Другие реализации SQL могут иметь свои фразы для сообщения пользователю результатов выполнения операторов.

GRANT OPTION

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

GRANT SELECT ON EMPLOYEE_TBL TO USER1 WITH GRANT OPTION;

Право предоставлено.

ADMIN OPTION

Опция ADMIN OPTION команды GRANT подобна опции GRANT OPTION в том, что получающий привилегии пользователь наследует также и право предоставлять эти привилегии другим пользователям. Но GRANT OPTION используется для привилегий на уровне объектов, a ADMIN OPTION - на уровне системы. Когда пользователь предоставляет другому пользователю привилегии доступа к системе с опцией ADMIN OPTION, этот новый пользователь получает также и возможность предоставления другим пользователям привилегий доступа к системе. Вот пример использования опции:

GRANT SELECT ON EMPLOYEE_TBL TO USER1 WITH ADMIN OPTION;

Право предоставлено.

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

Команда REVOKE

Команда REVOKE отменяет привилегии, ранее предоставленные пользователю базы данных. Команда REVOKE имеет две опции - RESTRICT и CASCADE. При использовании опции RESTRICT команда REVOKE будет успешно завершена только в том случае, когда отсутствуют другие пользователи с оставшимися привилегиями, явно указанными оператором REVOKE. С помощью опции CASCADE отменяются и все оставшиеся привилегии других пользователей. Другими словами, если владелец объекта наделил пользователя USERI привилегиями с опцией GRANT OPTION, а пользователь USER1 наделил привилегиями пользователя USER2, то при отмене владельцем привилегий пользователя USER1 с опцией CASCADE будут автоматически отменены и соответствующие привилегии пользователя USER2.

Оставшиеся привилегии (abandoned privileges) - это привилегии, переданные пользователю от другого пользователя с помощью опции GRANT OPTION и оставшиеся "бесхозными" у первого после удаления последнего из базы данных или после отмены привилегий последнего.

Синтаксис оператора для отмены привилегий следующий.

REVOKE Привилегия! [, Привилегия2 ] [ GRANT OPTION FOR ] ON Объект

FROM Имя_Пользователя { RESTRICT | CASCADE }

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

REVOKE INSERT ON EMPLOYEE_TBL FROM USERI;

Право отменено.

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

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

GRANT UPDATE (NAME) ON EMPLOYEES TO PUBLIC;

Право предоставлено.

Пользовательское имя PUBLIC

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

GRANT SELECT ON EMPLOYEE_TBL TO PUBLIC;

Право предоставлено.

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

Группы привилегий

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

В SQLBase имеются группы привилегий, называемые уровнями доступа (authority levels), а в Oracle такие группы называются ролями (roles). И SQLBase, и Oracle предлагают следующие группы привилегий.

CONNECT

RESOURCE

DBA

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

Группа RESOURCE позволяет пользователю создавать объекты, удалять созданные этим пользователем объекты, предоставлять другим право доступа к своим объектам и т. п.

Группа DBA позволяет пользователю осуществлять в рамках базы данных лю|ь/е действия. Такой пользователь имеет право доступа к любым объектам базы данйых и может осуществлять с ними любые действия.

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

GRANT DBA TO USER1;

Право предоставлено.

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

Контроль за привилегиями с помощью распределения ролей

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

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

При создании роли она не имеет никакого иного значения, кроме того, что она является ролью базы данных Она может быть назначена какому-нибудь пользователю или другой роли. Например, пусть схема с именем АРР01 предоставляет привилегию SELECT роли RECORDS_CLERK в отношении таблицы EMPLOYEE_PAY. После этого любой пользователь, получающий роль RECORDS_CLERK, будет обладать привилегией SELECT в отношении таблицы EMPLOYEE_PAY.

Аналогично, если АРР01 отменит привилегию SELECT для роли RECORDS_CLERK в отношении таблицы EMPLOYEE_PAY, то с этого момента и все пользователи и роли, которым была назначена роль RECORDS_CLERK, потеряют привилегию SELECT в отношении ТабЛИЦЫ EMPLOYEE_PAY.

Оператор CREATE ROLE

Создать роль можно с помощью оператора CREATE ROLE.

CREATE ROLE Имя_роли;

Предоставление привилегий ролям аналогично предоставлению привилегий пользователям Рассмотрите следующий пример

CREATE ROLE RECORDS_CLERK;

Роль создана.

GRANT SELECT, INSERT, UPDATE, DELETE ON EMPLOYEE_PAY TO

RECORDS_CLERK;

Право предоставлено.

GRANT RECORDS_CLERK TO USER1;

Право предоставлено.

Оператор DROP ROLE

Роль удаляется с помощью оператора DROP ROLE.

DROP ROLE Имя_роли;

Вот пример:

DROP ROLE RECORDS_CLERK;

Роль удалена.

Оператор SET ROLE

Роль может быть назначена пользователю в рамках его сеанса доступа к базе данных с помощью оператора SET ROLE.

SET ROLE Имя_роли;

Вот пример:

SET ROLE RECORDS_CLERK;

Роль назначена.

С помощью одного оператора можно назначить и несколько ролей.

SET ROLE RECORDS_CLERK, ROLE2, ROLE3;

Роль назначена.

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

Резюме

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

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

Для предоставления и отмены привилегий в SQL имеются две команды - GRANT и REVOKE. Эти две команды используются для того, чтобы осуществлять общее управление процессом назначения и отмены привилегий базы данных. В ходе этого часа мы с вами обсудили относящиеся к SQL принципы обеспечения безопасности базы данных, хотя в рамках реляционных баз данных имеется и целый ряд других связанных с безопасностью вопросов.

Вопросы и ответы

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

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

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

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

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

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

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы"

Тесты

1. Какая опция позволяет предоставлять доступ к объектам, не являясь их владельцем?

2. При предоставлении привилегий пользователю PUBLIC эти привилегии получат все пользователи базы данных или только определенные пользователи?

3. Какие привилегии необходимы для разрешения просматривать данные конкретной таблицы?

4. К какому типу привилегий относится привилегия SELECT?

Упражнения

1. Запишите оператор, разрешающий доступ на выборку из вашей таблицы EMPLOYEE_TBL, для пользователя с именем RPLEW. При этом необходимо предоставить пользователю RPLEW право наделять других пользователей привилегиями доступа к данной таблице.

2. Запишите оператор, отменяющий роль CONNECT для пользователя из п 1.

3. Запишите оператор, дающий пользователю RPLEW возможность выбирать, пополнять и обновлять данные таблицы EMPLOYEE_TBL.

20-й час Создание и использование представлений и синонимов

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

Основными на этом уроке будут следующие темы.

• Что такое представление?

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

• Представления и безопасность

• Хранение представлений

• Создание представлений

• Связанные представления

• Манипуляция данными в представлениях

• Что такое синоним?

• Управление синонимами

• Создание синонимов

• Удаление синонимов

Что такое представление?

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

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

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

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

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

Рис. 20.1, Представление

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

Использование представлений для защиты данных

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

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

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

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

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

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

Хранение представлений

Представление существует только в оперативной памяти. Представление не требует дискового пространства, как другие объекты базы данных, кроме пространства, занимаемого определением самого представления. Владельцем представления является создатель представления или владелец схемы. Владелец схемы автоматически получает все соответствующие привилегии доступа к представлению и право предоставлять привилегии доступа к нему другим пользователям точно так же, как и в отношении обычных таблиц. С представлениями команда GRANT и ее опция GRANT OPTION работают точно так же, как и с таблицами. За подробностями обратитесь к тексту урока 19, "Обеспечение сохранности данных".

Создание представлений

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

Базовый синтаксис оператора CREATE VIEW следующий.

CREATE [ RECURSIVE ] VIEW ИМЯ_ПРЕДСТАВЛЕНИЯ

[ИМЯ_СТОЛБЦА [, ИМЯ_СТОЛБЦА]]

[OF ИМЯ_иОТ [UNDER ИМЯ_ТАБЛИЦЫ]

[REF IS ИМЯ_СТОЛБЦА SYSTEM GENERATED | USER GENERATED | DERIVED]

[ИМЯ_СТОЛБЦА WITH OPTIONS SCOPE ИМЯ_ТАБЛИЦЫ] ]

AS

{ОПЕРАТОР SELECT}

WITH [CASCADED | LOCAL] CHECK OPTION]

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

В ANSI SQL никакого стандарта для оператора ALTER VIEW не предусматривается.

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

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

CREATE VIEW ИМЯ_ПРЕДСТАВЛЕНИЯ AS

SELECT * | СТОЛБЕЦ1 [ , СТОЛБЕЦ2 ]

FROM ИМЯ_ТАБЛИЦЫ

[ WHERE ВЫРАЖЕНИЕ1 [, ВЫРАЖЕНИЕ2 ]]

[ WITH CHECK OPTION ]

[ GROUP BY ]

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

CREATE VIEW CUSTOMERS AS

SELECT *

FROM CUSTOMER_TBL;

Представление создано.

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

CREATE VIEW EMP_VIEW AS

SELECT LAST_NAME, FIRST_NAME, MIDDLE_NAME

FROM EMPLOYEE_TBL;

Представление создано.

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

CREATE VIEW NAMES AS

SELECT LAST_NAME || ', ' || FIRST_HAME || ' ' || MIDDLE_NAME

NAME

FROM EMPLOYEE_TBL;

Представление создано.

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

SELECT *

FROM NAMES;

NAME

--------------

STEPHENS, TINA D

PLEW, LINDA С

GLASS, BRANDON S

GLASS, JACOB

WALLACE, MARIAH

SPURGEON, TIFFANY

6 строк выбраны.

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

CREATE VIEW CITY_PAY AS

SELECT E.CITY, AVG(P.PAY_RATE) AVG_PAY

FROM EMPLOYEEJTBL E

EMPLOYEE_PAY_TBL P

WHERE E.EMP_ID = P.EMP_ID

GROUP BY E.CITY;

Представление создано.

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

SELECT *

FROM CITYJPAY;

CITY AVG_PAY

--------------------------

GREENWOOD

INDIANAPOLIS 13.33333

WHITELAND

3 строки выбраны.

После создания представления его использование в операторах SELECT позволяет их значительно упростить.

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

Представление можно создать на базе данных нескольких таблиц, используя связи в операторе SELECT. Опция WITH CHECK OPTION будет обсуждаться немного позже. Синтаксис оператора следующий.

CREATE VIEW ИМЯ_ПРЕДСТАВЛЕНИЯ AS

SELECT * | СТОЛБЕЦ1 [ , СТОЛБЕЦ2 ]

FROM ИМЯ_ТАБЛИЦЫ1, ИМЯ_ТАБЛИЦЫ2 [ , ИМЯ_ТАБЛИЦЫЗ ]

WHERE ИМЯ_ТАБЛИЦЫ1 = ИМЯ_ТАБЛИЦЫ2

[ AND ИМЯ_ТАБЛИЦЫ1 = ИМЯ_ТАБЛИЦЫЗ ]

[ ВЫРАЖЕНИЕ1 ][, ВЫРАЖЕНИЕ2 ]

WITH CHECK OPTION ]

[ GROUP BY ]

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

CREATE VIEW EMPLOYEE_SUMMARY AS

SELECT E.EMP_ID, E.LAST_NAME, P.POSITION, P.DATE_HIRE,

P. PAY_RATE

FROM EMPLOYEEJTBL E

EMPLOYEE_PAY_TBL P

WHERE E.EMP_ID = P.EMP_ID;

Представление создано.

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

Создание представления на основе другого представления

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

CREATE VIEW ПРЕДСТАВЛЕНИЕ2 AS

SELECT * FROM ПРЕДСТАВЛЕНИЕ1

Уровни зависимости представлений

Новые представления на основе уже созданных можно создавать с достаточной глубиной зависимости (представление на основе представления на основе представления...), определяемой ограничениями конкретной реализации языка. Единственной проблемой при создании новых представлений на основе уже имеющихся является их управляемость. Например, если вы сначала создадите представление VIEW2 на основе представления VIEWI, представление VIEWS на основе представления VIEW2, а затем удалите представление VIEWI, то с представлениями VIEW2 и VIEWS возникнут проблемы, поскольку информация, на которые ссылаются эти представления, будет недоступна. Поэтому необходимо хорошо представлять себе место представлений в базе данных и то, на основе каких объектов эти представления созданы. Зависимость представлений схематически показана на рис. 20.2.

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

Рис. 20.2. Схема зависимости представлений

На рис. 20.2 показана схема зависимости представлений, основывающихся не только на таблицах, но и на других представлениях. ПРЕДСТАВЛЕНИЕ1 и ПРЕДСТАВЛЕНИЕ2 зависят от таблицы ТАБЛИЦА. ПРЕДСТАВЛЕНИЕЗ зависит от представления ПРЕДСТАВЛЕНИЕ1. ПРЕДСТАВЛЕНИЕ4 зависит от представлений ПРЕДСТАВЛЕНИЕ1 и ПРЕДСТАВЛЕНИЕ2. ПРЕДСТАВЛЕНИЕ5 зависит от представления ПРЕДСТАВЛЕНИЕ2. На основе анализа зависимостей можно заключить следующее.

• Если удалить ПРЕДСТАВЛЕНИЕ 1, несостоятельными станут ПРЕДСТАВЛЕНИЕЗ и ПРЕДСТАВЛЕНИЕ4.

• Если удалить ПРЕДСТАВЛЕНИЕ2, несостоятельными станут ПРЕДСТАВЛЕНИЕ4

и ПРЕДСТАВЛЕНИЕЗ.

• Если будет удалена ТАБЛИЦА, несостоятельными станут все представления.

Опция WITH CHECK OPTION

Опция WITH CHECK OPTION является опцией оператора CREATE VIEW. Эта опция применяется тогда, когда необходимо гарантировать, что все применяемые операторы UPDATE и INSERT удовлетворяют указанным в определении представления условиям. Если при этом указанные условия будут не удовлетворены, оператор UPDATE или INSERT возвратит ошибку. Опция WITH CHECK OPTION имеет свои собственные опции CASCADED и LOCAL. Опция WITH CHECK OPTION фактически гарантирует ссылочную целостность данных путем проверки отсутствия нарушений определения представления при обновлении данных.

Вот пример создания представления с использованием опции WITH CHECK OPTION.

CREATE VIEW EMPLOYEE_PAGERS AS

SELECT LAST_NAME, FIRST_NAME, PAGER

FROM EMPLOYEE_TBL

WHERE PAGER IS NOT NULL

WITH CHECK OPTION;

Представление создано.

Здесь опция WITH CHECK OPTION запрещает ввод значений NULL в столбец PAGER представления, поскольку представление определяется данными, не содержащими значения NULL в столбце PAGER.

Теперь попробуем ввести значение NULL в столбец PAGER.

INSERT INTO EMPLOYE_PAGERS

VALUES ('SMITH','JOHN',NULL);

INSERT INTO EMPLOYEE_PAGERS

*

ERROR at line 1:

ORA-01400: mandatory (NOT NULL) column is missing or NULL

during insert

Опция WITH CHECK OPTION работает.

Опции CASCADED и LOCAL

При использовании опции WITH CHECK OPTION в операторе создания представления из другого представления предлагается также использовать CASCADED или LOCAL.

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

Обновление данных представления

Данные представления можно обновить при следующих условиях.

• Представление не должно содержать связей.

• Представление не должно содержать выражения GROUP BY.

• Представление не должно содержать ссылок на псевдостолбец ROWNUM.

• Представление не должно содержать итоговых функций.

• Не должно использоваться выражение DISTINCT.

• В выражении WHERE не должно быть вложенных выражений со ссылками на ту же таблицу, на которую ссылается выражение FROM.

По поводу синтаксиса оператора UPDATE обратитесь к тексту урока 14, "Использование подзапросов".

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

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

Удаление строк из представления

Из представления можно удалять строки данных с помощью команды DELETE. При этом действуют те же ограничения, что и в случае применения команд UPDATE и INSERT. По поводу синтаксиса оператора DELETE обратитесь к тексту урока 14.

Связывание представлений с таблицами и другими представлениями

Представление можно связать с таблицами и другими представлениями. При связывании представлений с таблицами и другими представлениями действуют те же правила, что и при связывании таблиц. По поводу связывания таблиц обратитесь в тексту урока 13, "Объединение таблиц в запросах".

Создание таблицы из представления

Из представления можно создать таблицу точно так же, как таблицу можно создать из другой таблицы (или представление из другого представления). Синтаксис соответствующего оператора имеет следующий вид.

CREATE TABLE ИМЯ_ТАБЛИЦЫ AS

SELECT {* | СТОЛБЕЦ1 [, СТОЛБЕЦ2 ]}

FROM ИМЯ_ПРЕДСТАВЛЕНИЯ

[ WHERE УСЛОВИЕ1 [, УСЛОВИЕ2 ]]

[ ORDER BY ]

Для примера создадим представление на основе двух таблиц.

CREATE VIEW ACTIVE_CUSTOMERS AS

SELECT С.*

FROM CUSTOMER_TBL С

ORDERS_TBL О

WHERE C.CUST_ID = O.CUST_ID;

Представление создано.

Теперь создадим таблицу на основе только что созданного представления.

CREATE TABLE CUSTOMER_ROSTER_TBL AS

SELECT CUST_ID, CUST_NAME

FROM ACTIVE_CUSTOMERS;

Таблица создана.

Наконец, выберем данные новой таблицы точно так же, как любой другой.

SELECT *

FROM CUSTOMER_ROSTER_TBL;

CUST_ID CUST_NAME

-----------------------------------

232 LESLIE GLEASON

12 MARYS GIFT SHOP

43 SCHYLERS NOVELTIES

090 WENDY WOLF

287 GAVINS PLACE

432 SCOTTYS MARKET

6 строк выбраны.

He забывайте, что главное различие между таблицей и представлением заключается в том, что таблица содержит реальные данные и занимает физическое пространство, а представление не содержит реальных данных и не требует дополнительного места, кроме места для хранения своего определения (т е соответствующего оператора запроса)

Представления и выражение ORDER BY

В операторе CREATE VIEW использовать ключевое слово ORDER BY нельзя, но в операторе CREATE VIEW можно использовать ключевое слово GROUP BY, дающее тот же результат, что и ORDER BY.

Использовать выражение ключевого слова ORDER BY в операторе SELECT, осуществляющем запрос к представлению, выгоднее и проще, чем использовать GROUP BY в операторе CREATE VIEW.

Рассмотрим следующий пример использования ключевого слова GROUP BY в операторе CREATE VIEW.

CREATE VIEW NAMES2 AS

SELECT LAST_NAME || ', ' || FIRST_NAME || ' ' || MIDDLE_NAME

NAME

FROM EMPLOYEE_TBL

GROUP BY LAST_NAME || ', ' || FIRST_NAME || ' ' ||

MIDDLE_NAME;

Представление создано.

Теперь если выбрать все данные только что созданного представления, они будут представлены в алфавитном порядке (поскольку данные были сгруппированы по

SELECT *

FROM NAMES2;

NAME

------------------------

GLASS, BRANDON S

GLASS, JACOB

PLEW, LINDA С

SPURGEON, TIFFANY

STEPHENS, TINA D

WALLACE, MARIAH

6 строк выбраны.

Удаление представлений

Для удаления представлений из базы данных используется команда DROP VIEW. У этой команды есть две опции - RESTRICT и CASCADE. Если используется RESTRICT и в условиях имеются зависимые представления, то оператор DROP VIEW возвращает ошибку. При использовании опции CASCADE и наличии зависимых представлений оператор DROP VIEW завершается успешно и все зависимые представления тоже удаляются. Например,

DROP VIEW NAMES2;

Представление удалено.

Что такое синонимы?

Синоним - это просто другое имя для таблицы или представления Синонимы обычно создаются таким образом, чтобы пользователь имел возможность не указывать полное имя таблицы или представления другого пользователя. Синонимы можно создавать с атрибутами PUBLIC или PRIVATE. Синоним с атрибутом PUBLIC может использоваться всеми пользователями базы данных, а синоним с атрибутом PRIVATE - только владельцем и теми пользователями, кому были даны соответствующие привилегии.

Синонимы допускаются целым рядом основных реализаций SQL, но стандартом ANSI SQL синонимы не определяются. Ввиду того, что в ряде основных реализаций SQL синонимы используются, кажется разумным провести здесь их краткое обсуждение. По поводу правильного использования синонимов (если они допускаются вообще) лучше обратиться к документации той реализации языка, которую вы используете.

Управление синонимами

Управление синонимами обычно осуществляет администратор базы данных (или другое уполномоченное лицо) или конкретные пользователи. Ввиду существования двух типов синонимов (PUBLIC и PRIVATE), для их создания могут потребоваться привилегии разного уровня доступа к системе. Любой пользователь имеет возможность создавать синонимы с атрибутом PRIVATE. Право создавать синонимы с атрибутом PUBLIC обычно имеется у администратора или привилегированных пользователей базы данных. По поводу требуемых для создания синонимов привилегий обратитесь к документации той реализации языка, которую вы используете.

Создание синонимов

Общий синтаксис оператора для создания синонимов следующий.

CREATE [PUBLIC]PRIVATE] SYNONYM ИМЯ_СИНОНИМА FOR

ТАБЛИЦА |ПРЕДСТАВЛЕНИЕ

В следующем примере создается синоним с именем CUST для таблицы CUSTOMER_TBL. Это позволит не печатать полное имя таблицы каждый раз при ее использовании.

CREATE SYNONYM CUST FOR CUSTOMER_TBL;

Синоним создан.

SELECT CUST_NAME FROM CUST;

CUST_NAME

---------------------------

LESLIE GLEASON

NANCY BUNKER

ANGELA DOBKO

WENDY WOLF

MARYS GIFT SHOP

SCOTTYS MARKET

JASONS AND DALLAS GOODIES

MORGAN CANDIES AND TREATS

SCHYLERS NOVELTIES

GAVINS PLACE

HOLLYS GAMEARAM

HEALTHERS FEATHERS AND THINGS

RAGANS HOBBIES

ANDYS CANDIES

RYANS STUFF

15 строк выбраны.

Обычно владельцы таблиц, доступ к которым разрешается другим пользователям, создают для таких таблиц синонимы, чтобы другим пользователям не приходилось печатать полное имя таблицы с указанием владельца.

CREATE SYNONYM PRODUCTSJTBL FOR USER1.PRODUCTS_TBL;

Синоним создан.

Удаление синонимов

Удаление синонимов подобно удалению любого другого объекта базы данных. Общий синтаксис оператора для удаления синонима следующий.

DROP [PUBLIC|PRIVATE] SYNONYM ИМЯ_СИНОНИМА

Вот пример:

DROP SYNONYM CUST

Синоним удален.

Резюме

В ходе этого урока обсуждались представления и синонимы. Часто использованием этих возможностей пренебрегают, хотя во многих случаях они могут существенно ускорить работу пользователя с базой данных. Представления определяются как виртуальные таблицы, т. е. объекты, выглядящие и ведущие себя как таблицы, но не требующие места для хранения данных. Представления обычно определяются как запросы к таблицам или другим представлениям базы данных. Представления используют для ограничения пользователя в доступе к данным или для отображения данных в требуемом виде (например, для подведения итогов по извлекаемым данным). Представления можно создавать на основе других представлений, но при этом не следует создавать слишком много уровней зависимости, поскольку при этом возрастает риск потери контроля. При создании представлений соответствующий оператор допускает ряд опций, которые могут зависеть от реализации языка.

В этой главе обсуждались также синонимы - объекты базы данных, представляющие другие объекты. Синонимы используются для упрощения имен других объектов базы данных, например, при создании более короткого синонима имени для объекта с длинным именем или при создании синонима для объекта, к которому необходим доступ, но владельцем которого является другой пользователь. Синонимы бывают двух типов - PUBLIC и PRIVATE. Синоним с атрибутом PUBLIC доступен всем пользователям базы данных, а синоним с атрибутом PRIVATE - отдельному пользователю. Синонимы с атрибутом PUBLIC обычно создаются администратором базы данных, а обычные пользователи обычно создают синонимы с атрибутом PRIVATE для своих собственных нужд.

Вопросы и ответы

Как это представление может содержать данные и не требовать места для их хранения?

Представление на самом деле не содержит данных Представление представляет собой виртуальную таблицу или сохраненный запрос. Поэтому представление требует только место для хранения создающего представление оператора запроса, обычно называемого определением представления.

Что случится, если таблица, на основе которой строится представление, будет удалена?

Представление окажется несостоятельным, поскольку данные для отбора перестанут существовать.

Существуют ли какие-либо ограничения на имена синонимов при их создании?

Это зависит от реализации языка. В большинстве реализаций имена синонимов должны удовлетворять тем же ограничениям, что и имена таблиц и других объектов базы данных.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Можно ли удалить строку данных из представления, созданного на основе данных нескольких таблиц?

2. При создании таблицы ее владелец автоматически получает соответствующие привилегии в отношении этой таблицы. Верно ли это в случае создания представлений?

3. Какое выражение используется для упорядочения данных при создании представления?

4. Какая опция может быть использована для создания представления из другого представления, если необходимо гарантировать целостность данных?

5. При попытке удаления представления было получено сообщение об ошибке ввиду того, что имелись зависимые представления. Что нужно сделать, чтобы все-таки удалить представление?

Упражнения

1. Запишите оператор, создающий представление на основе всех данных таблицы EMPLOYEEJTBL.

2. Запишите оператор, создающий представление, возвращающее среднюю почасовую оплату и среднюю зарплату по каждому из городов для таблицы

EMPLOYEEJTBL.

3. Запишите операторы, удаляющие представления, созданные в результате выполнения пп. 1 и 2.

21-й час Работа с системным каталогом

В ходе этого урока мы с вами поговорим о системном каталоге, в некоторых реализациях реляционных баз данных называемом также словарем данных (data dictionary). К концу урока вам станет ясно назначение и содержимое системного каталога и вы сможете извлекать из него необходимую информацию о базе данных с помощью команд, изученных в ходе предыдущих уроков. Системный каталог с информацией о самой базе данных в той или иной форме присутствует во всех главных реализациях реляционных баз данных. В ходе этого урока мы приводим списки наиболее важных элементов системных каталогов основных производителей реляционных баз данных.

Основными на этом уроке будут следующие темы.

• Что такое системный каталог?

• Как создается системный каталог?

• Содержимое системного каталога

• Таблицы системного каталога

• Доступ к данным системного каталога

• Обновление системного каталога

Что такое системный каталог?

Системный каталог - это набор таблиц и представлений, содержащих важную информацию о базе данных. Системный каталог имеется в любой базе данных. Информация в системном каталоге определяет структуру всей базы данных. Например, в системном каталоге хранятся операторы DDL (Data Definition Language - Язык определения данных) для всех таблиц базы данных. Схематически место системного каталога в базе данных показано на рис. 21.1.

Как видно из рис. 21.1, системный каталог фактически является частью базы данных. В базе данных имеются различные объекты, в частности, таблицы, индексы и представления. Системный каталог представляет собой группу объектов, содержащих определения других объектов базы данных и структуры самой базы данных, а также другую не менее важную информацию.

Системный каталог в зависимости от реализации может Делиться на логичные группы, чтобы обеспечить доступ к соответствующей информации не только администратору базы данных, но и другим заинтересованным пользователям. Например, пользователю может понадобиться информация о предоставленных ему привилегиях, но совсем не обязательно знать о внутренней структуре или внутренних процессах базы данных. Пользователь, как правило, обращается к системному каталогу за информацией о своих собственных объектах и привилегиях, а администратору базы данных может потребоваться информация о структуре любого объекта и информация о любом событии в базе данных. В некоторых реализациях в системном каталоге имеются такие объекты, которые оказываются доступными только для администратора базы данных.

Рис. 21.1. Системный каталог

Системный каталог является главным источником информации о структуре и природе базы данных. Системный каталог помогает содержать базу данных в порядке не только администратору базы данных и ее пользователям, но и серверу базы данных.

В каждой реализации приняты свои соглашения по назначению имен таблицам и представлениям системного каталога. Но имена не так важны по сравнению с пониманием того, какие объекты этими именами представлены, какую информацию эти объекты содержат и как эту информацию можно извлечь

Как создается системный каталог?

Системный каталог создается либо автоматически при создании базы данных, либо администратором базы данных сразу же после ее создания. Например, в Oracle выполняется набор поставляемых производителем макросов SQL, которые атоматически создают доступные пользователям таблицы и представления системного каталога. Таблицы и представления системного каталога принадлежат системе, а не какой-нибудь отдельной схеме. Например, в Oracle владельцем системного каталога яшшется пользователь с именем SYS, имеющий права неограниченного доступа к базе данных. В Sybase системный каталог для сервера SQL размещается в базе данных MASTER.

Содержимое системного каталога

Системный каталог содержит массу информации, доступной многим пользователям и иногда используемой этими пользователями для своих собственных нужд. Системный каталог содержит информацию по следующим разделам.

• Учетные записи пользователей и установки по умолчанию.

• Привилегии и другая связанная с безопасностью информация.

• Статистика, характеризующая производительность системы.

• Размеры объектов.

• Динамика роста объектов.

• Структура таблиц и параметры их хранения.

• Структура индексов и параметры их хранения.

• Информация о других объектах базы данных, в частности, представлениях, синонимах, триггерах, сохраненных процедурах.

• Ограничения для таблиц и информация о ссылочной целостности данных.

• Пользовательские сеансы доступа.

• Информация об аудитах.

• Внутренние параметры базы данных.

• Размещение файлов базы данных.

Системный каталог управляется сервером базы данных. Например, при создании таблицы сервер базы данных вставляет данные об этом в соответствующую таблицу или представление каталога. При изменении пользователем структуры своей таблицы соответствующие объекты словаря данных тоже обновляются. В следующих разделах систематично описываются типы данных, которые отслеживаются в системном каталоге.

Пользовательские данные

В системном каталоге хранится информация обо всех пользователях базы данных: их привилегиях доступа к системе и объектам, информация о принадлежащих им объектах, а также информация о не принадлежащих им объектах, к которым эти пользователи имеют доступ. Пользовательские таблицы и представления оказываются доступными для извлечения этой информации. По поводу имеющихся в системном каталоге объектов обратитесь к документации, предлагаемой вашей реализацией базы данных.

Информация о безопасности

Системный каталог содержит также информацию о безопасности, в частности, учетные записи пользователей, закодированные пароли, пользовательские привилегии и группы привилегий доступа к данным. В некоторых реализациях предусмотрены таблицы аудита с данными обо всех действиях, предпринятых пользователями в отношении базы данных с указанием времени и инициатора этих действий и другой соответствующей информации. Могут подробно отслеживаться также и пользовательские сеансы доступа к базе данных.

Информация о структуре базы данных

Системный каталог содержит также информацию о структуре самой базы данных. Эта информация может включать дату создания базы данных, имена и размеры ее объектов, размеры и адреса размещения файлов, информацию о ссылочной целостности данных, об имеющихся индексах, столбцах таблиц и их атрибутах.

Статистика производительности системы

В системном каталоге обычно представлена и статистика, характеризующая производительность системы. Такая статистика обычно включает информацию о скорости выполнения операторов SQL и том методе, который был выбран оптимизатором для их выполнения. Другая информация о производительности может содержать параметры использования памяти, доступного базе данных свободного пространства, фрагментации таблиц и индексов. Эта информация может быть использована для оптимизации структуры и работы базы данных, оптимизации операторов SQL и выбора оптимальных способов доступа к данным с целью уменьшения времени, необходимого для выполнения запросов.

Таблицы системного каталога

Разные реализации баз данных предлагают свои таблицы и представления системного каталога, часто разделенные на группы по уровням доступа на пользовательские, системные и предназначенные для администратора базы данных. Конкретную информацию о содержимом таблиц системного каталога можно получить из запросов к этим таблицам и из документации к базе данных. Для некоторых из наиболее распространенных реализаций соответствующая информация представлена в табл. 21.1.

Microsoft SQL Server

Имя таблицы

Описание

SYSUSERS

SYSSEGMENTS

SYSINDEXES

SYSCONSTRAINTS

Информация о пользователях базы данных

Информация обо всех сегментах базы данных

Информация обо всех индексах

Информация обо всех условиях ограничения

dBase

Имя таблицы

Описание

SYSVIEWS

SYSTABLS

SYSIDXS

SYSCOLS

Информация обо всех представлениях

Информация обо всех таблицах

Информация обо всех индексах

Информация о столбцах таблиц

Microsoft Access

Имя таблицы

Описание

MSysColumns

MSyslndexes

MSysMacros

MSysObjects

MSysQueries

MSysRelationships

Информация о столбцах таблиц

Информация об индексах таблиц

Информация о созданных макросах

Информация обо всех объектах базы данных

Информация о созданных запросах

Информация о связях между таблицами

Sybase

Имя таблицы

Описание

SYSMESSAGES

SYSKEYS

SYSTABLES

SYSVIEWS

SYSCOLUMNS

SYSINDEXES

SYSOBJECTS

SYSDATABASES

SYSPROCEDURES

Список всех сообщений об ошибках сервера

Информация о ключах и внешних ключах

Информация обо всех таблицах и представлениях

Тексты всех представлений

Информация о столбцах таблиц

Информация об индексах

Информация о таблицах, триггерах, представлениях и т. п.

Информация обо всех базах данных на сервере

Информация о представлениях, триггерах и сохраненных процедурах

Oracle

Имя таблицы

Описание

ALLJTABLES

USER_TABLES

DBAJTABLES

DBA_SEGMENTS

DBAJNDEXES

DBA_USERS

DBA_ROLE_PRIVS

DBA_ROLES

DBA_SYS_PRIVS

DBA_FREE_SPACE

V$DATABASE

V$SESSION

Информация о таблицах, доступных пользователю

Информация о таблицах, принадлежащих пользователю

Информация обо всех таблицах в базе данных

Информация о сегментах

Информация о всех индексах

Информация о всех пользователях базы данных

Информация о выданных ролях

Информация обо всех ролях в базе данных

Информация о выданных привилегиях доступа к системе

Информация о доступном базе данных свободном пространстве

Информация о создании базы данных

Информация о текущем сеансе доступа

В таблице приведена лишь малая часть объектов системных каталогов некоторых реализаций баз данных. Многие объекты различных реализаций оказываются похожими, но в рамках этого урока мы стремимся показать их разнообразие. В конце концов, каждый из производителей реляционных баз данных реализует свой подход к организации системного каталога.

Использование данных системного каталога

С помощью средств SQL данные таблиц и представлений системного каталога можно извлечь точно так же, как данные других таблиц и представлений базы данных. Обычный пользователь имеет возможность осуществить запрос к своим таблицам, но, как правило, доступ к системным таблицам разрешается только привилегированным пользователям, например, администратору базы данных.

Запрос SQL на выборку данных из системного каталога по форме не отличается от запроса к любой другой таблице базы данных.

Например, следующий запрос возвратит все строки данных таблицы SYSTABLES в Sybase.

SELECT * FROM SYSTABLES

GO

В следующих разделах представлено несколько примеров запросов к таблицам системного каталога и соответствующая информация, которая может оказаться вам полезной.

Примеры запросов к системному каталогу

Следующие примеры иллюстрируют запросы к системному каталогу Oracle. Для выбора Oracle не было никаких особых причин, кроме той, что авторы книги знают реализацию Oracle лучше других реализаций.

Следующий запрос возвращает список всех имен пользователей базы данных.

SELECT USERNAME

FROM ALL_USERS;

USERNAME

------------

SYS

SYSTEM

RYAN

SCOTT

DEMO

RON

USER1

USER2

8 строк выбраны. Следующий запрос возвращает список всех таблиц данного пользователя.

SELECT TABLE_NAME

FROM USER_TABLES;

TABLE_NAME

-----------

CANDY_TBL

CUSTOMER_TBL

EMPLOYEE_PAY_TBL

EMPLOYEE_TBL

PRODUCTS_TBL

ORDERS_TBL

6 строк выбраны.

Следующий запрос возвращает список всех привилегий доступа к системе, имеющихся у пользователя с именем BRANDON.

SELECT GRANTEE, PRIVILEGE

FROM SYS.DBA_SYS_PRIVS

WHERE GRANTEE = 'BRANDON';

GRANTEE PRIVILEGE

-------------------------

BRANDON ALTER ANY TABLE

BRANDON ALTER USER

BRANDON CREATE USER

BRANDON DROP ANY TABLE

BRANDON SELECT ANY TABLE

BRANDON UNLIMITED TABLESPACE

6 строк выбраны.

А вот пример из MS Access:

SELECT NAME

FROM MSYSOBJECTS

WHERE NAME = 'MSYSOBJECTS'

NAME

------------

MSYSOBJECTS

Показанные здесь примеры иллюстрируют ничтожно малую долю той информации которую можно извлечь из любого системного каталога По поводу имеющихся в системном каталоге таблиц и их содержимого необходимо обратиться к документации той базы данных, с которой вы работаете

Обновление содержимого системного каталога

Системный каталог позволяет только выборку его данных - даже когда его использует администратор базы данных. Обновление системного каталога осуществляется автоматически сервером базы данных. Например, в базе данных пользователем создается таблица с помощью оператора CREATE TABLE. При этом сервер базы данных помещает соответствующий оператор DDL в определенную таблицу системного каталога. Необходимости обновлять таблицы системного каталога вручную не возникает никогда. Во всех реализациях эту работу выполняет сервер базы данных по схеме, показанной на рис. 21.2

Никогда не пытайтесь изменять таблицы системного каталога вручную. Это может привести к нарушению целостности данных Помните о том, что в системном каталоге хранится информация о структуре базы данных и ее объектах Как правило, системный каталог хранится отдельно от других данных в базе данных.

Рис. 21.2. Обновление системного каталога

Резюме

В ходе этого урока обсуждались назначение и содержимое системного каталога реляционной базы данных. Системный каталог в некотором смысле является базой данных внутри базы данных и по существу представляет собой базу данных с информацией о той базе данных, в рамках которой этот системный каталог создан. С помощью системного каталога проще осуществлять управление общей структурой базы данных, следить за происходящими в базе данных событиями и изменениями, получать полезную для управления базой данных информацию. Системный каталог предполагает только чтение его данных. Пользователям базы данных не позволено вносить какие бы то ни было изменения непосредственно в системный каталог. Изменения в системный каталог вносятся автоматически каждый раз, когда меняется структура базы данных, например, когда пользователем создаются таблицы. Такие изменения в системный каталог вносятся сервером базы данных.

Вопросы и ответы

Как пользователь базы данных я имею возможность получить информацию о своих объектах. Но как получить информацию об объектах других пользователей?

Есть целый ряд таблиц и представлений системного каталога, доступ к которым может получить любой пользователь базы данных. Среди таких таблиц и представлений обязательно найдутся такие, в которых содержится информация о тех объектах, к которым доступ вам разрешен.

Если пользователь забыл свой пароль, может ли администратор базы данных извлечь пароль пользователя из какой-нибудь таблицы системного каталога?

И да, и нет. Пароль действительно хранится в специальной таблице системного каталога, но обычно этот пароль бывает зашифрован, так что даже администратор не сможет его прочитать. Но пароль можно переустановить, что для администратора базы данных оказывается достаточно простым делом.

Как выяснить, из каких столбцов состоит некоторая таблица системного каталога?

К таблицам системного каталога можно адресовать запросы точно так же, как к любым другим таблицам базы данных. Просто выполните запрос к соответствующей таблице системного каталога.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Как по другому называется системный каталог в некоторых базах данных?

2. Имеет ли возможность обычный пользователь обновлять системный каталог?

3. Какая системная таблица Sybase содержит информацию о существующих в базе данных представлениях?

4. Кто является владельцем системного каталога?

5. В чем различия между системными объектами ALLJTABLES и DBAJTABLES в Oracle?

6. Кто вносит изменения в таблицы системного каталога?

Упражнения

1. Попытайтесь выполнить запросы к системным таблицам в рамках своей базы данных. Начните с запроса к таблице, содержащей информацию о вашем учетной записи пользователя базы данных.

2. Получите из системного каталога список всех таблиц, к которым вы имеете право доступа.

3. Получите из системного каталога список всех имеющихся у вас привилегий доступа к системе и объектам.

4. Если вы имеете привилегию DBA или SELECT в отношении таблиц администратора базы данных, выполните запрос на выборку данных этих таблиц. Если же таких привилегий у вас нет, ознакомьтесь с образцами этих таблиц по документации, сопровождающей базу данных.

22-й час Средства опытного пользователя

В ходе этого урока мы с вами рассмотрим некоторые темы, выходящие за рамки элементарных средств SQL К концу урока вы будете иметь в своем арсенале понимание основ использования курсоров, сохраненных процедур, триггеров динамического SQL прямого вызова и вложенного SQL, а также SQL, сгенерированного средствами SQL

Основными на этом уроке будут следующие темы

• Что такое курсор

• Использование сохраненных процедур

• Триггеры

• Основы динамического SQL

• Использование SQL для генерирования SQL

• Прямой вызов SQL и вложенный SQL

• Интерфейс уровня вызовов

Средства, выходящие за рамки элементарных

Возможности SQL, обсуждаемые здесь, выходят за рамки базовых операций, которые мы с вами рассматривали до сих пор и к которым можно отнести операции выполнения запросов, создания структур базы данных и манипуляции данными Возможности, которые мы рассмотрим в ходе этого занятия, доступны во многих реализациях баз данных, использующих расширения стандартного SQL, обсуждавшегося до сих пор

Не все обсуждаемые здесь вопросы определяются стандартом ANSI SQL поэтому обязательно проверьте по документации синтаксис и правила использования предлагаемых ниже команд Для сравнения мы здесь приводим синтаксис команд нескольких ведущих производителей баз данных

Курсоры

Для многих людей слово "курсор" ассоциируется с мигающим прямоугольником на экране монитора, предназначенным для указания того места где в файле или приложении находится пользователь Здесь же под курсором понимается нечто иное Курсор SQL - это область памяти базы данных, где был сохранен последний из операторов SQL Если текущим оператором SQL оказывается запрос, в памяти сохраняется также и строка запроса Эта строка называется текущим значением курсора или текущей строкой Соответствующая область памяти именуется и оказывается доступной программам

Курсор обычно используется для извлечения порций данных из базы данных При этом программа получает возможность анализировать текущие строки курсора Курсоры обычно используются в рамках SQL, встроенного в программы процедурного типа Некоторые курсоры создаются автоматически сервером базы данных, другие же объявляются программистом Использование курсоров в базах данных разных производителей может иметь свои особенности

Рассмотрим для сравнения операторы объявления курсора для двух наиболее распространенных систем Microsoft SQL Server и Oracle

Синтаксис оператора объявления курсора в Microsoft SQL Server следующий

DECLARE ШЧ_КУРСОРА CURSOR

FOR OnEPATOP_SELECT

[ FOR {READ ONLY UPDATE [ СПИСОК__СТОЛБЦОВ ]}]

Синтаксис оператора объявления курсора в Oracle следующий

DECLARE CURSOR ИМЯ_ КУРСОРА

IS {ОПЕРАТОР_SELECT}

Создаваемый следующим оператором курсор будет содержать все записи таблицы EMPLOYEE_TBL

DECLARE CURSOR EMP_CURSOR IS

SELECT * FROM EMPLOYEE_TBL

{ ДРУГИЕ ОПЕРАТОРЫ ПРОГРАММЫ }

После определения курсора для доступа к нему стандартом ANSI предусмотрены следующие операторы

OPEN Открывает определенный ранее курсор

FETCH Извлекает данные курсора, помещая их в переменную программы

CLOSE Закрывает курсор после завершения работы с ним

Открытие курсора

При открытии курсора выполняется указанный в определении этого курсора оператор SELECT, и результат выполнения оператора сохраняется в специальной области памяти

Синтаксис оператора для открытия курсора в dBase следующий

OPEN ИМЯ_КУРСОРА

Синтаксис оператора для открытия курсора в Oracle следующий.

OPEN ИМЯ_КУРСОРА [ ПАРАМЕТР1 [, ПАРАМЕТР2 ]]

Например, следующий оператор открывает курсор EMP_CURSOR: OPEN EMP_CURSOR

Доступ к данным курсора

После того как курсор будет открыт, его содержимое (т. е. результат выполнения его запроса) можно прочитать с помощью оператора FETCH.

Синтаксис оператора FETCH в Microsoft SQL Server следующий.

FETCH ИМЯ_КУРСОРА [ INTO СПИСОК_ПОЛУЧАТЕЛЬ ]

Синтаксис оператора в Oracle следующий.

FETCH CURSOR ИМЯ_КУРСОРА {INTO : ГЛАВНАЯ_ПЕРЕМЕННАЯ }

[[ INDICATOR ] : ПЕРЕМЕННАЯ_ИНДИКАТОР ]]

[, : ГЛАВНАЯ_ПЕРЕМЕННАЯ

[[ INDICATOR ] : ПЕРЕМЕННАЯ_ИНДИКАТОР ]]

I USING DESCRIPTOR ДЕСКРИПТОР ]

Синтаксис оператора в dBase следующий.

FETCH ИМЯ_КУРСОРА INTO ПЕРЕМЕННЫЕ_ПАМЯТИ

Например, чтобы извлечь содержимое курсора EMP_CURSOR и поместить в переменную с именем EMP_RECORD, можно использовать оператор FETCH следующего вида.

FETCH EMP_CURSOR INTO EMP_RECORD

Закрытие курсора

Очевидно, если имеется возможность открыть курсор, должна быть предусмотрена и возможность закрыть его. Закрыть курсор несложно, только следует помнить, что после закрытия курсор становится недоступным для программ пользователей.

Закрытие курсора не обязательно освобождает выделенную для него память. В некоторых базах данных освободить занятую курсором память можно только явно с помощью команды DEALLOCATE. В результате выполнения этой команды освобождается занятая курсором память и назначенное курсору имя, которое теперь можно будет использовать снова. В других базах данных память освобождается автоматически при закрытии курсора. В таком случае ранее занятая курсором память оказывается доступной для других операций по мере необходимости.

В Microsoft SQL Server синтаксис операторов закрытия курсора и освобождения занимаемой курсором памяти будет следующим.

CLOSE ИМЯ_КУРСОРА

DEALLOCATE CURSOR ИМЯ_КУРСОРА

При закрытии курсора в Oracle занимаемые им ресурсы освобождаются автоматически без использования оператора DEALLOCATE. Синтаксис оператора закрытия курсора в Oracle следующий.

CLOSE ИМЯ_КУРСОРА

Для освобождения ресурсов в dBase объект должен быть закрыт и открыт вновь. Тогда ресурсы окажутся свободными, а имена - вновь доступными для использования. Синтаксис оператора закрытия курсора в dBase следующий.

CLOSE ИМЯ_КУРСОРА

Как вы могли видеть из предыдущих примеров вариации операторов в разных базах данных могут быть значительными, особенно если эти операторы используют возможности расширений SQL, о которых пойдет речь в ходе урока 24, "Расширения стандартного SQL". По поводу правильного использования курсоров в вашем конкретном случае обратитесь к документации, сопровождающей базу данных.

Сохраненные процедуры и функции

Сохраненная процедура - это набор операторов SQL, обычно называемый функцией или подпрограммой, созданный программистом для удобства использования в программах (сохраненную процедуру использовать проще, чем каждый раз записывать весь набор входящих в нее операторов SQL). Кроме того, сохраненные процедуры можно вкладывать одну в другую, т. е. одни сохраненные процедуры могут вызывать другие, последние, в свою очередь, тоже могут вызывать сохраненные процедуры и т. д.

Возможность сохранять процедуры - основа процедурного программирования. Команды SQL (CREATE TABLE, INSERT, UPDATE, SELECT'и т.д.) дают вам возможность сообщить базе данных, что делать, но не как делать. Посредством составления процедур вы получаете возможность сообщить ядру базы данных, каким образом следует обрабатывать данные.

Сохраненная процедура - это набор из одного или нескольких операторов SQL или функций, сохраненный в базе данных в откомпилированном виде, готовом для выполнения пользователем базы данных. Сохраненная функция является сохраненной процедурой, предполагающей в результате своего выполнения возврат некоторого значения.

Функции вызываются процедурами. При вызове функции ей, как процедуре, могут передаваться параметры, затем функция вычисляет некоторое значение и возвращает его вызывающей процедуре для дальнейшего использования.

При сохранении процедуры в базе данных сохраняются также и все входящие в эту процедуру подпрограммы и функции (использующие SQL). Все эти сохраняемые процедуры предварительно анализируются и сохраняются в виде, готовом для немедленного использования по команде, инициируемой пользователем.

В Microsoft SQL Server процедуры создаются с помощью оператора следующего вида.

CREATE PROCEDURE ИМЯ_ПРОЦЕДУРЫ

[ [ (] @ИМЯ_ПАРАМЕТРА

ТИП_ДАННЫХ [(ДЛИНА) | (ТОЧНОСТЬ] [, МАСШТАБ ])

[ = DEFAULT ][ OUTPUT ]]

[, @ ИМЯ_ПАРАМЕТРА

ТИП_ДАННЫХ [(ДЛИНА) | (ТОЧНОСТЬ] [, МАСШТАБ ])

[ = DEFAULT ][ OUTPUT ]] [)]]

[ WITH RECOMPILE ]

AS ОПЕРАТОРЫ_SQL

В Oracle синтаксис оператора следующий.

CREATE [ OR REPLACE ] PROCEDURE ИМЯ__ПРОЦЕДУРЫ

[ (АРГУМЕНТ [{IN | OUT | IN OUT) ] ТИП,

АРГУМЕНТ [{IN 1 OUT | IN OUT} ] ТИП] ] {IS I AS)

ТЕЛО_ПРОЦЕДУРЫ

Вот пример оператора, создающего достаточно простую процедуру.

CREATE PROCEDURE NEW_PRODUCT

(PROD_ID IN VARCHAR2, PROD_DESC IN VARCHAR2, COST IN NUMBER)

AS

BEGIN

INSERT INTO PRODUCTS_TBL

VALUES (PRODJT.D, PROD_DESC, COST);

COMMIT;

END;

Процедура создана.

Эту процедуру можно использовать для добавления новых строк в таблицу PRODUCTS_TBL.

В Microsoft SQL Server сохраненные процедуры используются следующего образом.

EXECUTE [ @ВОЗВРАЩАЕМОЕ_СОСТОЯНИЕ = ] ИМЯ ПРОЦЕДУРЫ

[[@ИМЯ__ПАРАМЕТРА = ] ЗНАЧЕНИЕ |

[@ИМЯ_ПАРАМЕТРА = } @ПЕРЕМЕННАЯ [ OUTPUT ]]

[WITH RECOMPILE]

В Oracle синтаксис следующий.

EXECUTE [ @ВОЗВРАЩАЕМОЕ_СОСТОЯНИЕ = ] ИМЯ__ПРОЦЕДУРЫ

[[@ИМЯ_ПАРАМЕТРА = ] ЗНАЧЕНИЕ | [@ШЯ ПАРАМЕТРА = ] @ПЕРЕМЕННАЯ [

OUTPUT ]]

[WITH RECOMPILE]

Давайте выполним только что созданную процедуру.

EXECUTE NEW_PRODUCT ('9999','INDIAN CORN',1.99);

PL/SQL процедура успешно выполнена.

Вы обнаружите, что синтаксис команд, используемых при работе с процедурами в базах данных разных производителей, сильно варьирует Базовые команды SQL остаются одинаковыми, но вот программные конструкции (такие как переменные, условные выражения, курсоры, циклы) могут отличаться существенно

Преимущества использования процедур

Использовать сохраненные ранее процедуры удобнее, чем отдельные операторы SQL по целому ряду причин. Некоторые из этих причин перечислены ниже.

• Операторы сохраненной процедуры уже сохранены в базе данных.

• Операторы сохраненной процедуры уже проверены и находятся в готовом для использования виде

• Возможность сохранения процедур позволяет использовать модульное программирование

• Сохраненные процедуры могут вызывать другие процедуры и функции.

• Сохраненные процедуры могут вызываться другими программами.

• При использовании сохраненных процедур результат ответ от базы данных обычно получается быстрее

• Использовать процедуры очень просто.

Триггеры

Триггер - это откомпилированная процедура, используемая для выполнения действий, инициируемых происходящими в базе данных событиями Триггер представляет собой сохраненную в базе данных процедуру, которая выполняется тогда, когда в отношении таблицы выполняются определенные действия (операторы языка манипуляции данными - DML). Триггер может выполняться до или после операторов INSERT, DELETE или UPDATE. Триггеры можно использовать, например, для проверки целостности данных перед выполнением INSERT, DELETE или UPDATE. С помощью триггеров можно отменять транзакции, а также модифицировать данные одних таблиц и читать данные других даже из других баз данных.

Чаще всего триггеры использовать очень удобно, однако, их использование приводит к значительному увеличению числа операций ввода-вывода. Триггеры не следует использовать тогда, когда сохраненная процедура или программа может добиться тех же результатов с меньшими накладными расходами.

Оператор CREATE TRIGGER

Триггер можно создать с помощью оператора CREATE TRIGGER. Стандарт ANSI предлагает для этого оператора следующий синтаксис.

CREATE TRIGGER TRIGGER NAME

[[BEFORE | AFTER] TRIGGER EVENT ON TABLE NAME]

[REFERENCING VALUES ALIAS LIST ]

[TRIGGERED ACTION TRIGGER EVENT ::=

INSERT UPDATE | DELETE {OF TRIGGER COLUMN LIST]

TRIGGER COLUMN LIST ::= COLUMN NAME [, COLUMN NAME]

VALUES ALIAS LIST ::=

VALUES ALIAS LIST ::=

OLD [ROW] [AS] OLD VALUES CORRELATION NAME |

NEW {ROW} {AS} NEW VALUES CORRELATION NAME |

OLD TABLE {AS} OLD VALUES TABLE ALIAS |

NEW TABLE {AS} NEW VALUES TABLE ALIAS

OLD VALUES TABLE ALIAS ::= IDENTIFIER

NEW VALUES TABLE ALIAS ::= IDENTIFIER

TRIGGERED ACTION ::=

[FOR EACH [ROW | STATEMENT] [WHEN SEARCH CONDITION]]

TRIGGERED SQL STATEMENT

TRIGGERED SQL STATEMENT ::=

SQL STATEMENT | BEGIN ATOMIC [SQL STATEMENT;]

END

В Microsoft SQL Server синтаксис оператора для создания триггера выглядит следующим образом.

CREATE TRIGGER ИМЯ_ТРИГГЕРА

ON ИМЯ_ТАБЛИЦЫ

FOR { INSERT | UPDATE | DELETE [, ..]}

AS

OnEPATOPH_SQL

[ RETURN ]

В Oracle базовый синтаксис оператора следующий.

CREATE [ OR REPLACE ] TRIGGER ИМЯ_ТРИГГЕРА

[ BEFORE | AFTER]

[ DELETE I INSERT | UPDATE]

ON [ ПОЛЬЗОВАТЕЛЬ.ИМЯ_ТАБЛИЦЫ ]

[ FOR EACH ROW ]

[ WHEN УСЛОВИЕ ]

[ БЛОК PL/SQL ]

Вот пример создания триггера.

CREATE TRIGGER EMP_PAY_TRIG

AFTER UPDATE ON EMPLOYEE_PAY_TBL

FOR EACH ROW

BEGIN

INSERT INTO EMPLOYEE_PAY_HISTORY

(EMP_ID, PREV_PAY_RATE, PAY_RATE, DATE_LAST_RAISE,

TRANSACTION_TYPE)

VALUES

(:NEW.EMP_ID, :OLD.PAY_RATE, :NEW.PAY_RATE,

:NEW.DATE_LAST_RAISE, 'PAY CHANGE');

END;

/

Триггер создан.

В этом примере создается триггер с именем EMP_PAY_TRIG. Этот триггер вставляет строку в таблицу EMPLOYEE_PAY_HISTORY, отражая изменения таблицы EMPLOYEE_PAY_TBL каждый раз, когда данные последней обновляются.

Тело триггера изменить нельзя Для этого триггер придется либо заменить другим, либо воссоздать В некоторых реализациях SQL триггер можно заменить (если триггер с данным именем в системе уже существует) с помощью того же оператора CREATE TRIGGER.

Оператор DROP TRIGGER

Триггер можно удалить с помощью оператора DROP TRIGGER. Синтаксис этого оператора следующий.

DROP TRIGGER ИМЯ_ТРИГТЕPA

Динамический SQL

Динамический SQL дает возможность программисту или конечному пользователю создавать необходимые операторы SQL прямо во время выполнения программы. Создаваемые таким образом операторы передаются базе данных и возвращают данные в переменные программы, существующие во время выполнения последней.

Понять динамический SQL проще всего в сравнении со статическим. Статический SQL - это SQL, обсуждавшийся в книге до сих пор. Статический оператор SQL создается в предположении, что меняться он не будет. Хотя статические операторы SQL могут сохраняться в готовом для выполнения виде, например, в процедурах базы данных, они не обеспечивают той гибкости, которая достигается с помощью динамического SQL.

Проблема статического SQL состоит в том, что даже тогда, когда пользователю предлагается очень много видов запросов на выбор, всегда остается вероятность того, что в каких-то случаях пользователя ни один из этих "законсервированных запросов" не устроит. Динамический SQL используется в качестве средства создания подходящих для конкретной ситуации запросов непосредственно пользователем во время его работы с базой данных. После того как оператор будет приведен в нужный пользователю вид, он будет передан базе данных для проверки синтаксиса, необходимых привилегий, компиляции и, наконец, выполнения сервером базы данных. Динамический SQL создается с помощью интерфейса уровня вызовов, обсуждению которого посвящается следующий раздел.

Хотя динамический SQL обеспечивает конечным пользователям большую гибкость в построении запросов, он не может сравниться по производительности с сохраненными процедурами, операторы которых оказываются уже подготовленными оптимизатором SQL к немедленному выполнению.

Интерфейс уровня вызовов

Интерфейс уровня вызовов (call level interface) используется для внедрения программного кода SQL в главную программу, создаваемую, например, средствами ANSI С Создателям приложений понятие интерфейса уровня вызовов должно быть хорошо знакомым. Это один из методов, с помощью которого программист получает возможность внедрить SQL в программный код некоторых процедурных языков программирования. При использовании интерфейса уровня вызовов текст оператора SQL передается некоторой переменной программы с соблюдением правил соответствующего языка программирования. После этого получившая оператор SQL программа может его выполнить, обработав переменную, которой был передан текст этого оператора.

Типичной командой языка программирования, позволяющей вызвать оператор SQL из программы, является команда EXEC SQL.

ЕХЕС SQL

Вот некоторые из языков программирования, поддерживающих интерфейс уровня вызовов.

• COBOL

• ANSI С

• Pascal

• Fortran

• Ada

По поводу использования опций интерфейса уровня вызовов обратитесь к документации по соответствующему языку программирования

Использование SQL для генерации SQL

Использование SQL для генерации операторов SQL в некоторых случаях значительно экономит время. Предположим, что в вашей базе данных 100 пользователей. Предположим также, что вы создаете новую роль ENABLE (пользовательский объект с соответствующими привилегиями), которую необходимо приписать всем 100 пользователям. Вместо того, чтобы вручную создавать 100 операторов GRANT, можно использовать следующий оператор SQL, который сгенерирует необходимые операторы за вас

SELECT 'GRANT ENABLE TO '|| USERNAME || ';'

FROM SYS.DBA_USERS;

В этом примере используется представление системного каталога Oracle, содержащее информацию о пользователях.

Обратите внимание на то, что здесь фраза GRANT ENABLE TO заключена в кавычки. Использование кавычек заставляет воспринимать все заключенное между ними как буквальное значение. Буквальные значения можно выбирать из таблиц точно так же, как и столбцы. USERNAME является столбцом таблицы SYS. DBA_USERS из системного каталога. Двойная вертикальная черта ( | | ) используется для конкатенации столбцов. Использование двойной вертикальной черты с последующим '; ' добавляет к концу пользовательского имени точку с запятой, означающую завершение оператора.

В результате сгенерированные операторы SQL будут выглядеть примерно так:

GRANT ENABLE TO RRPLEW;

GRANT ENABLE TO RKSTEP;

Результат необходимо сохранить в файле, который можно будет передать базе данных. База данных, в свою очередь, выполнит все операторы SQL из этого файла по очереди, избавляя вас от необходимости долгого печатания команд и тем самым сэкономив вам немало времени.

В следующий раз, когда вам придется при написании операторов SQL повторять однообразные операторы SQL несколько раз подряд, остановитесь и позвольте SQL сделать эту работу за вас.

Прямой вызов SQL и вложенный SQL

Прямое использование SQL означает выполнение операторов SQL с любого интерактивного терминала. Результаты при этом возвращаются обратно на терминал, инициировавший выполнение операторов. В данной книге до сих пор, в основном, рассматривалось прямое использование SQL. Прямое использование SQL называют также интерактивным вызовом или прямым вызовом (direct invocation)

Вюженныи SQL (embedded SQL) представляет собой программный код SQL, используемый в рамках другой программы, созданной, например, средствами Pascal, Fortran, COBOL или С Программный код SQL оказывается фактически встроенным в несущий его язык программирования посредством интерфейса уровня вызовов, как было указано выше. Встроенные в несущий язык программирования операторы SQL обычно предваряются командой ЕХЕС SQL и, как правило, завершаются точкой с запятой. В других же случаях такими завершающими командами могут быть END-EXEC или закрывающая скобка.

Вот пример вложения оператора SQL в вызывающую программу, созданную средствами ANSI С

{операторы вызывающей программы}

ЕХЕС SQL {оператор SQL};

{другие операторы вызывающей программы}

Резюме

В ходе этого урока обсуждались некоторые средства SQL, выходящие за рамки элементарных. Хотя мы и не вдавались в детали, вы должны были получить общее представление о том, как используются обсуждавшиеся здесь возможности. Сначала были рассмотрены курсоры, с помощью которых можно сохранять результаты запросов в памяти. Чтобы объявившая курсор программа могла его использовать, эта программа должна открыть его. После этого содержимое курсора можно передать соответствующей переменной, чтобы программа смогла в нужный момент эти данные использовать. Данные курсора сохраняются в памяти до тех пор, пока курсор не будет закрыт, а занятая им память освобождена.

Затем были рассмотрены сохраняемые процедуры и триггеры. Сохраняемые процедуры состоят, в основном, из групп операторов SQL, хранящихся вместе в базе данных. Такие операторы вместе с другими необходимыми командами компилируются базой данных и сохраняются в виде, готовом для немедленного выполнения в любое время по требованию пользователя базы данных. Триггер тоже представляет собой сохраненную процедуру, но его выполнение инициируется автоматически в ответ на определенные события, происходящие в базе данных. Использование сохраненных процедур оказывается, как правило, более выгодным с точки зрения производительности системы, чем непосредственное использование отдельных операторов SQL.

Кроме того, были рассмотрены динамический SQL, генерирование операторов SQL средствами SQL и различия между прямым вызовом SQL и использованием вложенного SQL. Динамический SQL, в отличие от статического, позволяет динамическое создание программного кода SQL непосредственно пользователем в ходе выполнения программы. Использование SQL для генерации операторов SQL может существенно экономить время, поскольку дает возможность с помощью конкатенации и выбора подходящих буквальных значений автоматизировать трудоемкие операции по созданию больших последовательностей однообразных операторов SQL. Наконец, обсуждались различия между прямым вызовом SQL и вложенным SQL. Главное из этих различий заключается в том, что прямой вызов операторов SQL осуществляется непосредственно пользователем с любого терминала, а вложенный SQL можно фактически считать частью программы, с помощью которой обрабатываются данные.

Рассмотренные в ходе этого урока средства будут использованы для иллюстрации возможностей использования SQL в рамках реальной базы данных типичного предприятия, о котором пойдет речь на следующем уроке, "Использование SQL в локальных и глобальных сетях".

Вопросы и ответы

Может ли сохраненная процедура вызывать другую сохраненную процедуру?

Да. Вызываемая процедура называется также вложенной процедурой.

Как заставить курсор выполняться?

Используйте для этого оператор OPEN CURSOR. В итоге результат выполнения курсора будет сохранен в специальной области памяти.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Можно ли изменить триггер?

2. Можно ли использовать имя курсора вновь после того, как курсор будет закрыт?

3. Какая команда используется для извлечения данных курсора после его открытия?

4. Когда выполняются триггеры - до или после выполнения команд INSERT, UPDATE И DELETE?

Упражнения

1. Используя таблицы системного каталога вашей базы данных, запишите программный код SQL, с помощью которого автоматически будут созданы следующие операторы SQL. Условные имена объектов замените реальными.

a. GRANT SELECT ON ИМЯ_ТАБЛИЦЫ ТО ИМЯ_ПОЛЬЗОВАТЕЛЯ;

б. GRANT, CONNECT, RESOURCE TO ИМЯ_ПОЛЬЗОВАТЕЛЯ; В. SELECT COUNT (*) FROM ИМЯ__ТАБЛИЦЫ;

2. Запишите оператор, создающий процедуру, позволяющую удалять строки таблицы PRODUCTS_TBL. В качестве образца используйте оператор, предложенный в тексте этого урока для процедуры, добавляющей строку с новым продуктом в указанную таблицу.

3. Запишите оператор, использующий созданную в предыдущем упражнении процедуру для удаления из таблицы строки с информацией о продукте с кодом (PROD_ID), равным 9999.

23-й час Использование SQL в локальных и глобальных сетях

В ходе этого урока мы с вами поговорим о том как использовать SQL в \сю-виях реального предприятия ичи локачьной сети компании и как испочьзовать SQL в Internet

Основными на этом уроке будут следующие темы

• SQL на уровне предприятия

• Приложения прикладной и интерфейсной частей системы

• Удаленный доступ к базе данных

• SQL и Internet

• SQL и intranet

SQL на уровне предприятия

В ходе предыдущего урока мы рассмотрели средства SQL, которые приоткрыли вам дверь в мир практического использования возможностей этого языка В ходе этого урока мы обсудим использование SQL в рамках реального предприятия, что предполагает, в частности, наличие приложений SQL, с помощью которых работники предприятия получают возможность использования базы данных в производственных целях Многие коммерческие предприятия имеют данные, доступ к которым предлагается пользователям вне компании - другим предприятиям, покупателям или производителям Например, предприятие может предлагать потенциальным покупателям доступ к дополнительной информации о продуктах предприятия в надежде увеличить сбыт Должны быть учтены и нужды служащих предприятия Например, доступной может быть служебная информация о графиках работы и отпусков, обучении персонала, политике компании и т п Подобная база данных может быть создана и сделана легко доступной для пользователей средствами SQL и Internet

Прикладная часть

Сердцем любой базы данных является ее прикладная часть Именно там происходят главные события базы данных, оставаясь совершенно незаметными для пользователя Прикладная часть клиент-серверного приложения (back-end application) состоит из сервера базы данных, источников данных и соответствующего промежуточного программного обеспечения, используемого для подключения приложения к Web или удаленной базе данных по локальной сети.

Еще раз напомним, что к наиболее распространенным серверам баз данных относят Oracle, Informix, Sybase, Microsoft SQL Server и Borland InterBase Именно с сервера начинается разворачивание приложения баз данных либо на все предприятие в рамках локальной сети (LAN) или сети intranet предприятия, либо в Internet Разворачивание (porting) представляет собой процесс внедрения приложения в среду, доступную пользователям Сервер базы данных должен быть установлен на рабочем месте администратора базы данных, который, в свою очередь, должен понимать и производственные потребности предприятия, и требования самого приложения

Промежуточное программное обеспечение приложения состоит из сервера Web и средств, позволяющих подключить сервер Web к серверу базы данных Главной целью в данном случае является наличие в Web приложения, предоставляющего доступ к корпоративным данным

Интерфейсная часть

Интерфейсная часть приложения (front-end application) - это та часть приложения, с которой имеет дело пользователь Интерфейсная часть приложения может быть коммерческим продуктом какой-нибудь компании, производящей программное обеспечение на продажу, либо продуктом, разработанным внутри предприятия с применением различных программных средств О таких средствах будет идти речь в следующих разделах.

До того, как на рынке сложилось имеющееся сегодня разнообразие приложений, предлагающих интерфейс пользователя базы данных, пользователю необходимо было уметь программировать на языках типа С HTML или любом другом из множества процедурных языков программирования, с помощью которых разрабатывались приложения для Web Языки типа ANSI С, COBOL, FORTRAN или Pascal использовались для разработки интерфейсной части внутри предприятия, и соответствующий интерфейс пользователя был, как правило, текстовым Сегодня большинство новых приложений интерфейсной части предлагают графический пользовательский интерфейс (GUI)

Интерфейсная часть приложения призвана обеспечить пользователю простоту доступа к базе данных и работы с ней Внутренние процессы программный код и происходящие в ней события должны быть незаметными для пользователя Интерфейсная часть приложения должна быть разработана для того чтобы по возможности избавить пользователя от необходимости теряться в догадках и интуитивно чувствовать систему в целом Новые технологии позволяют сделать приложения более понятными и простыми в применении что дает пользователю возможность сосредоточиться на решении своих конкретных задач повышая в конечном итоге эффективность своего труда.

Имеющиеся на сегодня средства разработки приложений достаточно просты в применении и объектно-ориентированны, что достигается использованием в них пиктограмм, возможностей перетаскивания объектов с помощью мыши, а также различных мастеров, автоматически генерирующих объекты с заданными свойствами. Среди наиболее популярных средств разработки Web-приложений следует упомянуть C++Builder, IntraBuilder фирмы Borland и Visual J++, C++ фирмы Microsoft. Для разработки программ, предназначенных для работы в рамках локальной сети предприятия, используют PowerBuilder фирмы Powersoft, Developer/2000 фирмы Oracle Corporation, Visual Basic фирмы Microsoft и Delphi фирмы Borland.

На рис. 23.1 представлена схема взаимозависимости прикладной и интерфейсной частей приложения баз данных. Прикладная часть располагается на сервере, там же размещается и сама база данных. Пользователями прикладной части являются разработчики базы данных, программисты, администраторы базы данных, системные администраторы и системные аналитики. Интерфейсная часть приложения размещается на машинах-клиентах, которыми обычно являются персональные компьютеры конечных пользователей. Интерфейсная часть приложения рассчитана на самую широкую аудиторию пользователей, включающую операторов ввода данных, бухгалтеров и т. д. Пользователь должен иметь возможность доступа к базе данных по сети-и такая сеть может быть как локальной (LAN), так и глобальной (WAN). Для предоставления пользователю такой возможности используется промежуточное программное обеспечение (например, драйвер ODBC).

Рис. 23.1. Приложение баз данных

Удаленный доступ к базе данных

База данных может быть локальной, и тогда вы имеете возможность подключится к ней непосредственно. Но, как правило, пользователю требуется доступ к базе данных, которая находится на некотором удалении от его системы. Удаленная база данных - это некоторая база данных, не являющаяся локальной, т. е. расположенной на том сервере, к которому вы подключены в данный момент, и предполагающая для доступа к ней использование сети и определенных сетевых протоколов.

Доступ к удаленной базе данных можно осуществить несколькими способами. Говоря в общем, доступ к удаленной базе данных осуществляется с помощью Подключения к сети или Internet посредством использования промежуточного программного обеспечения (например, стандартных средств ODBC, обсуждению которых посвящен следующий раздел). На рис. 23.2 схематически показаны три сценария, по которым можно организовать доступ к удаленной базе данных.

На этом рисунке показана схема доступа к удаленной базе данных с локального сервера базы данных, локального интерфейсного приложения и главного локального сервера. Локальный сервер базы данных и главный локальный сервер часто оказываются одним и тем же объектом, поскольку база данных, как правило, размещается на главном локальном сервере. Но подключиться к удаленной базе данных с главного локального сервера можно и без подключения к локальной базе данных. Для конечного пользователя чаще всего предлагается подключение к удаленной базе данных средствами интерфейсного приложения. Во всех этих случаях используется передача запросов к базе данных по сети.

Рис. 23.2. Доступ к удаленной базе данных

ODBC

Технология ODBC (Open Database Connectivity - открытый интерфейс доступа к базам данных) обеспечивает возможность доступа к удаленным базам данных с помощью подходящего драйвера. Драйвер ODBC используется интерфейсным приложением для получения доступа к прикладной части базы данных для взаимодействия с данными нижнего уровня. Для доступа к удаленной базе данных, кроме того, может понадобиться и сетевой драйвер. Приложение вызывает функции ODBC, а соответствующий драйвер обеспечивает загрузку драйвера ODBC. Драйвер ODBC обрабатывает вызов функции, пересылает запрос к базе данных и возвращает результат этого запроса. На сегодня ODBC является стандартом, используемым целым рядом продуктов, в частности, PowerBuilder, FoxPro, Visual C++, Visual Basic, Delphi, Microsoft Access и многими другими.

Как часть ODBC, любой производитель систем управления базами данных предлагает со своими базами данных программный интерфейс приложения (API). Для примера из таких предлагаемых продуктов можно отметить Open Call Interface (OCI) фирмы Oracle и SQLGateway или SQLRouter фирмы Centura.

Другие интерфейсы доступа к данным

В дополнение к драйверу ODBC многие производители систем управления базами данных предлагают свое программное обеспечение, предназначенное для организации доступа к удаленным базам данных. Каждый из таких продуктов оказывается специфическим для системы управления базами данных конкретного производителя и, вообще говоря, не предполагает переносимости на другие типы серверов баз данных.

Oracle Corporation для организации доступа к удаленным базам данных предлагает свой продукт под именем Net8. Net8 можно использовать практически с любыми сетевыми протоколами, в частности, TCP/IP, OSI, SPX/IPX и многими другими. Кроме того, Net8 может работать под управлением почти любой из наиболее распространенных операционных систем.

Sybase Incorporated предлагает свой продукт под именем Open Client/C Developers Kit, поддерживающий продукты других производителей, в частности Net8 фирмы Oracle.

Доступ к удаленным базам данных с помощью интерфейса Web

Доступ к удаленным базам данных посредством интерфейса Web подобен доступу к базам данных по локальной сети Главное отличие состоит в том, что в Web все запросы к базе данных направляются через Web-сервер.

Из рис. 23.3 видно, что конечный пользователь инициирует доступ к удаленной базе данных с помощью броузера Web. Броузер Web используется для связывания с заданным URL или адресом IP в Internet, соответствующим нужному серверу Web. Сервер Web, проверив имя и пароль пользователя, пересылает пользовательский запрос базе данных, которая, в свою очередь, тоже может потребовать проверки имени и пароля. Затем сервер базы данных вернет результаты запроса серверу Web, а последний отобразит эти результаты в окне пользовательского броузера Web. Несанкционированный доступ к конкретному серверу может пресекаться с помощью брандмауэра (firewall).

Рис. 23.3. Доступ к удаленной базе данных через Web

Брандмауэр (firewall) - это аппаратно-программная система межсетевой защиты от несанкционированного доступа к серверу. Для зашиты от несанкционированного доступа к серверу может использоваться как одна, так и несколько таких систем. Точно также одна или несколько систем защиты могут использоваться для управления доступом к серверу базы данных и к самой базе данных.

При пересылке информации по Web следует принять все возможные меры безопасности на всех уровнях. К таким уровням можно отнести сервер Web, главный локальный сервер и удаленную базу данных Частные данные, такие как идентификационные номера служащих, всегда должны быть защищены от доступа к ним случайных лиц и не должны распространяться в Web.

SQL и Internet

SQL можно использовать в рамках приложений, создаваемых средствами С или COBOL. Точно так же SQL можно использовать и в Internet-приложениях, создаваемых средствами таких языков программирования, как Java. Текст HTML тоже можно транслировать в запрос SQL, чтобы потом с помощью интерфейсного приложения Web переслать этот запрос удаленной базе данных. Возвращенный базой данных результат затем транслируется обратно в текст HTML и отображается броузером Web на экране пользователя, пославшего запрос. В следующих разделах использование SQL в Internet обсуждается подробнее.

Предоставление доступа к данным пользователям во всем мире

С изобретением и распространением Internet по всему миру данные стали доступными покупателям и производителям в любой стране. Такие данные обычно бывают доступными только для чтения с помощью соответствующего интерфейсного приложения.

Предназначенные для покупателей данные могут состоять из общей информации для покупателей, информации о конкретных продуктах, бланков заказов, информации о текущих и выполненных ранее заказах и т.д. Частная информация, например, информация о корпоративной стратегии и о служащих компании доступной быть не должна.

Наличие информационной странички в Web стало почти обязательным для компаний, стремящихся успешно конкурировать с другими в своем бизнесе. Страничка Web оказывается весьма эффективным средством информирования большого числа потенциальных покупателей об услугах, продуктах и других аспектах деятельности компании, не требуя при этом чрезмерных затрат.

Предоставление доступа к данным служащим и привилегированным клиентам

С помощью Internet или сети intranet компании базу данных можно сделать доступной для служащих этой компании или ее клиентов. Использование технологий Internet оказывается весьма удобным для информирования служащих о политике компании, преимуществах работы в ней, обучающих программах и т. п.

Интерфейсные приложения Web, использующие SQL

Имеется целый ряд приложений, обеспечивающих доступ к базам данных. Многие из таких приложений предлагают графический интерфейс пользователя, так что пользователю даже нет необходимости понимать SQL, чтобы составить запрос к базе данных. В таких приложениях пользователю предлагается указывать и щелкать мышью на объектах, представляющих таблицы, манипулировать данными этих объектов, задавать критерии отбора возвращаемых данных и т. д. Такие приложения часто разрабатываются и настраиваются в полном соответствии с конкретными требованиями конкретной компании.

SQL и intranet

IBM изначально создавала SQL для доступа к базам данных, размещенным на мэйнфреймах, с клиентских машин пользователей. Пользователи при этом связывались с мэйнфреймами по локальной сети. Позже SQL стал стандартным языком коммуникации пользователей с базами данных. Intranet, по сути, является миниатюрным аналогом Internet. Основным различием между ними является то, что intranet предна-шачлегся для использования внутри некоторой организации, a Internet открыта для доступа всем. Пользовательский (клиентский) интерфейс в intranet остается тем же, что и в модели клиент/сервер. Запросы SQL направляются базе данных сервером Web с использованием соответствующего языка (например, HTML).

Безопасность в рамках базы данных значительно выше, чем в Internet. Поэтому всегда используйте средства безопасности, предлагаемые вашим сервером базы данных.

Резюме

В ходе этого урока мы обсудили некоторые идеи, позволяющие распространить SQL и приложения баз данных в Internet. На сегодняшний день это оказывается весьма важным для тех компаний, которые стремятся оставаться конкурентоспособными в своем секторе рынка. Чтобы не отстать от остального мира, весьма выгодно - если не обязательно - организовать свое "присутствие" в World Wide Web. A чтобы такое "присутствие" организовать, необходимо разработать соответствующие приложения и перейти от систем клиент/сервер к серверу Web в Internet. При этом главным вопросом представления корпоративных данных в Web становится вопрос безопасности. Стратегия безопасности должна быть тщательно разработана и выполняться неукоснительно.

В главе обсуждались также методы доступа к удаленным базам данных по локальным сетям и через Internet. Каждый из этих методов для передачи запросов удаленной базе данных предполагает использование сетевых адаптеров и соответствующих протоколов. Кратко обсуждались использующие SQL приложения ряда производителей для работы в локальных сетях, сетях intranet и Internet. После проверки своих знаний с помощью приведенных ниже контрольных вопросов и упражнений вы будете готовы к последнему из уроков нашего с вами путешествия в страну SQL.

Вопросы и ответы

В чем разница между Internet и intranet?

Internet обеспечивает публичный доступ к информационным ресурсам посредством интерфейса Web. Intranet тоже использует интерфейс Web, но предполагает только внутренний доступ, например для служащих компании или для привилегированных клиентов.

Отличается ли база данных для приложения Web от базы данных в системе клиент/сервер?

Сама по себе база данных для приложения Web может ничем не отличаться от базы данных в системе клиент/сервер, но использование технологий Web накладывает некоторые дополнительные ограничения. Например, приложение Web для доступа к базе данных использует сервер Web и поэтому в рамках такого приложения конечные пользователи обычно не имеют возможности прямого доступа к базе данных.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б. "Ответы"

Тесты

1. Может ли база данных на одном сервере быть доступной с другого сервера?

2. Что может использовать компания для того, чтобы распространять информацию среди своих служащих?

3. Как называется программное обеспечение, посредством которого осуществляется доступ к базам данных.

4. Можно ли внедрить SQL в языки программирования для Internet?

5. Как осуществляется доступ к удаленной базе данных в рамках приложения Web?

Упражнения

1. Войдите в Internet и ознакомьтесь с информационными страницами нескольких из представленных там компаний. Если ваша компания тоже имеет информационную страницу в Web, сравните ее с информационными страницами конкурентов. Ответьте для себя на следующие вопросы в отношении просмотренных страниц.

а. Открывается ли страница быстро или ее открытие тормозится наличием слишком большого числа графических изображений?

б. Интересно ли читать представленную на странице информацию?

в. Получили ли вы в результате чтения имеющейся на странице информации представление о предлагаемых компанией услугах и продуктах и о компании в целом?

г. Если на странице предлагается доступ к некоторой базе данных, то достаточно ли быстро осуществляется такой доступ?

д. Можно ли сделать вывод об использовании на данной странице Web каких-либо средств безопасности?

2. Если в вашей компании используется intranet, войдите в сеть и посмотрите, какая информация о компании там представлена. Доступна ли там какая-нибудь база данных? Если да, то кто является производителем соответствующей системы управления базами данных? Какого типа интерфейсные приложения предлагаются при этом конечному пользователю?

24-й час Расширения стандартного SQL

На этом уроке обсуждаются расширения стандарта ANSI SQL. Хотя большинство реализаций SQL в основном предлагают стандартные средства, многие производители предлагают также расширения стандартного SQL с целью различных усовершенствований

Основными на этом уроке будут следующие темы

• Разные реализации языка

• Различия между реализациями

• Соответствие стандарту ANSI SQL

• Интерактивные операторы SQL

• Использование переменных

• Использование параметров

Реализации SQL

Имеется целый ряд реализаций SQL, предлагаемых различными производителями. Перечислить здесь всех производителей систем управления базами данных возможности нет, поэтому мы рассмотрим только некоторые программные продукты, предлагаемые лидерами. Мы обсудим реализации SQL, предлагаемые Sybase, dBase, Microsoft SQL Server и Oracle. Кроме них достаточно популярными являются продукты фирм Borland, IBM, Informix, Progress, CA-Ingress и многих других.

Различия между реализациями

Хотя все реализации, о которых идет речь, предназначены для работы с реляционными базами данных, каждая из этих реализаций немного отличается от других. Эти различия вытекают из различий в дизайне продукта и различий в подходах к обработке данных ядром базы данных. Но в данной книге мы сосредоточимся на различиях в рамках SQL. Как и рекомендовано стандартом ANSI, все реализации в качестве языка взаимодействия с базой данных используют SQL. Но кроме стандартных средств SQL, предлагаются расширения SQL, специфичные для каждой из имеющихся реализаций.

Различия в SQL различных производителей возникают из-за стремления улучшить стандарт ANSI SQL с точки зрения простоты использования и эффективности. Внедрять усовершенствования и делать свои продукты более привлекательными для клиентов производителей заставляет конкуренция.

Теперь, когда вы знаете основы SQL, вам будет нетрудно разобраться в различиях SQL разных производителей. Другими словами, если вы можете использовать SQL в рамках реализации Sybase, для вас не составит большого труда использовать SQL и в Oracle. Кроме того, знание SQL различных производителей по крайней мере улучшит ваше резюме.

В следующих примерах сравнивается синтаксис операторов SELECT разных производителей со стандартом ANSI.

Стандарт ANSI предлагает следующий синтаксис оператора.

SELECT [DISTINCT ] [* | СТОЛБЕЦ1 [, СТОЛБЕЦ2 ]

FROM ТАБЛИЦА1 [, ТАБЛИЦА2]

[ WHERE УСЛОВИЕ ПОИСКА ]

GROUP BY [ ПСЕВДОНИМ_ТАБЛИЦЫ | СТОЛБЕЦ1 [, СТОЛБЕЦ2 ]

[ HAVING УСЛОВИЕ_ПОИСКА ]]

[{UNION | INTERSECT | EXCEPT}][ ALL ]

[ CORRESPONDING [ BY (СТОЛБЕЦ! [, СТОЛБЕЦ2 ]) ]

СПЕЦКФИКАЦИЯ_ЗАПРОСА | SELECT * FROM ТАБЛИЦА |

КОНСТРУКТОР_ТАБЛИЦЫ ]

[ORDER BY СПИСОК_СОРТИРОВКИ ]

SQLBase предлагает следующий синтаксис оператора.

SELECT [ ALL | DISTINCT ] СТОЛБЕЦ1 [, СТОЛВЕЦ2 ]

FROM ТАБЛИЦА1 [, ТАБЛИЦА2]

[ WHERE УСЛОВИЕ_ПОИСКА ]

[ GROUP BY СТОЛБЕЦ1 [, СТОЛБЕЦ2 ]

[ HAVING УСЛОВИЕ_ ПОИСКА ]]

[ UNION [ ALL ] ]

[ ORDER BY СПИСОК_СОРТИРОВКИ ]

[ FOR UPDATE OF СТОЛБЕЦ1 [, СТОЛБЕЦ2 ]]

Oracle предлагает следующий синтаксис оператора.

SELECT [ ALL | DISTINCT ] СТОЛБЕЦ1 [, СТОЛБЕЦ2 ]

FROM ТАБЛИЦА1 [, ТАБЛИЦА2]

[ WHERE УСЛОВИЕ_ПОИСКА ]

[[ START WITH УСЛОВИЕ_ПОИСКА ]

CONNECT BY УСЛОВИЕ_ПОИСКА ]

[ GROUP BY СТОЛБЕЦ1 [, СТОЛБЕЦ2 ]

[ HAVING УСЛОВИЕ_ПОИСКА ]]

[{UNION [ ALL ] ] INTERSECT | MINUS} СПЕЦИФИКАЦИЯ_ЗАПРОСА ]

[ ORDER BY СТОЛБЕЦ1 [, СТОЛБЕЦ2 ]

[ NOWAIT ]

Informix предлагает следующий синтаксис оператора.

SELECT [ ALL | DISTINCT | UNIQUE ] СТОЛБЕЦ1 [, СТОЛБЕЦ2 ]

FROM ТАБЛИЦА1 [, ТАБЛИЦА2]

[ WHERE УСЛОВИЕ_ПОИСКА ]

[ GROUP BY {СТОЛБЕЦ1 [, СТОЛБЕЦ2 ] | INTEGER}

[ HAVING УСЛОВИЕ_ПОИСКА ]]

[ UNION СПЕЦИФИКАЦИЯ_ЗАПРОСА ]

[ ORDER BY СТОЛБЕЦ1 [, СТОЛБЕЦ2 ]

[INTO TEMP TABLE [WITH NO LOG ]]

Как вы уже, наверное, заметили, синтаксис операторов по сути одинаков. Везде присутствуют ключевые слова SELECT, FROM, WHERE, GROUP BY, HAVING, UNION и ORDER BY. В каждом случае эти ключевые слова выполняют одни и те же задачи, но имеют различные опции в зависимости от реализации. Эти опции и называются усовершенствованиями.

Соответствие стандарту ANSI SQL

Производители стараются соответствовать стандарту ANSI SQL. но ни один из их продуктов не соответствует стандарту на 100%. Некоторые производители добавит к стандартным свои команды, и многие из этих команд и функций были приняты стандартом ANSI SQL. Для производителя соответствие стандарту выгодно по многим причинам. Например, в случае соответствия стандарту реализацию соответствующего производителя легко освоить, а создаваемый в рамках данной реализации программный код SQL будет легко переносим от одной реализации к другой. Переносимость, очевидно, оказывается важным фактором, когда приходится переводить базу данных из одной системы управления базами данных в другую. Какая причина может sacia-вить компанию потратить кучу денег на переход к реализации, которая не согласуется со стандартами? Компания не станет этого делать, если переход потребует внесения слишком больших изменений в программное обеспечение, а освоение языка новой реализации потребует слишком больших усилий. ПОЭТОМУ соответствие стандарту ANSI SQL в большинстве случаев проблемой не является.

Расширения SQL

Практически все известные производители имеют свои расширения SQL Каждое расширение SQL по-своему уникально и, вообще говоря, не предполагает переносимости от одной реализации к другой. Однако самые популярные расширения отмечаются стандартом ANSI, а иногда со временем становятся частью нового стандарта.

Примерами расширений стандартного SQL являются PL/SQL, используемый продуктами Oracle, и Transact-SQL, используемый Sybase и Microsoft SQL Server. Оба эги расширения обсуждаются достаточно подробно в примерах следующих разделов.

Примеры расширений

И PL/SQL, и Transact-SQL считаются языками программирования четвертого поколения. Оба, в отличие от стандартного SQL, являются процедурно-ориентированными языками. Кроме них, мы рассмотрим также другую реализацию SQL, называемую MySQL, которую можно найти в Internet.

Непроцедурный язык SQL включает следующие операторы.

• INSERT

• UPDATE

• DELETE

• SELECT

• COMMIT

• ROLLBACK

Любое расширение SQL, являющееся процедурным языком, должно включать все операторы, команды и функции стандартного SQL. Кроме того, такое расширение включает операторы следующего вида.

• Объявления переменных

• Объявления курсоров

• Условные операторы

• Циклы

• Обработчики ошибок

• Различные приращения

• Преобразования данных

• Знаки подстановки

• Триггеры

• Сохраненные процедуры

Эти операторы в рамках процедурного языка дают пользователю более широкие возможности для управления данными.

Стандартный SQL по своей сути является непроцедурным языком, что предполагает предъявление серверу базы данных отдельных операторов. Получив такой оператор, сервер должен решить, каким образом выполнить данный оператор оптимально. Процедурные языки дают программисту возможность не только осуществить запрос на выборку или манипуляцию данными, но и указать серверу базы данных, как именно следует выполнять такой запрос.

Transact-SQL

Transact-SQL является процедурным языком, позволяющим указать базе данных, как и где искать и обрабатывать данные. Стандартный SQL не является процедурным языком, поэтому при его использовании способы извлечения и обработки данных база данных выбирает сама. В Transact-SQL имеются, в частности, возможности объявлять локальные и глобальные переменные, курсоры, программно обрабатывать ошибки, создавать и сохранять триггеры и другие процедуры, использовать циклы, знаки подстановки, преобразовывать одни типы данных в другие, создавать итоговые отчеты.

Вот пример оператора Transact-SQL:

IF (SELECT AVG(COST) FROM PRODUCTSJTBL) > 50

BEGIN

PRINT "ПОНИЗИТЬ ВСЕ ЦЕНЫ НА 10 ПРОЦЕНТОВ."

END

ELSE

PRINT "ЦЕНЫ ПРИЕМЛЕМЫ."

END

Это очень простой оператор Transact-SQL. В результате его выполнения, ••'' •"*-"" если средняя стоимость товаров в таблице PRODUCTSJTBL оказывается выше 50, печатается текст "понизить ВСЕ ЦЕНЫ НА 10 ПРОЦЕНТОВ", а если средняя стоимость товаров не превышает 50, печатается текст "ЦЕНЫ ПРИЕМЛЕМЫ".

Обратите внимание на использование здесь оператора IF.. .ELSE для оценки условий, накладываемых на получаемые данные. Новой здесь является и команда PRINT. Эти дополнительные возможности не составят даже капли в море всех возможностей Transact-SQL.

PL/SQL

PL/SQL является расширением SQL, предлагаемым Oracle. Подобно расширению Transact-SQL, PL/SQL является процедурным языком, структурированным в виде логических блоков программного кода. Блок PL/SQL состоит из трех разделов, два из которых необязательны. Первый раздел представляет собой раздел DECLARE (раздел объявлений) и яшшется необязательным. В разделе DECLARE содержатся переменные, курсоры и константы. Второй раздел - это раздел PROCEDURE (раздел выполняемых операторов), состоящий из условных команд и операторов SQL. Именно в этом разделе осуществляется управление всем блоком, поэтому раздел PROCEDURE является в блоке обязательным. Третий раздел называется разделом EXCEPTION (разделом исключительных состояний), и в нем задается реакция программы на ошибки выполнения и заданные программистом исключительные ситуации. Раздел EXCEPTION в блоке является необязательным. В PL/SQL имеется возможность использования переменных, констант, атрибутов, циклов, обработчиков исключительных ситуаций, отображения сообщений для программиста, управления транзакциями, сохранения процедур, триггеров и пакетов.

Вот пример оператора PL/SQL.

DECLARE

CURSOR EMP_CURSOR IS SELECT EMP_ID, LAST_NAME, FIRST_NAME, MID_INIT

FROM EMPLOYEE_TBL;

EMP_REC EMP_CURSOR%ROWTYPE;

BEGIN

OPEN EMP_CURSOR;

LOOP

FETCH EMP_CURSOR INTO EMP_REC;

EXIT WHEN EMP_CURSOR%NOTFOUND;

IF (EMP_REC.MID_INIT IS NULL) THEN

UPDATE EMPLOYEE_TBL

SET MID_INIT = 'X'

WHERE EMP_ID = EMP_REC.EMP_ID;

COMMIT;

END IF;

END LOOP;

CLOSE EMP_CURSOR;

END;

В данном операторе представлены два из упомянутых выше разделов блока - разделы DECLARE и PROCEDURE. Сначала с помощью запроса объявляется курсор EMP_CURSOR. После этого объявляется переменная EMP_REC, чей тип данных совпадает с типом данных (%ROWTYPE) столбцов объявленного курсора. Первым шагом в разделе PROCEDURE (начинающемся оператором BEGIN) является открытие курсора. После этого для просмотра всех записей курсора используется оператор LOOP, заканчивающийся ключевыми словами END LOOP. Для всех строк курсора, в которых средний инициал имени служащего пропущен (т. е. равен NULL), данные таблицы EMPLOYEEJTBL должны быть обновлены. Обновление состоит в добавлении среднего инициала 'X'. После этого изменения подтверждаются, и курсор, наконец, закрывается.

MySQL

MySQL представляет собой многопользовательское многозадачное приложение баз данных SQL типа клиент/сервер. MySQL состоит из сетевого сервера (демона), терминальной программы-клиента, нескольких дополнительных программ-клиентов и ряда библиотек. Главные преимущества MySQL - скорость работы, надежность и простота использования. Изначально приложение MySQL разрабатывалось для обеспечения быстрого доступа к очень большим базам данных.

Приложение MySQL можно найти в Internet по адресу http://www.mysql.com. Чтобы установить программные файлы MySQL, вам потребуется программа gunzip, чтобы разжать предлагаемый бинарный файл, и подходящая версия программы TAR, чтобы распаковать входящие в него файлы Предлагаемый в Internet бинарный файл будет иметь название mysql-VERSiON-os. tar. gz, где VERSION означает идентификатор версии MySQL, а OS - название соответствующей операционной системы.

Вот пример выполнения запроса в системе MySQL.

mysql> SELECT CURRENT_DATE(),VERSION();

+----------------+------------+

| current date() | version () |

+----------------+------------+

| 1999-08-09 | 3-22.23b |

+----------------+------------+

1 row in set (0.00 sec)

mysql>

Интерактивные операторы SQL

Интерактивные операторы SQL - это такие операторы SQL, которые сами спрашивают о необходимых переменных, параметрах и других необходимых для их выполнения данных Скажем, у вас имеется интерактивный оператор SQL для создания в базе данных записей с информацией о новых пользователях. Такой оператор SQL может попросить вас ввести учетную запись нового пользователя, его реальное имя и номер контактною телефона. Такой оператор применяется для ввода информации об одном новом пользователе или о многих одновременно. Без такого оператора для каждого из пользователей пришлось бы выполнить свой отдельный оператор CREATE ScR Интерактивный оператор SQL может запросить у вас информацию о привилегиях для создаваемого пользователя Не все производители предлагают интерактивные опера юры SQL. вам придется уточнить это по документации, сопровождающей систему управления базой данных В следующих разделах приводятся примеры использования интерактивных операторов SQL в базах данных Oracle.

Использование параметров

Параметры представляют собой переменные SQL, размещенные в программе. Параметры можно передавать операторам SQL во время выполнения приложения, что придает этим операторам дополнительную гибкость. Практически все 1лавные реализации SQL допускают использование параметров. Мы рассмотрим примеры передачи параметров в Oracle и Sybase.

Oracle

В Oracle предусмотрена передача параметров операторам, которые в противном случае оставались бы статическими операторами SQL.

SELECT EMP_ID, LAST_NAME, FIRST_NAME

FROM EMPLOYEEJTBL

WHERE EMP_ID = '&EMP__ID'

Этот оператор возвратит данные столбцов EMP_ID, LAST_NAME, FIRST_NAME таблицы EMPLOYEE_TBL для служащего с любым табельным номером EMP_ID, который вас попросит этот оператор ввести.

SELECT *

FROM EMPLOYEE_TBL

WHERE CITY = '&CITY'

AND STATE = '&STATE'

Этот оператор спросит у вас названия города и штата. В результате выполнения запроса к базе данных оператор возвратит данные обо всех служащих, проживающих в указанных вами городе и штате.

Sybase

В Sybase параметры можно передать сохраненной ранее процедуре

CREATE PROC EMP_SEARCK

(@EMP_ID)

AS

SELECT LAST_NAME, FIRST_NAME

FROM EMPLOYEE_TBL

WHERE EMP_ID = @EMP__ID

Чтобы выполнить созданную здесь процедуру с передачей ей подходящич параметров, вам придется напечатать что-то похожее на следующий оператор SP_EMP_SEARCH "443679012"

Резюме

В ходе этого урока мы обсудили расширения стандартного SQL, предлагаемые рядом производителей систем управления базами данных и их соответствие стандарту ANSI. После того, как вы изучили SQL, применение ваших знаний и вашего программного кода в рамках других реализаций языка окажется для вас достаточно простым делом. SQL обладает хорошей переносимостью от системы к системе и для адаптации программного кода потребуется при этом не слишком много усилии.

В конце этого урока были рассмотрены два конкретных расширения SQL использующиеся тремя системами управления базами данных. Transact-SQL используется Microsoft SQL Server и Sybase, a PL/SQL используется Oracle Принципы, заложенные в основу этих расширений SQL, оказываются достаточно схожими. Например, оба ли расширения имеют стандартные возможности и усовершенствования, позволяющие повысить общую функциональность языка и эффективность работы В главе обсуждался продукт MySQL, специально предназначенный для ускорения работы с очень большими базами данных. Цель этого урока - показать, что расширений SQL существует немало и что одним из важнейших требований ко всем реализациям языка оказывается соответствие стандарту ANSI SQL.

Применив информацию из этой книги к своим конкретным задачам (т. е создав программный код, отладив его и заставив выполнять конкретную работу), вы вступите на путь практического освоения SQL. Компании имеют дело с массой данных, и поэтому не могут обойтись без баз данных. Реляционные базы данных имеются повсюду, а поскольку стандартным языком общения с реляционными базами данных и управления ими является SQL, то ваше решение освоить этот язык, безусловно, было решением правильным. Удачи вам!

Вопросы и ответы

Почему существуют различные вариации SQL?

Вариации SQL существуют потому, что различные производители по-разному решают проблемы представления и хранения данных, из-за амбициозного стремления каждого производителя получить преимущество по сравнению с другими, а также из-за постоянно возникающих новых идей.

После изучения основ SQL получаю ли я возможность использовать SQL в различных системах управления базами данных?

Да. Однако не забывайте о том, все реализации имеют свои особенности и поэтому в чем-то отличаются одна от другой. Общими для всех реализаций остаются как раз основные конструкции SQL.

Практикум

Задания практических занятий разделены на тесты и упражнения. Тесты предназначены для проверки общего уровня понимания рассмотренного материала. Упражнения дают возможность применить на практике идеи, обсуждавшиеся в ходе текущего урока, в комбинации с идеями из предыдущих уроков. Мы рекомендуем ответить на тестовые вопросы и выполнить упражнения прежде, чем продолжать дальнейшее чтение книги. Ответы можно проверить по Приложению Б, "Ответы".

Тесты

1. Каким языком является SQL - процедурным или непроцедурным?

2. Почему существуют различия между разными реализациями SQL?

3. Назовите три основные операции, которые выполняются с курсором после его объявления.

4. При использовании какого (процедурного или непроцедурного) языка обращения к базе данных ядро базы данных само принимает решение о том, как обрабатывать и выполнять операторы SQL?

Упражнения

1. Попробуйте самостоятельно обнаружить различия между реализациями SQL разных производителей. В библиотеке или книжном магазине ознакомьтесь с книгами по соответствующим реализациям языка. Сравните синтаксис соответствующих операторов SQL, в частности, операторов DML (языка манипуляций данными). Сравните формы операторов INSERT, DELETE и UPDATE. При этом для сравнения можно заглянуть также и в книгу по ANSI SQL.

2. Используя таблицу EMPLOYEEJTBL (см. Приложение В, "Операторы CREATE TABLE для примеров книги"), запишите интерактивный оператор SQL, возвращающий имена всех служащих, имеющих ZIP-код, равный 46234.

Content

SQL за 24 часа

SQL за 24 часа

1-й час Добро пожаловать в мир SQL

2-й час Структура данных

3-й час Управление объектами базы данных

4-й час Процесс нормализации

5-й час Манипуляция данными

6-й час Управление транзакциями

7-й час Знакомство с запросами

8-й час Операции в условиях для отбора данных

9-й час Подведение итогов по данным запроса

10-й час Сортировка и группирование данных

11-й час Изменение представления данных при выводе

12-й час Работа с датами и временем

13-й час Объединение таблиц в запросах

14-й час Использование подзапросов

15-й час Объединение запросов

16-й час Использование индексов для ускорения поиска данных

17-й час Повышение эффективности работы с базой данных

18-й час Управление доступом к базе данных

19-й час Обеспечение сохранности данных

20-й час Создание и использование представлений и синонимов

21-й час Работа с системным каталогом

22-й час Средства опытного пользователя

23-й час Использование SQL в локальных и глобальных сетях

24-й час Расширения стандартного SQL