ГЛАВНАЯ Визы Виза в Грецию Виза в Грецию для россиян в 2016 году: нужна ли, как сделать

SQL команды. Механизм доступа к данным

3.1 Общие положения

Изложенные выше механизмы РМД легли в основу языков манипулирования данными. Заметим, что крайне редко РА или РИ принимаются в качестве полной основы какого-либо языка РБД. Обычно язык основывается на некоторой смеси алгебраических и логических конструкций.

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

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

1) команды определения данных (Data Definition Commands), которые служат для создания, изменения, удаления таблиц и индексов, а также для определения схемы БД;

2) команды манипулирования данными (Data Manipulation Commands) для изменения данных (редактирование существующих данных, добавление и удаление записей);

3) команды выборки данных (Data Query Commands) для выборки существующих данных;

4) команды управления транзакциями (Transaction Control Commands) для сохранения или отката изменений в БД;

5) команды управления данными (Data Control Commands) для проверки целостности БД, предоставления и отмены привилегий на доступ к данным.

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

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

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

– звездочка (*) означает "все" и употребляется в обычном для программирования смысле, т.е. "все случаи, удовлетворяющие определению";

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

– фигурные скобки ({}) означают, что конструкции, заключенные в эти скобки, должны рассматриваться как целые синтаксические единицы; эти скобки позволяют уточнить порядок разбора синтаксических конструкций, заменяя обычные скобки, используемые в синтаксисе SQL;

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

– прямая черта (|) означает наличие выбора из двух или более возможностей; например, конструкция [термин_1 | термин_2] означает, что можно выбрать один из двух терминов (или термин_1, или термин_2); при этом термин_1 выбирается по умолчанию; отсутствие всей этой конструкции будет восприниматься как выбор термин_1;

– точка с запятой (;) завершающий элемент предложений SQL; этот знак должен присутсвовать после каждой команды;

– запятая (,) используется для разделения элементов списков;

– пробелы () могут вводиться для повышения наглядности между любыми синтаксическими конструкциями предложений SQL;

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

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

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

Язык SQL: классификация команд

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

— команды для построения запросов;

— команды встроенных функций и процедур;

— команды системных таблиц и триггеров;

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

— команды для работы с таблицами и данными.

Эту классификацию можно продолжать бесконечно долго, однако основные наборы команд языка SQL будут строиться именно исходя из представленных типов. Рассматривая классификацию языка, нельзя не сказать о том, что он универсален. Об этом лишний раз свидетельствует сфера его применения. Данный язык программирования и его разновидности используются не только в стандартной среде, но и в других программах, которые вы использовали, так или иначе. Можно рассматривать сферу использования SQL с точки зрения офисного программного обеспечения. Речь идет о MicrosoftAccess. Данный язык, а если говорить точнее, его разновидность MySQL, дает возможность администрировать базы данных в Интернете. Среда разработки Oracle использует команды SQL на основе своих запросов.

Применение SQL в Microsoft Access

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

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

SELECTPe_SurName

WHEREPe_Name = ‘Мери’;

Рассматривая синтаксис данной программы, можно сказать, что она вернет пользователю фамилию человека. В данном случае речь идет о женщине по имени Мери, имя которой хранится в базе данных Contacts. Хотя использование SQL в Access ограничено, такие простые запросы иногда сильно упрощают выполнение поставленного задания.

Использование команд SQL в Oracle

Oracle является наверное единственным серьезным конкурентом Microsoft SQL Server. Эта среда разработки и управления БД постоянно приводит к усовершенствованию функций программного продукта от компании Microsoft, поскольку конкуренция является двигателем прогресса. Команды SQL Oracle, несмотря на постоянное соперничество, повторяют SQL. Необходимо отметить, что хотя Oracle практически считается копией SQL, логика данной системы и в целом языка считается проще. При использовании определенного набора команд система Oracle не имеет такой сложной структуры. Если рассматривать возможности этих сред разработки баз данных, то у Oracle нет сложной структуры вложенных запросов. Подобная разница дает возможность во много раз ускорить работу с данными. Однако в противовес это в некоторых случаях может привести к нерациональному использованию памяти в отдельных случаях. В основном структура Oracle построена на временных таблицах и их применении. К примеру, SQL команды в данной системе строятся по аналогии со стандартами языка SQL, хотя и отличаются от него.

SELECTCONCAT(CONCAT(CONCAT(‘Сотрудник ‘, sname),

CONCAT(SUBSTR(fname, 0, 1), SUBSTR(otch, 0, 1))),

CONCAT(‘принят на работу ‘, acceptdate))

FROM employees WHERE acceptdate>to_date(‘01.01.80′,’dd.mm.yyyy’);

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

Применение SQL в сети Internet

После появления всемирной паутины, или иначе говоря, интернета, сфера применения языка SQL была существенно расширена. В сети, как известно, хранится большой объем информации. При этом она расположена не хаотично, а размещена на серверах и сайтах по определенным критериям. За хранение информации в Интернете и других местах отвечают непосредственно базы данных. Сайты представляют собой системы управления. Сайты и их программный код, как правило, организованы на разных языках программирования. В основе баз данных лежит одна из разновидностей SQL, а именно язык создания баз данных, который ориентирован на веб-интерфейсы MySQL. Основной набор команд и синтаксис данного языка полностью копируют SQL. Однако имеются некоторые дополнения, которые и придают ему отличие от Microsoft SQL Server. Команды SQL похожи не только по синтаксису, но и по набору служебных слов. Разница заключается только в структурировании и вызове запроса. Можно рассмотреть для примера запрос для создания новой таблицы. Именно этому прежде всего и учат детей на уроках информатики.

$link = mysqli_connect(‘localhost’, «root», », ‘tester’);

if (!$link) die(«Error»);

$query = ‘create table users(

login VARCHAR(20),

password VARCHAR(20))’;

if (mysqli_query($link, $query)) echo «Таблицасоздана.»;

elseecho «Таблица не создана: «.mysqli_error();

mysqli_close($link);

Результатом выполнения такого запроса будет создание новой таблицы Users с двумя полями: логин и пароль. В данном случае синтаксис изменен под Веб. В основе лежат команды MicrosoftSQLServer.

Microsoft SQL Server: построение запросов

Одной из основных задач SQL является выборка из таблиц определенного набора данных. Для выполнения таких операций в SQL предусмотрена команда select. О ней и будет идти речь ниже. Правила построения команд довольно просты. Сама команда select в SQL строится следующим образом. Предположим, у вас имеется таблица, в которой присутствуют данные о сотруднике. Таблица имеет имя Person. Вам нужно выбрать данные о сотрудниках, дата рождения которых лежит в промежутке с первого января по первое сентября текущего года. Чтобы осуществить такую выборку необходимо выполнить команду SQL, в которой будет использоваться не только стандартная конструкция, но и примерно такое условие выбора: Select * fromPersonWhereP_BirthDay>=’01/01/2016’ andP_BirthDay=’01/01/2016’ andP_BirthDay= @DB and P_BerthDay0 и =" Smith ").

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

SELECT FirstName, LastName, State FROM tblCustomer

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

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

Можно создавать более сложные предложения WHERE, связывая два и более критерия с помощью логических операторов AND или OR. Например, необходимо отобрать всех клиентов, проживающих в городе Денвер (Denver) штата Колорадо (СО), т.е. вас не интересуют те клиенты, которые проживают в других городах этого штата. Для этого нужно задать два критерия и связать их оператором AND, как показано в приведенном ниже примере.

WHERE (State = "CO") AND (City = "Denver")

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

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

SELECT FirstName, LastName, City, State WHERE State = "CO" OR State = "CA"

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

НА ЗАМЕТКУ

Ключ к успешной разработке приложений клиент/сервер – выработка такой тактики, согласно которой приложение-клиент не заказывало бы слишком много записей в одной выборке. Это гарантирует, что приложения будут выполняться быстро и компьютеры ваших пользователей не зависнут. Залог успеха вашей работы - рациональное использование предложения WHERE.

При построении предложения WHERE можно использовать операторы, перечисленные в табл. 2.1.

Таблица 2.1. операторы, используемые в предложении WHERE

Оператор Функция
< Меньше
Больше
>= Больше или равно
= Равно
Не равно
BETWEEN Внутри диапазона значений
LIKE Соответствует образцу
IN Входит в список значений
Оператор BETWEEN

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

WHERE OrderDate BETWEEN "1/4/2001" AND "6/5/2001"

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

Обратите внимание, что значения даты в SQL Server обозначаются символом одиночной кавычки. Разработчикам, которые имеют опыт работы с датами в Microsoft Access и привыкли использовать для этого символ #, придется учесть это новшество и заменить символы # одиночными кавычками.

РИС. 2.4. Результаты выполнения запроса для таблицы tblOrder с использованиям предложения SELECT и оператора BETWEEN


Границы оператора BETWEEN являются включающими; это значит, что если вы запрашиваете информацию обо всех заказах, оформленных за период с 4 января по 5 июня 2001 года, то в результирующий набор включаются заказы, которые были оформлены как 4 января, так и 5 июня.

Оператор LIKE и символы шаблона

С помощью оператора LIKE отбираются записи, соответствующие заданному шаблону. Этот шаблон обычно состоит из так называемых подстановочных символов (wildcard characters) * или с которыми вы, возможно, уже знакомы по работе с файловыми системами MS DOS или Windows.

Символ процента (%) означает частичное соответствие. Например, чтобы отобрать в таблице tblCustomer все записи, в которых фамилия начинается с буквы J, можно воспользоваться приведенным ниже запросом.

SELECT ID, FirstName, LastName, Address, City, State

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

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

SELECT ID, FirstName, LastName, Address, PostalCode

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

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

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

НА ЗАМЕТКУ

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

Оператор IN

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

SELECT FirstName, LastName, State

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

Сортировка результатов с помощью предложения ORDER BY

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

SELECT ID, FirstName, LastName

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

Сортировка в убывающей последовательности

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

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

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

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

SELECT FirstName, LastName, City, State

В результате выполнения этого запроса из таблицы tblCustomer будут извлечены все записи, отсортированные по фамилиям, а затем по именам (например, за клиентом Betty Klein будет располагаться клиент Daisy Klein).

Отображение первых или последних записей диапазона с помощью предложения ТОР

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

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

SELECT ID, OrderDate, CustomerID

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

В результате выполнения этого запроса из таблицы tblOrder будут извлечены три записи для наиболее крупных заказов.

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

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

Этот запрос показывает три самых "древних" заказа в базе данных.

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

Создание запросов TOP PERCENT

Можно писать запросы, возвращающие записи, количество которых определяется заданным процентом от общего количества записей в таблице. Например, если у вас есть таблица с 1000 записей и необходимо возвратить один процент первых записей, то, как правило, будет отображено 10 записей. (Возможно, будет отображено более 10 записей, если несколько записей имеют одинаковое значение. Такой же случай рассматривался и для запроса ТОР N.)

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

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

Объединение связанных таблиц в запросе

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

tblCustomer
ID
FirstName
LastName
Address
City
State
PostalCode
Phone
Fax
Email
tblOrder
ID
CustomerID
OrderDate
OrderAmount

Хотя в таблице tblOrder хранится информация о заказах, а в таблице tblCustomer - информация о клиентах, вполне вероятно, что вам потребуется, например, отобрать такую информацию о заказах клиентов, как показано ниже.


FirstName LastName OrderDate
Jane Winters 9/10/2001
Jane Winters 8/16/2001
Thurston Ryan 7/2/2001
Dave Martin 6/5/2001
Daisy Klein 4/4/2001
...

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

НА ЗАМЕТКУ

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

Выражение объединения в SQL

В SQL Server объединение можно установить с помощью выражения эквивалентности между двумя полями, например:

Этот запрос SQL возвращает информацию обо всех клиентах, которые имеют заказы в таблице tblOrder. В результате выполнения запроса возвращаются три столбца данных: поля FirstName и LastName из таблицы tblCustomer, а также поле OrderDate из таблицы tblOrder.

Обратите внимание, что в запросе с объединением таблиц при использовании полей, имеющих одинаковые имена, но принадлежащих разным таблицам, необходимо перед именем поля вставлять ссылку на соответствующую таблицу (например, tblOrder.ID вместо ID). В большинстве случаев при использовании конструктора представлений в среде Visual Studio .NET для создания запроса интегрированная среда разработки способна определить выполняемые действия и дополнить выражение недостающими частями. Как уже сообщалось ранее, в данной книге примеры инструкций SQL приводятся в наиболее кратком виде, а необязательные части применяются только в случае необходимости.

Использование конструктора представлений для создания объединений

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

1. В окне Server Explorer создайте новое представление для базы данных Novelty.

2. После этого появится диалоговое окно Add Table (Создать таблицу), в котором следует указать таблицы tblCustomer и tblOrder, а затем щелкнуть на кнопке Close. Схема представления в окне конструктора представлений показана на рис. 2.5.

РИС. 2.5. Создание объединения двух таблиц в окне конструктора представлений

Обратите внимание на то, что конструктор представлений автоматически создает объединение между двумя таблицами на основе известного ключевого поля ID в таблице tblCustomer и явно заданного ранее отношения с полем CustomerID в таблице tblOrder.

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

Использование внешних объединений

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

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

SELECT FirstName, LastName, OrderDate FROM tblCustomer LEFT OUTER JOIN tblOrder ON tblCustomer.ID = tblOrder.CustomerID

Обратите внимание, что в предложении LEFT JOIN используется синтаксис имя_таблицы.имя_поля. Более длинное имя позволяет избежать неоднозначности при использовании полей с одинаковыми именами, поскольку поле ID существует как в так и в tblOrder. Фактически предложение LEFT OUTER JOIN означает, что будут отображены все данные таблицы tblCustomer, которая находится в левой стороне выражения tblCustomer.ID = tblOrder.CustomerID.

РИС. 2.6. Выполнение запроса на основе объединения двух таблиц в окне конструктора представлений

Этот запрос возвращает приведенный ниже набор записей.

FirstName LastName OrderDate
John Smith 1/4/2001
John Smith 1/9/2001
Jill Azalia 1/14/2001
Brad Jones
Daisy Klein 2/18/2001
Daisy Klein 3/21/2001
Daisy Klein 4/4/2001
Dave Martin 6/5/2001
Betty Klein
Thurston Ryan 7/2/2001
Jane Winters 8/16/2001
Jane Winters 9/10/2001

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

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

Выполнение вычислений в запросах

В строках запроса допускается выполнение вычислений. Для этого нужно просто заменить имя поля в предложении SELECT именем арифметического выражения. Допустим, вам нужно создать запрос для вычисления налога с продаж для складских запасов (сведения о которых хранятся в таблице tblItem). В приведенном ниже запросе SQL вычисляется налог с продаж с учетной ставкой 7,5% для каждого товара.

SELECT ID, Item, Price, Price * 0.075 AS SalesTax

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

ID Name Price SalesTax
1 Rubber Chicken 5.99 0.44925
2 Hand Buzzer 1.39 0.10425
3 Stink Bomb 1.29 0.09675
4 3.99 0.29925
5 Invisible Ink 2.29 0.17175
6 Loaded Dice 3.49 0.26175
7 Whoopee Cushion 5.99 0.44925

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

SELECT Name, Retail Price, ROUND (Retail Price + Retail Price * 0.075, 2)

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

Name Retail Price PriceWithTax
Rubber Chicken 5.99 6.44
Hand Buzzer 1.39 1.49
Stink Bomb 1.29 1.39
Disappearing Penny Magic Trick 3.99 4.29
Invisible Ink 2.29 2.46
Loaded Dice 3.49 3.75
Whoopee Cushion 5.99 6.44
Определение псевдонимов с использованием предложения AS

Из предыдущего примера ясно, что существует возможность определения псевдонимов (alias), т.е. переименования полей в запросе. Это может быть вызвано следующими причинами:

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

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

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

SELECT TOP 5 ItemID, Quantity, Price, tblInventory.RetailPrice * tblOrderTime.Quantity AS ExtendedPrice tblInventory ON tblOrderTime.ItemID = tblITem.ID ItemID Quantity RetailPrice ExtendedPrice
1 1 5.99 5.99
2 2 1.39 2.78
5 3 2.29 6.87
4 2 3.99 7.98
7 1 5.99 5.99

Обратите внимание, что данные в поле ExtendedPrice не хранятся в базе данных, они вычислены "на лету".

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

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

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

SELECT CustomerID, COUNT(CustomerID) AS TotalOrders

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

CustomerID TotalOrders
1 2
2 1
4 3
5 1
7 1
8 2

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

Для отображения имен клиентов вместо их идентификаторов нужно просто объединить с результатами запроса данные из таблицы tblCustomer.

SELECT tblOrder.CustomerID, FirstName, LastName FROM tblOrder INNER JOIN tblCustomer ON tblOrder.CustomerID = tblCustomer.ID

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

CustomerID FirstName LastName TotalOrders
1 John Smith 2
2 Jill Azalia 1
4 Daisy Klein 3
5 Dave Martin 1
7 Thurston Ryan 1
8 Jane Winters 2

В этом случае предложение GROUP BY содержит поле CustomerID вместе с объединенными полями FirstName и LastName из таблицы tblCustomer. При использовании предложения GROUP BY в него необходимо включить все поля, по которым группируются извлекаемые записи. В данном случае идентификатор клиента и его имя участвуют в группировании данных и потому присутствуют в предложении GROUP BY. (К счастью, если вы забудете выполнить эту операцию, среда Visual Studio .NET автоматически предложит вам сделать это.)

Применение предложения HAVING для группирования данных в запросах

Как уже отмечалось выше, критерий запроса служит для ограничения количества извлекаемых записей. В обычных запросах для включения критериев используется предложение WHERE, в запросах с группированием - предложение HAVING. Эти предложения применяются совершенно одинаково, за исключением того, что HAVING относится к агрегированным строкам (т.е. к результату группирования), a WHERE – к отдельным строкам. Это довольно незначительное отличие, потому что в 9 случаях из 10 они дают совершенно одинаковый результат. Например для создания отчета о продажах клиента Jane с группированием данных можно использовать приведенный ниже запрос.

COUNT(dbo.tblOrder.CustomerID) AS TotalOrders FROM tblOrder INNER JOIN tblCustomer ON tblOrder.CustomerID = tblCustomer.ID GROUP BY FirstName, LastName, CustomerID

Этот запрос возвращает одну запись для клиента Jane Winters с указанием двух сделанных ею заказов. Допустим, теперь нужно получить список активных покупателей, т.е. клиентов, сделавших более одного заказа. Поскольку агрегированное количество заказов хранится в вычисленном поле TotalOrders, можно предположить, что для определения таких клиентов допустимо использовать выражение HAVING TotalOrders > 1. К сожалению, это выражение некорректно, так как TotalOrders – это не поле базы данных, а вычисленное поле. Вместо этого следует включить данное вычисление в предложение HAVING показанного ниже запроса.

SELECT tblOrder.CustomerID, FirstName, LastName, COUNT(dbo.tblOrder.CustomerID) AS TotalOrders FROM tblOrder INNER JOIN tblCustomer ON tblOrder.CustomerID = tblCustomer.ID GROUP BY FirstName, LastName, CustomerID HAVING (COUNT(tblOrder.CustomerID) > 1)

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

CustomerID FirstName LastName TotalOrders
1 John Smith 2
4 Daisy Klein 3
8 Jane Winters 2
Функция SUM

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

SELECT OrderID, SUM(Quantity) AS TotalItems

Этот запрос возвращает приведенный ниже результирующий набор.

OrderID TotalItems
1 6
2 2
3 1
4 23
5 4
6 13
7 12
8 3
9 4
10 4

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

Перечень итоговых функций

В табл. 2.2 перечислены все итоговые функции, доступные в SQL.

Таблица 2.2. Итоговые функции SQL


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

SELECT AVG(tblOrderItem.Quantity) AS AverageLineItemQuantity tblOrderItem ON tblOrder.ID = tblOrderItem.OrderID

Этот запрос возвращает значение 2, т.е. количество товаров в заказах всех клиентов.

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

SELECT tblOrderItem.OrderID, SUM(Quantity * Price) tblOrderItem ON tblItem.ID = tblOrderItem.OrderID GROUP BY OrderID

Этот запрос возвращает приведенный ниже результирующий набор.

OrderID OrderTotal
1 15.64
2 7.98
3 5.99
4 99.17
5 13.96
6 49.07
7 55.88
8 13.97
9 9.16
10 14.76
Запросы на объединение

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

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

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

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

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

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

Подзапросы

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

Единственное синтаксическое различие между подзапросом и выражением любого другого типа, размещенным в предложении WHERE, состоит в том, что подзапрос должен быть заключен в круглые скобки. Например, нужно создать запрос, который отображает заказы с самыми дорогими товарами. Дорогим считается такой товар, стоимость которого превышает среднюю стоимость товаров в таблице tblItem. Поскольку среднюю стоимость товара легко определить (выполнив итоговую функцию AVG по полю UnitPrice в таблице tblItem), это значение можно использовать как подзапрос в более крупном запросе. Такой запрос SQL приведен ниже.

WHERE (UnitPrice > (SELECT AVG(UnitPrice) FROM tblItem)

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

Приведенная выше инструкция SQL возвращает следующий результирующий набор:

Name UnitPrice
Rubber Chicken 5.99
Disappearing Penny Magic Trick 3.99
Loaded Dice 3.49
Whoopee Cushion 5.99
Манипулирование данными с помощью SQL

Команда манипулирования данными (data manipulation command) - это команда SQL, которая изменяет записи. Такие команды создаются на языке манипулирования данными DML, который является подмножеством языка SQL. Эти команды не возвращают записи, а только изменяют их в базе данных.

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

В среде Visual Studio .NET предусмотрен очень мощный интерфейс для выполнения DML-команд. Действительно, инструменты среды Visual Studio .NET могут пре

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

НА ЗАМЕТКУ

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

На низком уровне (т.е. не на уровне графического интерфейса пользователя) DML-команды SQL можно использовать с помощью следующих двух инструментов:

Microsoft SQL Server Query Analyzer (или просто Query Analyzer) - инструмент с графическим интерфейсом пользователя для создания запросов и команд для SQL Server;

Osql - используемый в режиме командной строки процессор запросов.

Вы можете использовать любой из этих инструментов, а в данной главе применяется Query Analyzer, который обладает более широкими возможностями и более удобен в употреблении, чем процессор запросов osql. В настоящей главе основное внимание сосредоточено на фактически выполняемых командах, а не на методах использования графического интерфейса Query Analyzer. Инструмент Query Analyzer находится в группе программ Microsoft SQL Server. (В главе 7, "ADO.NET: дополнительные компоненты", более подробно рассматриваются способы применения DML-команд в среде Visual Studio.NET.)

Запросы на обновление

Запрос на обновление может изменить сразу целую группу записей. Этот запрос состоит из трех частей:

Предложение UPDATE, которое указывает на обновляемую таблицу;

Предложение SET, задающее данные для обновления;

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

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

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

Ниже приведены значения полей после выполнения данного запроса на обновление.

ID Name Description UnitPrice Price
1 Rubber Chicken A classic laugh getter 2.0300 6.5890
2 Hand Buzzer Shock your friends .8600 1.5290
3 Stink Bomb Perfect for ending boring meetings .3400 1.4190
4 Invisible Ink Write down your most intimate thoughts 1.4500 2.5190
5 Loaded Dice Not for gambling purposes 1.4600 3.8390
6 Whoopee Cushion The ultimate family gag 2.0300 6.5890

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

Эта команда увеличивает на 10% цену на товары, текущая цена которых больше $100.

Запросы на удаление

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

WHERE OrderDate < "10/31/2002" Запрос на добавление записей

Запрос на добавление (append query) используется в двух случаях:

При добавлении одиночной записи в таблицу;

При копировании одной или нескольких записей из одной таблицы в другую.

Для создания запроса на добавление используйте предложение SQL INSERT. Точный синтаксис запроса зависит от того, добавляете ли вы одну запись или копируете несколько. Например, для добавления одной новой записи в tblOrder можно использовать приведенный ниже запрос.

INSERT INTO tblOrder(CustomerID, OrderDate)

При выполнении этого запроса в таблице tblOrder создается новый заказ для клиента с идентификационным номером 119 и датой 16 июня 2001 года.

НА ЗАМЕТКУ

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

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

НА ЗАМЕТКУ

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

Ниже приведена инструкция SQL для копирования старых записей из tblOrder в tblOrderArchive.

При выполнении этой инструкции SQL в таблицу tblOrderArchive копируются все записи, содержащие заказы, которые были оформлены до 1 июня 2001 года.

Запросы на основе команды SELECT INTO

Запрос на основе команды SELECT INTO аналогичен запросу на добавление, за исключением того, что он создает новую таблицу и сразу же копирует в нее записи. В Microsoft Access он называется запросом на создание таблиц (make-table query). Так, в предыдущем примере все записи из таблицы tblOrder копировались в таблицу tblOrderArchive, исходя из предположения, что таблица tblOrderArchive уже существует. Вместо этого запроса для копирования тех же записей в новую таблицу с такой же структурой, как и у оригинала, воспользуйтесь приведенным ниже запросом SQL.

НА ЗАМЕТКУ

Этот запрос копирует все записи из tblOrder в новую таблицу с именем tblOrderArchive. Однако если такая таблица уже существует, эта команда не будет выполнена. Это отличается от результата выполнения данного запроса в Microsoft Access.

Если его выполнить в окне конструктора запросов программы Access при условии, что таблица tblOrderArchive уже существует, то процессор баз данных удалит исходную таблицу и заменит ее вновь созданной, которая будет заполнена содержимым скопированных записей. В SQL Server для удаления таблицы нужно использовать DDL-команду DROP TABLE.

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

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

Команды языка определения данных (Data Definition Language - DDL) представляют собой инструкции SQL, которые позволяют создавать элементы структуры базы данных, манипулировать ими и удалять. Используя DDL, можно создавать и удалять таблицы, а также изменять структуру этих таблиц.

Команды DDL относятся к наиболее редко используемым инструкциям в SQL в основном потому, что существует множество прекрасных инструментов, которые позволяют легко справиться с задачами создания таблиц, полей и индексов. В среде Visual Studio.NET DDL-команды SQL используются незаметно для разработчика при создании схемы базы данных в окне Server Explorer, но в ней не предусмотрены инструменты для непосредственного выполнения команд SQL по отношению к базе данных. Для этого следует применять инструменты Query Analyzer и osql либо использовать DDL-команды непосредственно в коде.

Но если вы работаете в среде клиент/сервер, то для создания структуры базы данных удобнее использовать DDL-команды. Подобно командам манипулирования данными, DDL-команды не возвращают результирующих наборов (поэтому их и называют не запросами, а командами).

Создание элементов базы данных с помощью предложения CREATE

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

Тип данных char(2), означает, что процессор баз данных должен создать текстовое поле фиксированной длины для хранения максимум двух символов, а выражение varchar (50) указывает на создание поля с переменной длиной до 50 символов.

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

tblRegion
State
Region

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

Добавление ограничений в таблицу

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

Ограничение создается с помощью предложения SQL CONSTRAINT, которое принимает два параметра: имя индекса и имя поля или полей, в индексации которых вы заинтересованы. Можно объявить индекс с помощью ключевого слова UNIQUE или PRIMARY, и тогда этот индекс будет означать, что поле может принимать только уникальные значения или что поле (поля) служит первичным ключом таблицы.

НА ЗАМЕТКУ

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

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

CONSTRAINT StateIndex UNIQUE (State)

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

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

State char Region varchar (50), CONSTRAINT StatePrimary PRIMARY KEY (State) Назначение внешнего ключа

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

CONSTRAINT IDPrimary PRIMARY KEY (ID), CONSTRAINT StateForeign FOREIGN KEY (State) REFERENCES tblRegionNew (State)

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

Создание индексов с помощью команды CREATE INDEX

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

Для создания индекса в существующей таблице используйте приведенную ниже команду SQL.

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

CREATE UNIQUE INDEX StateIndex

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

CREATE UNIQUE NONCLUSTERED INDEX StateIndex ON tblRegion ( Удаление таблиц и индексов с помощью предложения DROP

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

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

DROP INDEX tblRegion.StateIndex

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

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

Модификация структуры таблицы с помощью предложения ALTER

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

Для того чтобы удалить поле из базы данных, используйте предложение DROP COLUMN вместе с предложением ALTER TABLE, как показано ниже.

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

ADD CONSTRAINT OrderForeignKey

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

Резюме

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

Большая часть материала этой главы приводится отнюдь не ради увеличения объема книги; начав программировать с использованием Visual Studio .NET и ADO.NET, вы почувствуете реальную пользу от прочитанного.

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

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

Квадратные скобки часто окружают имена объектов в среде Visual Studio.NET и административных инструментах SQL Server для исключения проблем при использовании имен с пробелами и другими зарезервированными символами и словами. Например в базе данных Northwind, которая инсталлируется вместе с SQL Server 2000, есть таблица с именем Order Details. Хотя в общем случае не рекомендуется включать пробелы в имена таблиц, ее все же можно использовать в SQL Server в виде . Однако инструменты с графическим интерфейсом, например в среде Visual Studio .NET, всегда добавляют квадратные скобки. Но в данной книге они не используются, чтобы исключить излишнюю работу по их вводу.

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

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

SQL (ˈɛsˈkjuˈɛl; англ. structured query language - «язык структурированных запросов») - декларативный язык программирования, применяемый для создания, модификации и управления данными в реляционной базе данных.

Соответствие стандартам SQL разных БД:

SQL (Structured Query Language - язык структурированных запросов). SQL является, прежде всего, информационно-логическим языком, предназначенным для описания хранимых данных, для извлечения хранимых данных и для модификации данных.

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

SQL является регистронезависимым языком. Cтроки в SQL берутся в одинарные кавычки.

Язык SQL представляет собой совокупность операторов. Операторы SQL делятся на:

    операторы определения данных (Data Definition Language, DDL) - язык описания схемы в ANSI, состоит из команд, которые создают объекты (таблицы, индексы, просмотры, и так далее) в базе данных (CREATE, DROP, ALTER и др.).

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

    операторы определения доступа к данным (Data Control Language, DCL) - состоит из средств, которые определяют, разрешить ли пользователю выполнять определенные действия или нет (GRANT/REVOKE , LOCK/UNLOCK).

    операторы управления транзакциями (Transaction Control Language, TCL)

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

SELECT раздел JOIN

    Простой JOIN (=пересечение JOIN =INNER JOIN) - означает показывать только общие записи обоих таблиц. Каким образом записи считаются общими определяется полями в join- выражении. Например следующая запись: FROM t1 JOIN t2 ON t1. id = t2. id

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

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

    RIGHT JOIN (или RIGHT OUTER JOIN) действует в противоположность LEFT JOIN - показывает все записи из правой (второй) таблицы и только совпавшие из левой (первой) таблицы.

    Другие виды JOIN объединений: MINUS - вычитание; FULL JOIN - полное объединение; CROSS JOIN - “Каждый с каждым” или операция декартова произведения.

SELECT JOIN SUBSTRING INSERT INTO users_auth VALUES (default, "root" , MD5("root"));

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

INSERT IGNORE INTO prices VALUES(DEFAULT, 1, 1111, "Fr", 50, 50, 1, 1)

Команда REPLACE отличается от INSERT только тем, что если в таблице имеется запись с таким же значением в индексированном поле (unique index), как у новой записи, то старая запись удаляется перед добавлением новой.

UPDATE < tablename> SET { | } .,. .< COLUMN name> = < VALUE expresslon> [ WHERE < predlcate> | WHERE CURRENT OF < cursor name> (* только для вложения* ) ] ; UPDATE peers SET zone= "voip" ; # обновить все строки в столбце zone таблицы peers UPDATE stat SET whp= "13x13x13" WHERE id = 1 ; UPDATE countries SET nm_ukr= ( SELECT del_countries. ukrainian FROM del_countries WHERE countries. nm_en= del_countries. english ) ;

WordPress использование, настройка : в таблице wp_posts удалить все вхождения строки

UPDATE wp_posts SET post_content = REPLACE (post_content, "" , "" ) ;

DELETE FROM

[ WHERE | WHERE CURRENT OF (*только для вложения*) ];

DELETE FROM Peers; // удалит все содержимое таблицы Peers. DELETE FROM FinR where day Like "20120415%"; // DELETE FROM prices WHERE ratesheet_id NOT IN (SELECT id FROM ratesheets);

ALTER

    Изменение значения по умолчанию для колонки . Чтобы установить новое значение по умолчанию для колонки, используйте команду вида: ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77 ; OR ALTER TABLE nases ALTER COLUMN zone SET DEFAULT "voip" ;

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

    ALTER TABLE products ALTER COLUMN price DROP DEFAULT ;

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

    Функция как значение по умолчанию для колонки . В этом случае столбец timetracking имеет тип данных timestamp и значит для нее значением по умолчанию можно задать встроенную функцию now() т.е. при добавлении новой строки в столбец будет записана текущая дата и время ALTER TABLE timetracking ALTER COLUMN date_wd SET DEFAULT now();

    Добавление ограничения . Чтобы добавить какое-либо ограничение, используется табличный синтаксис определения этого ограничения. Например: ALTER TABLE products ADD CHECK (name ""); ALTER TABLE products ADD CONSTRAINT some_name UNIQUE (product_no); ALTER TABLE products ADD FOREIGN KEY (product_group_id) REFERENCES product_groups;

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

    ALTER TABLE products ALTER COLUMN product_no SET NOT NULL;

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

Функции агрегирования

В стандартном SQL существует 5 агрегатных функций:

    COUNT - функция возвращает количество строк, которые соответствует определенным критериям.,

    SUM - возвращает сумму (общую) значений в определённом столбце. Строки столбцов со значениями NULL игнорируются функцией SUM.

    AVG - среднее значение в столбце,

Функции агрегирования используются как имена полей в предложении запроса SELECT, но с одним исключением: имена полей применяются как аргументы. Функции SUM и AVG могут работать только с цифровыми полями. Функции COUNT, MAX, MIN работают как с цифровыми так и с символьными полями. При применении к символьным полям функции MAX и MIN могут работают с ASCII эквивалентами символов.

SELECT Count(Books.ID) AS [Количество Книг] FROM Books;

Использование CROUP BY позволяет применять агрегатные функции к группам записей.

SELECT Count(Books.ID) AS [Количество Книг] FROM Books GROUP BY [Писатель];

Представления (VIEW)

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

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

    Команда CREATE VIEW . Представление создается командой CREATE VIEW. Она состоит из слов CREATE VIEW (СОЗДАТЬ ПРЕДСТАВЛЕНИЕ), имени представления которое нужно создать, слова AS (КАК), и далее запроса. Создадим представление Londonstaff: CREATE VIEW Londonstaff AS SELECT * FROM Salespeople WHERE city = "London";

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

    Structured Query Language (Язык Структурированных Запросов) разработан корпораций IBM в начале 1970-х годов. В 1986 году SQL был впервые стандартизирован организаций ANSI .

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

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

    Команды DDL

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

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

    ALTER - используется для добавления в таблицы новых столбцов и изменения определенных столбцов.

    Команды DML

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

    SELECT список_полей1 FROM имя_таблицы ]

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

    Для примера создадим простейший запрос на получение данных из полей "name" и "phone" таблицы "friends":

    SELECT name, phone FROM friends

    Если необходимо получить все поля таблицы, то не обязательно их перечислять, достаточно поставить звездочку (*):

    SELECT * FROM friends

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

    SELECT DISTINCT name FROM friends

    Если необходимо получить отдельную запись, то используется оператор WHERE . Например, нам надо получить из таблицы "friends" номер телефона "Васи Пупкина":

    SELECT * FROM friends WHERE name = "Вася Пупкин"

    или наоборот, нам надо узнать кому принадлежит телефон 44-65-01:

    SELECT * FROM friends WHERE phone = "44-65-01"

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

    * - соответствует строке состоящей из одного или более символов;

    Соответствует одному любому символу;

    Соответствует одному символу из определенного набора;

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

    SELECT * FROM friends WHERE name LIKE "*Вася*"

    Для определения порядка, в котором возвращаются данные используется оператор ORDER BY . Без этого оператора порядок возвращаемых данных невозможно предсказать. Ключевые слова ASC и DESC позволяют определить направление сортировки. ASC - упорядочивает по возрастанию, а DESC - по убыванию.

    Например, запрос на получение списка записей из поля "name" в алфавитном порядке будет выглядеть следующим образом:

    SELECT * FROM friends ORDER BY name

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

    INSERT - данная команда служит для добавления новой записи в таблицу. Записывается она следующим образом:

    INSERT INTO имя_таблицы VALUES (список_значений )

    Обратите внимание, типы значений в списке значений должны соответствовать типам значений полей таблицы, например:

    INSERT INTO friends VALUES ("Анка Пулеметчица" , "32-09-81" )

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

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

    UPDATE имя_таблицы SET имя_поля = значение

    Если опустить оператор WHERE, то будут обновлены данные во всех определенных полях таблицы. Для примера, поменяем номер телефона Васи Пупкуна:

    UPDATE friends SET phone = "55-55-55" WHERE name = "Вася Пупкин"

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

    DELETE FROM имя_таблицы

    Для примера, давайте удалим этого надоедливого Васю Пупкина из нашей таблицы:) :

    DELETE FROM friends WHERE name = "Вася Пупкин"

    The конец

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