РОССИЙСКАЯ ЭКОНОМИЧЕСКАЯ АКАДЕМИЯ им. Г.В. ПЛЕХАНОВА ПРАКТИКУМ ПО ЯЗЫКУ SQL В СРЕДЕ СУБД ACCESS Москва 2006 1 Составитель: канд. техн. наук Н . А . Г е р а с и м о в Практикум по языку SQL в среде СУБД Access / Сост.: Н.А. Герасимов.- М.: Изд-во Рос. экон. акад., 2006 - с Настоящее учебное пособие представляет собой методический материал, который позволяет получить базовые навыки в построении различных запросов на языке SQL (Structured Query Language) к базам данных, построенных на Access. В качестве инструмента реализации SQL запросов предлагается использовать среду СУБД Access. Такой подход позволяет осуществить «плавный» переход от освоения примитивных конструкторов запросов к мощным средствам языка SQL и использовать конструкции, созданные на SQL, в различных приложениях. Пособие ориентировано на студентов экономических специальностей и может служить методическим основанием для создания практических занятий по изучению стандартной версии языка запросов SQL (SQL92). © Российская экономическая академия, 2006 2 Введение Занятие 1. Построение простых запросов на SQL к одной таблице 1.1. Построение запроса в QBE и просмотр его в режиме SQL 1.2. Задание списка имен столбцов и изменение имен столбцов в запросе. 1.3. Построение запросов с комплексными условиям 1.4. Вставка текстовых столбцов. 1.5. Вычисляемые столбцы Занятие 2. Построение запросов со сложными условиями. 2.1. Использование в запросах специальных слов 2.2. Построение запросов на агрегирование 2.3. Включение сортировки строк в запросы 2.4. Построение вычисляемых столбцов с использованием функций Занятие 3. Построение запросов к нескольким таблицам. 3.1. Объединение таблиц в запросах и выполнение операции JOIN (объединение) 3.2. Объединение копий таблиц 3.3.Вложенные запросы Занятие 4. Запросы на ввод и корректировку данных в базе. 4.1. Запросы на ввод данных в таблицы 4.2. Запросы на изменение данных в таблицах 4.3. Запросы на удаление данных из таблиц Занятие 5. Запросы на создание и изменение базы данных. 5.1. Запросы на создание таблиц базы данных 5.2. Запросы на изменение таблиц базы данных 5.3. Запросы на удаление таблиц базы данных Занятие 6. Создание приложений с использованием запросов на языке SQL. 6.1. Приложение в среде VBA 6.2. Разработка локальных Web-приложений (на VBScript). 6.3. Некоторые приемы ASP-технологии. Заключение. 3 Литература. Приложения: Приложение 1. Описание схемы учебной базы данных «Автомобильный салон» (Avto.mdb). Приложение 2. Разработка VBA приложения для обработки SQLзапросов. 4 Введение В настоящий момент можно твердо утверждать, что наиболее распространенный способ организации больших объемов информации основан на методологии реляционных баз данных. В основе концепции реляционных баз данных и языка запросов SQL (Structured Query Language), лежит реляционная алгебра (или алгебра над отношениями), которая является развитием фундаментальных понятий теории множеств, известных нам из базового курса математики «теория множеств»[1]. Определения. Под множеством в математике понимается собрание определенных и различных между собой объектов (или элементов), представляемых как единое целое. Например, мы говорим «множество людей», «множество автомобилей», «множество предметов» и т.п. Изучая множества, математика не интересует ни предметная область, к которой относятся элементы множества, ни физические их свойства. Иначе говоря, множество (A) состоит из элементов (a1, a2, a3,…,aN), которые объединены по некоторым правилам или признакам. Это обстоятельство обычно записывается так: A={ a1, a2, a3,…,aN }. Запись a1 A обозначает, что элемент a1 принадлежит множеству A (противоположное утверждение записывается следующим образом- a1 A). Пустое множество, которое не содержит элементов, обозначается символом . Существует два способа определения конкретного множества: - прямой (или явный) метод, когда перечисляются все элементы, входящие в множество; 5 - неявный (интенсиональный), основанный на использовании некоторой функции PA(ai), которая может принимать одно из двух значений {True,False} («ИСТИНА» или «ЛОЖЬ»). Значение «True» означает, что элемент aiA, «False» - в противном случае (a1 A). Например, пусть PA(ai), определяет A- множество «легковых автомобилей», тогда PA(«Жигули»)=True, а PA(«ЗИЛ-130»)=False. Функция PA(x), определенная над множеством X, называется предикатом и представляет собой двухзначную функцию, принимающую в качестве аргумента значение xi из некоторого множества-универсума X (некоторого более общего множества по отношению к множеству A). Например, пусть X множество всех автомобилей, а A – множество легковых автомобилей, тогда PA(x) есть предикат, определяющий A, принимает значение True только тогда, когда xi является легковым автомобилем. Отношение между множествами X и A можно отобразить схемой, как показано на рис.1. Предикат Множество PA(x) Универсум X A Рис.1. Схема отношений универсума X, множества A и предиката PA(x) Таким образом, в нашем примере предикат PA(x) определяет отношение 6 включения множества A в множества X, которое обозначается как AX. Например множество A – «легковые автомобили» включается в множество X - «все автомобили». Обычно математики не интересуются предметной содержательной стороной реальных объектов, которые составляют множества, а изучают формальные свойства множеств и операции над ними. Из теории множеств известно, что над множествами можно выполнять различные операции, некоторые из которых определены ниже: Объединение множеств: C=AB. Например, пусть A={a,b,c,d} и B={a,c,d,x}, тогда C={a,b,c,d,x}. Заметим, A=A. Пересечение множеств: C=AB. Пусть A и B такие же как и в примере выше, тогда C={a,c,d}. Заметим, A=. Разность: C=A – B. Множество C содержит все элементы, принадлежащие множество A, но не содержатся в B. Пусть A={a,b,c,d,x,y} и B={a,b,x,y,z}, тогда разность C={c,d}. Заметим, что A - =A. Использование этих операций над множествами и функций предикатов позволяет разработать формальные языки (похожие на естественный язык), которые позволяют описать процедуры получения результирующих множеств чисто формальными методами без учета природы объектов, составляющих исходные множества. Часто предикат PA(x) интерпретируется как двухзначная функция P(x) над множеством X={x1, x2, xn}, которая определяет для каждого xi истинность утверждения: «обладает или нет этот элемент некоторым свойством xi». Например, пусть P(x1) определяет, является ли легковой автомобиль красным, тогда выражение P(«Жигули»)=True, обозначает, что конкретный легковой автомобиль марки «Жигули» 7 является красным и его можно отнести к множеству B «красные легковые автомобили» (очевидно, что в данном случае выполняется условие BA). Рассмотрим случай, когда для множества объектов Z («множество автомобилей») задано несколько свойств (или множество свойств X={x1, x2, xn}), каждое из которых задано одним из множеств X1, X2,…,Xn. Например, если Z множество всех автомобилей, и его объекты имеют свойства x1, x2 и «белый»} – множество, X2={1999,2000,2001} – x3 , то X1={«красный», «синий», определяющее множество, цвет определяющее автомобилей, год выпуска, X3={«Мерседес», «Опель», «БМВ»} - множество, определяющее фирму производителя. Тогда, если нам необходимо отобрать все автомобили со свойствами: x1=(«красный»), x2=(2000) и x3=(«Опель»), нам надо построить сложный предикат следующего вида: PA(x)=PZ(x1=(«красный»)) PZ(x2=(2000)) PZ(x3=(«Опель»)). Применив, сконструированный предикат ко всем объектам множества Z, мы получим все автомобили, удовлетворяющие сформулированному в задаче запросу. Формальные языки (в том числе и язык SQL) позволяют строить такие предикаты, не прибегая к программированию, а используя непроцедурные формальные конструкции языка похожие на предложения в обычном естественном языке. Например, выше описанный предикат PA(x) на формализованном языке (близком к естественному) можно представить так: ВЫБЕРИ автомобили, у которых цвет= «Красный» И год= «2000» И фирма= «Опель». 8 В этом выражении слова ВЫБЕРИ и И являются ключевыми словами формального языка запроса, а цвет, год и фирма - именами множеств свойств объектов из универсума «автомобили». В рассмотренном запросе (или предикате PA(x)) свойства принимают конкретные значения. В общем случае функцию предиката можно построить над несколькими переменными PA(x1, x2, xn). Предикаты такого вида определяют множества из элементов вида (x1, x2,…,xn), которые называются кортежами. Например, пусть X- множество всех автомобилей, у которых x1- свойство, определяющее год выпуска, а x2 – фирму изготовителя. Например, построим кортежи: x1=(«красный»,2000, «Опель»), x2 =(«белый»,2001, «БМВ»), или x3 =(«белый»,2001, «Мерседес») и т.п.. Теперь, если мы хотим построить новое множество A, которое содержит легковые автомобили года выпуска 2000 и производства фирмы «Мерседес», то сначала надо построить предикат вида PA(x2, x3 ), который принимает значение True при x2=2000, x3=«Мерседес». Затем сформировать множество X всех кортежей (x2, x3), и после этого, применив, полученный предикат PA(x2, x3) ко всем кортежам множества X, мы получим множество А из объектов (т.е. автомобилей) с интересующими нас свойствами. На формализованном языке запросов данную процедуру можно записать так: ВЫБЕРИ ВСЕ объекты ИЗ множества автомобили, у которых год= «2000» И фирма= «Опель». 9 Таким образом, формулировка и реализация сложных предикатов над кортежами в удобной языковой форме является одной из основных задач, которая решается с помощью теории множеств, а ее результаты используются при создании конструкций формальных языков запросов типа SQL. Следует отметить, что переменные x1, x2, xn, определяющие кортежи, могут определяться из различных универсумов. Множество, которое получается в результате применения многозначного предиката к нескольким универсам, называется отношение. Иными словами, отношение это множество, построенное из кортежей, которые в свою очередь формируются из элементов других множеств («цвет», «год выпуска», универсума «пробег» и т.п.), («автомобили»). описывающие Взаимосвязь свойства понятий исходного «множество» (универсум), «кортежи», многозначный «предикат» и «отношение» показано на Рис.2. Предикат Универсум PA(x1, x2, xn). Отношение A (множество кортежей, удовлетворяющ их предикату) и множества свойств Кортежи (x1, x2, xn) X1 X2 Xn 10 Рис.2. Схема связи основных понятий: универсум, кортежи, предикат и отношение На рис.2 показана схема решения задачи синтеза кортежей из исходных множеств, которые описывают свойства объектов Xi («прямая» задача). Однако, на практике часто возникает «обратная» задача, которая заключается в том, что необходимо выполнить анализ исходных кортежей и провести их декомпозицию, с целью получения оптимальной структуры исходных множеств. Решению этих задач посвящено много теоретических работ, с которыми можно познакомиться в литературе, посвященной вопросам «реляционной алгебры»[]. Базы данных, построенные на отношениях, называются реляционными базами данных. Отношения обозначаются либо как множества R={r1, r2,…,rm }, где ri R не что иное как i-й объект, свойства которого определяется кортежем (x1, x2,…,xn), либо как множество R={(x1, x2,…,xn)i}, где (x1, x2, ,xn)i – i-й кортеж, однозначно определяющий свойства объекта ri R. На практике при создании реляционных баз данных многомерные отношения R={(x1, x2,…,xn)i} обычно представляются в виде двухмерных таблиц R, которые удовлетворяют следующим основным свойствам: - строки таблицы R содержат кортежи (x1, x2,…,xn)i, которые описывают свойства одного объекта ri R. Строка таблицы R называется записью. 11 - столбец – содержит данные, принадлежащие к одному свойству (xi). Столбец называется полем, которое имеет имя и тип данных; - на пересечении записи и поля лежит атрибут, который является атомарным (т.е. «неделимым») и однозначным 1; - порядок записей и полей в таблице R не имеет значения и не влияет на кортежи; - - каждая запись определяется ключом, который однозначно идентифицирует объект. Например, в таблице, которая содержит список студентов, поле с номером зачетной книжки студента является ключом. Ключевое поле обычно выделяется (например, подчеркивается). Ниже приведен пример реляционной таблицы R=(Номер, Марка, Цвет, Год выпуска, Цена), которая содержит описания свойств выставленных на продажу в автосалоне автомобилей : Таблица 1 Пример отношения R=(Номер, Марка, Цвет, Год выпуска, Цена) Номер Марка Цвет Год Цена выпуска 0001 «Мерседес» зеленый 2000 20000 0002 «БМВ» красный 2001 18000 0003 «Опель» красный 2000 9000 Над отношениями R справедливы все те операции, которые применимы над множествами. Некоторые операции, которые описаны выше: объединение, пересечение, вычитание, здесь интерпретируются следующим образом. 1 Замечание: в некоторых учебниках по реляционной алгебре по атрибутом, понимается поле. Множество значений атрибута образуют домен. Значение – это элемент домена (т.е. однозначно). Существуют также концепции использующие понятие многозначного атрибута (например, Pick systems). 12 Под операцией «объединение» двух отношений R1 и R2, понимается выборка всех записей, которые либо содержатся в одном из двух отношений, либо являются общими для двух отношений (в языке SQL соответствует операции UNION). Под операцией «пересечение» двух отношений R1 и R2, понимается выборка всех строк, которые являются общими для двух отношений (в языке SQL соответствует операции INTERSECT). Под операцией «разность» двух отношений R1 и R2, понимается выборка строк, которые содержатся только в одном из двух отношений (в R1) (в языке SQL соответствует операции EXPECT).. Особую роль в реляционной теории играют специальные операции над отношениями, которые заложены в основу языка запросов SQL: - «проекция», которая определяет подмножество полей из заданного отношения (или набора отношений). Иначе эту операцию называют «вертикальной выборкой». Пример, рассмотрим в качестве исходного отношения R=(Номер, Марка, Цвет, Год выпуска, Цена). На базе исходного отношения построим его проекцию R1, которая является новым отношением R1=(Год выпуска, Марка). Проекция R1 в табличной форме будет иметь вид: Пример проекции отношения R в виде R1=(Год выпуска, Марка). Таблица 2 Проекция R1 на отношением R Год выпуска Марка 2000 «Мерседес» 2001 «БМВ» 2000 «Опель» Таблица 2 нового отношения 13 Построение проекции R1 над отношением R соответствует фразе на языке SQL: SELECT [Год выпуска],[ Марка] FROM R. - селекция (или ограничение), - это операция выбора строк, удовлетворяющих определенным условиям (иначе эту операцию называют «горизонтальной выборкой»). Например, выберем из исходного отношения R (см. описание выше), автомобили красного цвета. Это соответствует фразе на языке SQL: SELECT * FROM R WHERE [Цвет]=«красный». В результате получается новое отношение R2, которое показано в таблице 3 ниже: Таблица 3 Пример селекции отношения R и получение нового отношения R2=(Номер, Марка,[Цвет]= «красный», Год выпуска, Цена.). Номер Марка Цвет Год выпуска Цена 0002 «БМВ» красный 2001 18000 0003 «Опель» красный 2000 9000 Оператор WHERE выполняет функцию предиката P(xi=a), фильтрующего нужные строки из исходного отношения R. - естественное соединение – выполняет объединения отношений. Здесь выбираются только операцию те кортежи, у которых в указанном поле есть совпадения. Например, есть два отношение R1=([Имя],[Отдел]) и R2=([Отдел],[Название]), и требуется построить новое отношение R3=([Имя],[Отдел],[Название]). В табличном виде решение этой задачи показано на рис.3. ниже. На языке SQL эта операция выглядит так: SELECT R1.[Имя], R1.[Отдел],R2[Название] FROM R1, R2 WHERE R1.[Отдел]= R2.[Отдел]. Иллюстрация процесса выполнения операции соединения показана на рис.3. ниже. 14 - произведение – результат соединения двух отношений, каждая запись одного отношения соединяется с записью второго отношения ( аналогично операции соединении без условия). На языке SQL эта операция выглядит так: SELECT R1.[Имя], R1.[Отдел], R2[Название] FROM R1, R2. Исходные отношения R1 и R2 Отношение R1 Иванов 10 Петров 10 Сидоров 20 Отношение R2 Операция Соединение 10 Бухгалтерия 20 Отдел кадров Отношение R3 Соединение R3= R1 R2 Иванов 10 Бухгалтерия Петров 10 Бухгалтерия Сидоров 20 Отдел кадров Рис.3. Пример выполнения операции «соединения» (R3= R1 R2) В случае примера отношений R1 и R2, которые рассмотрены выше, результатом операции произведение будет новое отношение R3, строки которого показаны в таблице 3. Таблица 3 Пример произведения отношений R1 и R2 и получение нового отношения R3= R1хR2 . Имя Иванов Отдел 10 Наименование Бухгалтерия 15 Петров Сидоров Иванов Петров Сидоров Бухгалтерия Бухгалтерия Отдел кадров Отдел кадров Отдел кадров 10 20 10 10 20 Кроме обоснования структуры предложений формального языка запросов SQL, реляционная алгебра играет большую роль в описании методологии синтеза новых отношений и декомпозиции исходных отношений, полученных в результате анализа реальной объектной среды. Применение формальной реляционной теории помогает в построении оптимальной структуры базовых отношений, составляющих основу для проектирования реляционной базы. Решение этой задачи сводится к нахождению рациональной процедуры построения нормализованных отношений (или как принято говорить «нормальных форм»), т.е. таких отношений, которые удовлетворяют определенным требованиям полноты, целостности, отсутствия избыточности, непротиворечивости и т.п. Однако эти вопросы выходят за рамки данной методической работы и здесь не рассматриваются. В предлагаемых примерах используются базы данных, построенные на уже нормализованных отношениях. Для построения реляционных баз данных используются специальные программные комплексы, которые называются СУБД (системы управления базами данных). Известно много СУБД различных фирм производителей программного обеспечения: Informix (IBM), FireBird (Borland), SQL Server 2000 (MicroSoft), Oracle (Oracle), MySql и т.п. Одной из популярных СУБД для создания небольших офисных приложений является СУБД Access (продукт компании MicroSoft). 16 Процесс создания реляционной базы данных с использованием СУБД MicroSoft в упрощенном виде можно описать следующей последовательностью процедур: - проектирование логической схемы базы данных (определения состава таблиц (базовых отношений), описание полей, выбор ключей и связей между таблицами); - создание базы данных в среде СУБД; - создание описаний таблиц (описание столбцов, назначение ключей, присвоение имени таблице); - создание схемы базы данных ; - ввод данных в таблицы; - подготовка и выполнение запросов; - разработка диалоговых форм для работы с базой данных; - подготовка и выполнение отчетов, подключение отчетов к диалоговым формам. Для выполнения упражнений на занятиях необходимо создать в СУБД Access автомобильном учебную салоне) базу по данных описанию, AVTO которое (учет заказов в представлено в Приложении 1. Эта база данных состоит из четырех таблиц: Salespeople(snum, sname, saddress, comm., stel, semail) – список продавцов автомобилей; Customers (cnum, cname, caddress, rating., ctel, cemail)- список покупателей (клиентов) автомобилей; Price(pnun, pname, peddim, price, pdate) – прайс-лист, продаваемых автомобилей; Orders (onum, odate, amount, snum, cnum, pnun) – журнал учета продаж автомобилей. 17 База данных используется AVTO для выполнения ежемесячных расчетов, определения доходов и расходов по автосалону в различных разрезах. Например, владельца салона интересует, кто из продавцов продал автомобилей больше чем другие, или кто из покупателей купил самый дорогой автомобиль, какие марки автомобилей за отчетный период пользовались большим спросом, какова общая сумма проданных автомобилей и т.д. Для получения ответов на эти и другие вопрос необходимо иметь возможность без утомительного программирования формулировать запросы к базе данных на языке, который похож на естественный язык. Иначе говоря, запросы к базе данных должны записываться на непроцедурном языке, с помощью которого пользователь формулирует «что он хочет получить» от базы данных, а компьютер сам реализует этот запрос в программу поиска нужной информации и представляет пользователю результаты запроса в удобной для анализа форме. Для большинства реляционных СУБД таким языком является язык структурированных запросов SQL, который был разработан в середине 70 годов прошлого столетия фирмой IBM. Затем в 1979 году фирма Oracle разработала коммерческую версию этого языка, который широко внедряла в различных приложениях. Благодаря своим достоинствам язык SQL стал общепринятым языком для реляционных баз данных. В 1986 году Американский институт стандартов (ANSI – American Nation Standard Institute) присвоил языку SQL статус национального стандарта для реляционных СУБД. Позже этот статус был подтвержден Международной организацией стандартов (ISO – International Standard Organization). В 18 настоящее время практически все разработчики реляционных СУБД придерживаются стандарта SQL ANSI. SQL (Structured Query Language) DQL DML DDL DML (Data Query Language) (Data Manipulation Language) (Data Definition Language) (Data Control Language) Команды: Select From Where Group By Order By Команды: Insert Update Delete Команды: Create Alter Drop Команды: Grant Revoke Рис.4. Схема группировки команд языка SQL Особенности языка SQL следующие: SQL похож на естественный английский язык, что позволяет пользователям легко формулировать свои запросы без программирования; SQL- это непроцедурный язык, используя который пользователь формулирует какая информация ему нужна, и не определяет алгоритма ее поиска; SQL включает достаточно широкий набор команд (и других ключевых слов), которые позволяют решать множество различных прикладных задач: - извлечения данных (DQL- Data Query Language); - вставка, изменение или удаление строк и столбцов DML -Data Manipulation Language) таблицы; 19 - создание, модификация и уничтожение объектов базы данных (DDL - Data Definition Language) ; - обеспечение целостности базы данных и доступа к данным (DML - Data Control Language) Обычно команды языка SQL группируют по функциям как показано на рис. 4. Очень широко конструкции языка SQL используются в приложениях, которые создаются при помощи языков современных программирования (например, Появляются специальные VBA, VB, инструментарии, С++ Delphi, с помощью и т.п.). которых конструируются диалоговые приложения на базе реляционных систем и языка SQL. В последние годы все больше полезных и эффективных экономических приложений разрабатывается самими пользователями, без привлечения специалистов в области программирования. Поэтому курс по изучению основ языка SQL входит в состав базовых курсов информатики для студентов экономических направлений. Настоящее пособие представляет собой методический материал, который позволяет получить базовые навыки в построении различных запросов к базам данных, построенных на Access. Учитывая то, что освоение СУБД Access включено в обязательную программу многих экономических ВУЗов, предлагается использовать в качестве инструмента реализации запросов среду Access. Такой подход позволяет осуществить «плавный» переход от освоения примитивных конструкторов запросов, которые несомненно являются эффективным средством построения запросов для начинающих пользователей, к мощным средствам языка SQL и использовать конструкции, созданные на SQL в различных приложениях. 20 Занятие 1. Построение простых запросов на SQL к одной таблице Тема занятия: Построение запросов в Access (QBE и SQL),изменение списка имен столбцов в запросе, вставка текстовых столбцов 1.1. Построение запроса в QBE и просмотр его в режиме SQL Важным приемом предлагаемой методики изучения конструкций языка SQL является одновременное использование конструктора запросов (QBE - Query By Example) запроса и редактора SQL запроса. Такая удобная возможность имеется в СУБД Access. Суть приема заключается в том, сто сначала пользователь создает запрос в QBE, а затем просматривает и модифицирует его в редакторе запросов SQL. Иногда целесообразна обратная операция. Пользователь пишет запрос в SQL-редакторе, а затем переходит в QBE, где добавляет условия запроса, используя удобный механизм «перетаскивания мышью» (drag-and-drop). Таким образом, пользователь быстро привыкает к конструкциям языка SQL. Для выполнения заданий откроем базу данных Avto.mdb2, в которой будем строить учебные запросы на языке SQL. Начнем с построения простого запроса, который отображает все строки и все столбцы одной таблицы Salespeople (Продавцы). В СУБД Access для построения запросов к базе данных существует простой и удобный инструмент – конструктор (или мастер) построения запросов, называемый QBE, использование которого заключается в следующем: - надо войти в закладку (команду) ЗАПРОСЫ; 21 - выбрать режим «Создать» запрос с помощью «Конструктора запросов» (на экране появится макет запроса как показано на рис.1 ниже); - на верхнем поле конструктора надо разместить таблицу Salespeople (для этого можно использовать кнопку ДОБАВИТЬ); - затем для создания нашего запроса надо из макета таблицы Salespeople мышкой перетащить «звездочку» (*) в макет запроса (в первый столбец первой строки (Поле:) ). После правильного выполнения этих процедур получается макет запроса, как показано на рис.5. Поле для размещения макетов таблиц Поле для макета запроса Рис.5. Макет простого запроса к таблице Salespeople, построенный в конструкторе на QBE. 2 Учебную базу Avto.mdb данных можно создать по описанию, которое находится в в приложении 2. 22 Для выполнения запроса нажмите пиктограмму [!], которая находится в центре строки пиктограмм. В результате выполнения запроса, получится таблица, которая отображает все строки и все столбцы таблицы Salespeople (см. рис.6.). Рис.6. Результат выполнения запроса, сконструированного на QBE (запрос см. рис.5). Замечательная особенность конструктора QBE в Access состоит в том, что параллельно с табличной формой конструирования запроса создается и SQL- выражение, которое можно просмотреть и отредактировать с помощью специального режима «SQL». Теперь перейдем в режим SQL, для чего выполним следующее: ВидSQL, и получим отображение созданного запроса на языке SQL, который будет иметь вид как показано на рис.3. Внимательно рассмотрим его и убедимся, что его структура полностью соответствует синтаксису команды SELECT в языке SQL, которая в общем виде может представлена следующей структурой: SELECT <список столбцов> FROM <таблица> [WHERE <условия отбора>] 23 [ORDER BY <условия сортировки>] [GROUP BY <условия группировки>]; где SELECT, FROM, WHERE, ORDER BY, GROUP BY ключевые слова языка SQL, [ ] – обозначает необязательное присутствие термов (или ключевых слов языка SQL), <список столбцов> - задает список выводимых столбцов, разделенных запятой ( в нашем случае выбраны все столбцы, что обозначено специальным символом «звездочка» ), <таблица> - задает имя таблицы (или нескольких объединенных таблиц), из которой происходит выбор строк ( в нашем случае таблица Salespeople). В запросе, созданным с помощью QBE представлены только ключевые слова SELECT и FROM. Другие ключевые слова (WHERE, ORDER BY и т.п.) в запросе отсутствуют, поэтому в данном случае запрос имеет вид как показано на рис.7. Этот запрос выводит все строки и все таблиц таблицы Salespeople аналогично запросу, созданному на QBE выше (результат работы запроса см. рис. 6). Рис.7. Пример сконструированного запроса на языке SQL 24 Используя встроенный текстовый редактор, отредактируем полученный запрос (см. рис. 7) до вида как показано на рис 8. и еще раз запустим запрос на исполнение с помощью пиктограммы <!>. Убедимся, что результат выполнения запроса не изменился. Таким образом, мы можем не только, просматривать запросы в режиме SQL (что само по себе весьма удобно и поучительно), но и самостоятельно конструировать требуемые запросы на языке SQL, а затем выполнять их в среде СУБД Access. Рис. 8. Вид отредактированного запроса в режиме редактора запросов на языке SQL в СУБД Access. Чтобы убедиться в правильности нашего утверждения, добавим в запрос (см. рис.8) условие на отбор строк из таблицы Salespeople. Предположим, что нам надо получить список продавцов, которые живут в городе Москве (т.е. отобрать все записи, которые удовлетворяют условию: WHERE saddress = “Москва”). И так, наш запрос на SQL будет выглядеть так: SELECT * FROM Salespeople FROM WHERE saddress = “Москва”. Используя пиктограмму <!>, запустим созданный запрос на исполнение и получим следующую таблицу, которая отображена на 25 рис.9 ниже. Как и следовало ожидать, отобраны только 3-и строки, которые удовлетворяют заданному условию: продавцы живут в городе Москва. Рис.9. Пример простого запроса с условием. Замечание: При формировании условия значения текстовых столбцов должны выделяться в кавычки (двойные или одинарные), столбцы дат – в «решетки» (#), числовые данные не требуют выделения. Теперь вернемся в режим представления запроса в форме QBE (режим Конструктор). Для этого выполним Вид Конструктор, на экране получим форму запроса как показано на рис.10. Задание условия saddress=”Москва” Рис.10. Запрос с условием в режиме конструктора. Запрос, созданный в QBE, в режиме SQL будет выглядеть так (напомним, что для перехода в режим SQL выполни ВидSQL): 26 SELECT Salespeople.* FROM Salespeople WHERE (((Salespeople.saddress)="Москва")); Замечание: Язык SQL не чувствителен к регистру, на котором пишутся ключевые слова (например, SELECT и select будут восприниматься одинаково). Однако рекомендуется выделять ключевые слова, используя регистр заглавных букв. Конструктор при построении запросов расставляет много «лишних» круглых скобок, которые можно удалить при редактировании. Например, выше приведенный запрос, который создан конструктором, можно отредактировать, упростить и представить его так: SELECT * FROM Salespeople WHERE saddress ="Москва"; Таким образом, построенные в SQL-редакторе запросы удобно просматривать в QBE, где запрос можно проверить, изменить и корректность, а затем снова вернуться в режим SQL и редактировать запрос в режиме текстового редактора. Такой способ может стать основой быстрого проектирования SQL-запросов (элемент «экспресс» технологии построения приложений). Запросы, созданные с помощью «экспресс» технологии, затем могут использоваться в различных программных приложениях (например, в VBA или в Web- приложениях). 1.2. Задание списка имен столбцов и изменение имен столбцов в запросе. 27 При формировании запросов можно указывать список выводимых столбцов (операция проекция) и накладывать ограничения на выбранные строки, путем формирования комплексных условий отбора записей. Пример запроса на проекцию столбцов: построить запрос, который отображает заданный набор столбцов (snum, sname, semail) таблицы Salespeople: SELECT snum, sname, semail FROM Salespeople; Результат выполнения запроса показан ниже на рис.11. Рис.11. Результат выполнения запроса (операция проекция). Не редко необходимо переименовать столбцы в запросе, для этого к имени каждого столбца добавляется синоним, используя ключевое слово AS. Например, столбец snum надо переименовать как «Номер», тогда надо записать: snum AS Номер. Если синоним состоит из нескольких слов, его надо выделить «квадратными скобками». Исходный SQL запрос, сконструированный выше, можно записать следующим образом: SELECT snum AS Номер, sname AS Фамилия , semail AS Почта FROM Salespeople; Результат выполнения запроса показан ниже на рис.12. 28 Рис. 12. Результат выполнения запроса с переименованием столбцов. Таким образом, порядок выбранных столбцов и наименования, которые будут выводиться в результате выполнения запроса, определяются ключевыми словами SELECT и AS. Замечание. Использование синонимов столбцов (с помощью ключевого слово AS), позволяет разработчикам баз данных не использовать кириллицу в именах столбцов на этапе физического проектирования базы данных. 1.3. Построение запросов с комплексными условиям В языке SQL условия отбора записей из таблицы задаются ключевым словом WHERE. Условие может быть «простое» или «комплексное». Комплексное условие состоит из нескольких простых, объединенных логическими операторами. При формировании условий используются следующих основные правила: Правило 1. Для формирования простого условия можно использовать набор операторов, который показан в таблице4 ниже: Таблица 4 Операторы, применяемые в построении комплексных запросов Равно = Больше > 29 >= < <= <> Больше или равно Меньше Меньше или равно Не равно Пример запроса с простым условием: отобрать все товары (т.е. строки из таблицы price), которые имеют цену больше или равную (>=) 3000. SELECT pnun AS номер , pname AS наименование, price AS цена FROM price WHERE price>=3000; Результат выполнения этого запроса показан на рис. 13. Рис. 13.Результат выполнения запроса с условием (price>=3000). Правило 2. Для логического соединения простых условий и создания сложного условия используются логические операторы : Таблица 4. Логические операторы, применяемые для построения комплексных условий. Логическое «ИЛИ» OR Логическое «И» AND Не равно (логическое отрицание) NOT Дополним условие предыдущего запроса дополнительным ограничением по дате регистрации продукта в прайсе (например, pdate>#12/14/2005#;). 30 Иначе говоря, надо отобрать все строки с товарами, которые имеют цену больше или равную (>=) 3000 и зарегистрированы позднее (>) 12/14/2005. (дата в условиях выделяется символом «решетка» - #...#) На языке SQL запрос выглядит следующим образом: SELECT price.pnun AS номер, price.pname AS наименование, price.price AS цена, price.pdate FROM price WHERE price>=3000 AND pdate>#12/14/2005#; Результат запроса со сложным условием представлен на Рис. 14 ниже. Рис.14. Выполнение запроса с условием (price>=3000 AND pdate>#12/14/2005#) Рассмотрите этот запрос в режиме QBE (см. рис.15 ниже). В конструкторе запросов можно заменить, что условие AND формируется соседними столбцами. Оно указывает, что отбираются записи, которые удовлетворяют и первому и второму условиям одновременно (логическое «И»). 31 Логическое условие AND ( «И») Рис. 15. Запрос в формате QBE со сложным условием (price>=3000 AND pdate>#12/14/2005#) Сформулируем запрос комплексным условием, который использует логическую связку «ИЛИ» (OR). Например, надо отобрать все строки из прайса для автомобилей «Волга» и «Ауди» (т.е. условие WHERE pname="Волга" OR pname ="Ауди") (см. рис.16) Запрос с комплексным условием на языке SQL запишется так: SELECT pnum AS номер, pname AS наименование, price AS цена FROM Price WHERE pname="Волга" OR pname ="Ауди" ; Замечание: Логический оператор «ИЛИ» соответствует обычному (бытовому) пониманию союза «И» (т.е. можно интерпретировать этот логический оператор так: подходит «и тот и другой» объект). 32 В режиме QBE запрос со связкой «ИЛИ» выглядит так, как показано на рис.16 ниже. Условия располагаются в одном столбце и связываются союзом «ИЛИ». Логическое условие OR («ИЛИ») Рис.16. Построение запроса со сложным условием (pname="Волга" OR pname ="Ауди") Результат выполнения запроса с логическим условием «ИЛИ» (pname="Волга" OR pname ="Ауди") показан на рис. 17. Отобраны только две строки, в которых наименования автомобилей удовлетворяют заданным условиям (автомобили "Волга" или "Ауди"). Рис.17. Пример запроса с комплексным условием «ИЛИ» (pname="Волга" OR pname ="Ауди") 33 Правило 3. Когда много простых условий связано большим числом логических операторов (ЛО), порядком проверки условий, можно управлять расстановкой круглых скобок. Сначала проверяется условие, которое находится внутри самых «глубоких» скобок. Пример: Пусть задано комплексное условие вида: ((<условие C >ЛО2(<условие A>ЛО1<условие B>))ЛО3<условие D> ), в котором используются 4-ре простых условия A, B, C и D, соединенные тремя логическими операторами ЛО1, ЛО2 и ЛО3. Последовательность исчисления логического предиката будет следующая: Сначала вычисляется <условие A> и <условие B> и выполняется логическая связка ЛО1; Затем вычисляется <условие C> и выполняется ЛО2; В заключении вычисляется <условие D> ) и выполняется ЛО3. Рассмотрим запрос с вложенной структурой условий. Например, надо отобрать строки из таблицы Price, удовлетворяющие следующим нескольким условиям (простые условия соединяются с помощью AND): Цена SELECT pnum AS Номер, pname AS Наименование, price AS FROM price WHERE (( pnum ='3001' OR pnum ='3003') AND ( pdate <=#12/16/2005#) AND ( pdate >=#12/14/2005#) AND ( price >3000)); Такой запрос сначала обработает условие OR, а затем условия AND. 1.4. Вставка текстовых столбцов. В запросы можно вставлять текстовые столбцы, которые облегчают понимание результатов. 34 Например, в запросе ниже вставлено два текстовых столбца: «Наименование» и «цена». Этот текст будет повторяться в каждой строке результирующей таблицы. Пример SQL запроса с текстовыми столбцами: SELECT pnum AS НОМЕР, 'Наименование' , pname AS НАЗВАНИЕ, 'Цена' , price AS ЦЕНА FROM Price WHERE pnum ='3003' ; Результат запроса показан на рис. 18. Рис. 18. Пример запроса со вставленными текстовыми столбцами 1.5. Вычисляемые столбцы Следуя принципу минимизации хранимой информации, обычно в реляционных таблицах не хранятся столбцы, значения которых можно получить на основании данных из других столбцов (т.е. вычислить). Например, надо вычислить стоимость товара с НДС (налог на добавленную стоимость), который равен 20% от цены. Иначе говоря [СТОИМОСТЬ С НДС]=ЦЕНА*1.2.. Ниже приведен пример запроса на SQL с вычисляемым столбцом: SELECT pnum AS НОМЕР, pname AS НАЗВАНИЕ, , price*1.2 AS [СТОИМОСТЬ С НДС] FROM Price 35 Таким образом, имена столбцов в вычисляемых столбцах могут выступать как арифметические переменные действия над которыми (сложение, можно вычитание, выполнять умножение и столбцов со деления), а также применять различные функции. Числовые функции и функции обработки строковыми типами данных рассмотрен далее на занятии 2. Задания для самостоятельной работы. 1. Запишите запрос на языке SQL. Вывести все столбцы из таблицы Customers, для тех покупателей, которые не живут в городе Москва и имеют рейтинг меньше 300. 2. Написать запрос, который выведет все продажи автомобилей в интервале дат с 01.01.2006 по 02.01.2006. 3. Упростите и проинтерпретируете запрос: SELECT orders.onum, * FROM orders WHERE ((((orders.odate = #1/1/2006# )OR (orders.odate =#1/2/2006# ))) AND (orders.onum="4001")); 4. Приведите пример запроса с измененными названиями столбцов и с вставленными текстовыми столбцами. 5. Напишите запрос с вычисляемыми столбцами и с использованием функций 6. Самостоятельно выполнить запросы: Содержание запроса Выбрать все строки и столбцы из таблицы Продавцы 36 Запрос на SQL SELECT * FROM Salespeople; Выбрать все строки и показать стлбцы: snum, sname и semail из таблицы Продавцы Из таблицы Price выбрать строки, с автомобилями "Волга" и "Ауди". Выбрать продавцов. Которые не живут в городе "Москва" и райтинг которых больше 120 Выбрать заказы в период с 1/1/2006 по 1/2/2006 и номером "4001" Выбрать строки из таблицы Цены, которые удовлетворяют сложному условию:номер "3001" или "3003", дата в интервале с 12/16/2005 по12/14/2005 и цена больше 3000 SELECT snum AS Номер, sname AS Фамилия, semail AS Почта FROM Salespeople; SELECT pnum AS номер, pname AS наименование, price AS цена FROM price WHERE pname="Волга" Or pname="Ауди"; SELECT * FROM customers WHERE caddress<>"Москва" And rating>120; SELECT onum AS Номер FROM orders WHERE ((((odate=#1/1/2006#) Or (odate=#1/2/2006#))) And (onum="4001")); SELECT pnum, pname, price FROM price WHERE ((pnum='3001' Or pnum='3003') And (pdate<=#12/16/2005# And pdate>=#12/14/2005#) And (price>3000)); 37 Занятие 2. Построение запросов со сложными условиями. Тема занятия 2: использование в запросах специальных слов, построение запросов на агрегирование, сортировка в запросах. Для демонстрации примеров SQL-запросов будем использовать учебную базу данных Avto.mdb, описание которой дано в приложении 1. 2.1. Использование в запросах специальных слов При построении сложных условий в запросах на языке SQL можно использовать специальные ключевые слова (операторы): IN, BETWEEN, LIKE и IS NULL. IN - определяет множество, которому данное значение может принадлежать или нет. Оператор IN обычно задает список значений. Например, необходимо найти всех продавцов, которые живут либо в «Москве», либо ( «ИЛИ») в «Туле». Этот запрос можно записать, используя логический оператор OR, как показано ниже SELECT * FROM Salespeople WHERE saddress="Москва" OR saddress="Тула"; SQL-запрос со специальным словом IN в этом случае будет выглядеть так: SELECT * FROM Salespeople WHERE saddress IN ("Москва" , "Тула"); . Результат запроса показан на рис. 19. ниже, (отобраны строки с продавцами, которые живут либо по адресу "Москва", либо по адресу "Тула"). Аналогично устроен оператор BETWEEN , который определяет границы параметров. Если мы хотим отобрать всех продавцов, комиссионные которых больше (или равно) 0.10 и меньше (или равно) 0.15. Этот запрос можно записать двумя способами: SELECT * FROM Salespeople WHERE comm >= 0.12 AND comm <= 0.15; 38 или SELECT * FROM Salespeople WHERE comm. BETWEEN 0.10 AND 0.12; Результат выполнения запроса показан на рис. 20. Рис. 19. Результат запроса с ключевым словом IN. Рис. 20. Результат запроса с ключевым словом BETWEEN. Замечание: оператор BETWEEN включат границы интервала. Оператор LIKE применим только к полям типа CHAR или VARCHAR так как он выполняет функцию поиска строк со значением заданного поля, удовлетворяющего подстроке заданного маской. Маска формируется с учетом функций специальных символов, наборы которых отличаются в разных реализациях СУБД. В СУБД Access приняты следующие спецсимволы для формирования маски поиска: * (символ «звездочка»)- заменяет цепочку символов ( или это значит, что значения символов в данной позиции роли 39 не играет, например, “М*” - означает все, начинающиеся с буквы М); ? (символ «знак вопроса») – заменяет любой символ (например, по маске “М?к” – отберуться строки со словами Мак, Мик, Мук и т.п.). Рассмотрим примеры SQL-запросов с оператором применительно к базе данных автосалона (Avto.mdb): LIKE() Например, построим запрос: найти всех покупателей, фамилия которых начинается на букву «С». Маска для выборки строк ("С*"). На языке SQL этот запрос можно записать так: SELECT * FROM Customers WHERE cname LIKE("С*"); Результат запроса представлен на рис.21. Рис. 21. Результат запроса с оператором LIKE("С*") Использование оператора IS NULL позволяет выбрать все строки, в которых значения принимают значение NULL (т.е. нет значения). Например, выбрать всех покупателей, у которых нет номеров телефонов: SELECT * FROM Customers WHERE ctel IS NULL; Результат выполнения запроса показан на рис.22. ниже. 40 Рис. 22. Результат запроса с оператором IS NULL Таким образом, применение специальных ключевых слов IN, BETWEEN, LIKE IS NULL упрощает запись SQL-запроса и делает его лучше читаемым. 2.2. Построение запросов на агрегирование Использование баз данных на практике ориентировано, прежде всего, на получение итоговых аналитических и справочных отчетов, которые получаются в результате выполнения специальных SQLзапросов. В языке SQL для получения итоговых значений по столбцам (агрегирование данных по столбцам) применяются специальные функции агрегирования: Таблица 2. Функции агрегирования, применяемые в SQL-запросах Название Описание функции агрегирования функции Подсчитывает количество строк COUN Суммирует значение по столбцу SUM Рассчитывает среднее значение по AVG столбцу Определяет максимальное значение по MAX столбцу Определяет минимальное значение по MIN столбцу Рассмотрим примеры запросов, использующих функции агрегирования. Например, надо подсчитать количество зарегистрированных заказов в журнале Orders: SELECT COUNT(*) FROM orders; 41 Результат по запросу, содержащий функцию COUNT() показан на рис. 24 ниже Рис. 24. Результат запроса с функцией агрегирования COUNT(). Запрос найти сумму всех выполненных заказов: SELECT SUM(amount) AS Сумма FROM Orders; Рис. 2.6. Результат запроса с функцией агрегирования SUM(). Аналогично можно построить запросы и с другими функциями агрегирования MIN(), MAX и т.д. Например: SELECT MAX(amount) AS Сумма FROM Orders; Замечание: Столбец по которому идет группировка, должен обязательно присутствовать в списке столбцов оператора SELECT. Функции агрегирования можно использовать в запросах совместно с ключевым словом GROUP BY, что позволяет проводить агрегирования по сгруппированным строкам. Например, надо найти сумму всех заказов на каждый день (т.е. сгруппировать заказы по датам и просуммировать данные по каждому дню): 42 SELECT SUM(amount) AS Сумма, odate AS Дата FROM Orders GROUP BY odate; Результат запроса показан на рис.25 ниже. Рис. 25. Результат запроса с функцией агрегирования SUM() и ключевым словом GROUP BY . Для формирования условий над столбцами, которые используются в функции агрегирования, нельзя использовать ключевое слово WHERE, для этого в языке SQL применяется специальный оператор HAVING. Например, надо найти сумму покупок на каждый день, причем интересны только те дни, в которых сумма превышает 10000: SELECT SUM(amount) AS Сумма, odate AS Дата FROM Orders GROUP BY odate HAVING SUM(amount) >10000; В этом запросе столбец amount используется в функции агрегирования SUM(amount), поэтому для формирования условия отбора строк надо применить ключевое слово HAVING. Результат запроса показан на рис.26 ниже. Отобраны только две строки. Рис. 26. Результат запроса с функцией агрегирования SUM() и ключевыми словами GROUP BY и HAVING . 43 Условия над столбцами, которые не входят в группировку формируются с ключевым словом WHERE. Например, если надо найти минимальный заказ на конкретный день, то запрос на SQL запишется так: SELECT snum, MIN(amount) FROM Orders WHERE odate= #01/03/2006# GROUP BY snum; Здесь столбец odate не охвачен функцией агрегирования. Поэтому к нему можно применить ключевое слово WHERE. 2.3. Включение сортировки строк в запросы Для указания необходимости упорядочения строк в запросах используется ключевое слово ORDER BY. Предположим, что надо получить список продавцов в алфавитном порядке: SELECT sname AS Фамилия FROM Salespeople ORDER BY sname; Результат запроса с сортировкой показан на рис. 27. Рис. 27. Запрос с ключевым словом ORDER BY Ключевое слово ORDER BY может использовать указатель направления сортировки: ASC (по возрастанию) или DESC (по убыванию). По умолчании принята возрастающая последовательность сортировки (т.е. ASC). Допускается сортировка по нескольким столбцам («каскадная» сортировка). Например, как в запросе ниже: 44 SELECT odate AS Дата, amount AS Сумма, onum AS [Номер заказа] FROM orders ORDER BY odate, amount; Замечание: При указании порядка столбцов, по которым необходимо провести сортировку, допускается использование вместо имен столбцов применять их номера следования в списке (после SELECT). Аналогичный выше представленному запросу можно записать следующий запрос: SELECT odate AS Дата, amount AS Сумма, onum AS [Номер заказа] FROM Orders ORDER BY 1 ASC, 2 ASC; Результат запроса «каскадной» сортировкой показан на рис. 28 ниже. Рис. 28. Запрос с ключевым словом ORDER BY 2.4. Построение вычисляемых столбцов с использованием функций Согласно реляционной концепции построения баз данных, в таблицах не содержатся столбцы, значения в которых могут быть получены на основании данных из других столбцов(т.е. вычисляемые столбцы). Вычисляемые столбцы в языке SQL реализуются с использованием известных знаков операций (+ - сложение, - вычитание, * - умножение и / - деление), скобок и различных встроенных функций. Функции делятся на: математические для работы с числовыми данными, строковые для работы со строковыми столбцами, функции для работы с датой и временем и прочие функции. 45 Примеры математических функций, которые используются в стандартном SQL в таблице 2 ниже. Таблица 2.2 Некоторые функции, используемые в SQL Функция SIN() COS() LOG() ROUND(X,Y) SQR() SIGN() ABS() Описание операции Вычисление синуса Вычисление косинуса Вычисление логарифма Округление X до Y знаков после запятой Вычисление квадрата Вычисление знака Вычисление абсолютного значения. Замечание: Более полный состав математических функций можно найти в описании конкретной версии языка SQL (например, в SQL Oracle состав функций и их синтаксис может отличаться от стандартных и от функций в Access) В версии языка SQL СУБД Access имена математических функции похожи на имена функция языка VB, что значительно облегчает их запоминание для тех кто знает этот язык программирования. Пример запроса на вычисления приведен ниже: SELECT ROUND(amount,2) AS ОКРУГЛ, SIN(amount) AS СИНУС, LOG(amount) AS LOG, ABS(amount) AS АБСОЛЮТ, ROUND(SQR(amount),2) AS КВАДРАТ, (amount)/10+ ((amount)/20)*1.234 AS Выражение FROM Orders; Результат запроса показан на рис. 29. 46 Рис. 29. Пример результата запроса с вычисляемыми столбцами Особый интерес представляют функции для работы со строковыми переменными. Они позволяют строить комбинированные фразы из строковых столбцов. Например, если есть столбец с именем и фамилией, то можно сконструировать новый столбец который будет содержать только инициалы. Примеры некоторых строковых функций языка SQL приведены в табл. 7. Таблица 7 Некоторые функции для работы со строковыми переменными в SQL Функция Описание операции Символ конкатенации & (объединения) строк Вычисление длинны строки ss LENGTH(ss) Взять n левых символов в LEFT(ss, n) строке ss Вычислить ASCII-код для ASCII(s) символа s Найти CHR-символ для целого CHR(n) числа n. Перевод всех символов строки UPPER(ss) ss в верхний регистр Перевод всех символов строки LOVER(ss) ss в нижний регистр SUBSTR(ss,n,m) Взять подстроку с позиции n длинною m символов из строки ss Пример запроса переменными: на использование функций со строковыми 47 SELECT UCASE(cname) AS Фамилия, UCASE(LEFT(cname,1))&"." AS Инициалы, LEFT(caddress,10) & " - " & ctel AS [Адрес и телефон] FROM customers; Результат запроса со строковыми функциями показан на рис. 30 Рис. 30. Результат работы запроса с функциями для строк Задания для самостоятельной работы. 1. 2. 3. 4. 5. Напишите запрос для вычисления комиссионных продавцов по формуле (comm*100+1.25)/75. Подведите итоги по каждому продавцу и отсортируйте их в убывающем порядке. Напишите запрос, который выводит код покупателя его инициалы в порядке убывания рейтинга. Напишите запрос, который вычисляет максимальный рейтинг для каждого города продавцов. Напишите запрос, который выводит максимальный заказ на каждый день. Самостоятельно выполнить запросы: Содержание запроса 48 Запрос на SQL Выбрать продавцов, которые живут по адресу "Москва" или "Тула" Выбрать продавцов, которые живут по адресу "Москва" или "Тула" Выбрать продавцов,у которых comm >=0.12 и comm<=0.15 Найти всех покупателей, фамилия которых начинается на букву "С" Найти всех покупателей, у которых нет телефона Подсчитать количество покупателей Найти максимальный заказ Найти минимальный заказ на каждый день и не превышающий 9000 Найти максимальный заказ на каждый день Найти минимальный заказ на конкретный день Отсортировать заказы по дате и по сумме (порядок по возрастанию) SELECT * FROM Salespeople WHERE saddress="Москва" OR saddress="Тула"; SELECT * FROM Salespeople WHERE saddress IN ("Москва" , "Тула"); SELECT * FROM Salespeople WHERE comm BETWEEN 0.10 AND 0.12; SELECT * FROM customers WHERE cname LIKE("С*"); SELECT * FROM customers WHERE ctel Is Null SELECT COUNT(*) FROM customers; SELECT MAX(amount) AS Сумма FROM orders; SELECT MIN(amount) AS Сумма, odate AS Дата FROM orders GROUP BY odate HAVING MIN(amount) >9000; SELECT MAX(amount) AS Сумма, odate AS Дата FROM orders GROUP BY odate; SELECT snum, MIN(amount) FROM orders WHERE odate= #01/03/2006# GROUP BY snum; SELECT odate AS Дата, amount AS Сумма, onum AS [Номер заказа] FROM orders ORDER BY odate, amount; 49 Запрос на вычисляемые столбцы Запрос для демонстрации функций со стрингами 50 SELECT ROUND(amount,2) AS ОКРУГЛ, SIN(amount) AS СИНУС, LOG(amount) AS LOG, ABS(amount) AS АБСОЛЮТ, ROUND(SQR(amount),2) AS КВАДРАТ, (amount)/10+ ((amount)/20)*1.234 AS Выражение FROM orders; SELECT UCASE(cname) AS Фамилия, UCASE(LEFT(cname,1))&"." AS Инициалы, LEFT(caddress,10) & " " & ctel AS [Адрес и телефон] FROM customers; Занятие 3. Построение запросов к нескольким таблицам. Тема занятия 3: использование в запросах нескольких таблиц, Для демонстрации примеров SQL-запросов будем использовать учебную базу данных Avto.mdb, описание которой дано в приложении 1. 3.1. Объединение таблиц в запросах и выполнение операции JOIN (объединение) Предположим, нам надо получить ответ на вопрос: сколько заказов сделал покупатель с фамилией Семенов, причем в результате мы хотим получить таблицу, которая содержит только 4-ре следующих столбца: номер заказа, дата заказа, фамилия покупателя и фамилия продавца. Понятно, сто из одной таблицы Orders (Заказы) мы всю необходимую информацию по данному запросу не получим, т.к. таблица orders не содержит полей sname и cname. Поэтому для построения этого запроса необходимо привлечь таблицы Customers и Salespeople. Для построения запросов над несколькими таблицами в Access удобно пользоваться режимом Конструктор (ЗапросыКонструктор), который открывает окно построения запроса QBE, состоящее из двух частей: зона таблиц (сверху) и зона таблицы запроса (снизу) (более подробно о QBE см. Занятие 1). Рис.3.1. Пример построения запроса с тремя таблицами. 51 В верхнюю зону поместим три таблицы Customers, Orders и Salespeople, в нижнюю часть (зона запроса) выберем столбцы: onum и odate из таблицы orders, cname из таблицы Customers и sname из таблицы Salespeople, как показано на рис. 31. выше. В столбце с именем покупателя (cname.customers) запишем условие отбора записей (“Семенов”). Выполнение запроса даст следующий результат, который показан на рис. 32, т.е. будут отобраны только строки с заказами, которые обслужили покупателя с фамилией «Семенов». Рис.32. Результат запроса к БД «Авто.mdb» Посмотрим, как выглядит это запрос в режиме SQL, для чего войдем в редактор языка SQL через соответствующую пиктограмму или выполнив команду ВидЗапрос на SQL. Открывается окно редактора SQL и теперь мы можем рассмотреть текст запроса на языке SQL: SELECT orders.onum, orders.odate, customers.cname, Salespeople.sname FROM Salespeople INNER JOIN (customers INNER JOIN orders ON customers.cnum = orders.cnum) ON Salespeople.snum = orders.snum WHERE (((customers.cname)="Семенов")); Отметим, что имена столбцов в строке с ключевым словом SELECT записаны в полной синтаксической структуре: <имя таблицы>.<имя столбца>. Это необходимо, чтобы каждый столбец был четко и однозначно приписан к соответствующей таблице. В строке с ключевым словом FROM используются все три таблицы Oreds, Salespeple и Customers, которые объединены с помощью оператора INNER JOIN и с указанием соответствующих условий связи 52 между ними ( в нашем случае customers.cnum = orders.cnum и Salespeople.snum = orders.snum). Разобраться в структуре такого SQL сразу достаточно трудно, поэтому попытаемся создать аналогичный запрос вручную с помощью редактора SQL-запросов, путем построения сначала более простого запроса на объединение двух таблиц, а затем добавим в него необходимые ограничения с помощью условий. Запрос сформулируем следующим образом: отобрать все заказы для продавцов, которые живут в городе «Тула» (в Туле живет один продавец) и показать только три столбца (код заказа, дата заказа и фамилию продавца). Очевидно, что в построении запроса должны участвовать две таблицы: Orders и Salespeople. Сначала составим запрос без условия на отбор строк, используя строки с ключевыми словами SELECT и FROM: SELECT orders.onum, orders.odate, Salespeople.sname FROM Orders, Salespeople Результатом запроса будет объединение строк таблиц Orders и Salespeople по полям orders.onum и salespeople.sname и мы получим таблицу из 30 записей как показано на рис. 33. ниже, которая отражает всевозможные комбинации указанных столбцов (см. Введение). Часть строк этого результата являются «лишними» (т.е. не реальными) и не отвечают нашему запросу. Не реальные строки не содержатся в таблице Orders и их надо отсечь. Поэтому чтобы отобрать только «реальные» строки необходимо добавить условие, отражающее межсущностную связь (т.е. связь межу таблицами Salespeople и Orders): Salespeople.snum = Orders.snum, которое требует отбирать только те строки, в которых номер продавца в таблицах совпадает. SQL-запрос с дополнительным условием будет выглядеть так: SELECT orders.onum, orders.odate, Salespeople.sname FROM Orders, Salespeople WHERE Salespeople.snum = orders.snum 53 Рис. 33. Результат объединения двух таблиц Orders и Salespeople (операция «соединение») Результат запроса с учетом межсущностной связи между объединяемыми таблицами показан на рис. 34 ниже. Теперь получим таблицу с «реальными» строками, которые отражают все строки в таблице Orders и фамилии продавцов. 54 Рис. 34. Запрос над двумя таблицами с дополнительным условием (Salespeople.snum = orders.snum) Теперь в текст SQL-запроса добавим еще одно условие отбора строк: живущие в городе «Тула» (или Salespeople.saddress ='Тула') и соединим его при помощи логического оператора AND с условием в строке с ключевым словом WHERE. Полный запрос, отвечающий на поставленный вопрос показан ниже: SELECT orders.onum, orders.odate, Salespeople.sname FROM Orders, Salespeople WHERE (Salespeople.snum = orders.snum) AND (Salespeople.saddress ='Тула'); В результате получим искомую таблицу с одной строкой, отвечающую на поставленный вопрос (см. рис.35). Рис.35. Запрос над двумя таблицами с дополнительным условием Salespeople.saddress ='Тула' Аналогичный результат можно получить, используя оператор INNER JOIN для объединения таблиц с включением условия объединения в строку с ключевым словом FROM. В этом случае запрос на SQL будет выглядеть следующим образом: 55 SELECT Orders.onum, Orders.odate, Salespeople.sname FROM Salespeople INNER JOIN Orders ON Salespeople.snum = Orders.snum WHERE Salespeople.saddress ='Тула'; Следует отметить, что поле snum в таблице Salespeople является первичным ключем, а поле snum в таблице orders – внешним ключом, который используется для связи и организации проверки целостности. Более подробно о целостности в реляционных базах данных смотри в работе []. Таким образом, ключевое слово INNER JOIN с условием на первичных и внешних ключах позволяет упростить структуру запроса над несколькими таблицами, оставляя в строке с ключевым словом WHERE только условия над обычными полями. 3.2. Объединение копий таблиц В сложных запросах можно объединять не только разные таблицы, но и копии одной таблицы. Например, если необходимо найти все пары продавцов, которые имеют одинаковые комиссионные. Для этого с помощью Конструктора создадим запрос как показано на рис. 36. Здесь таблица Salespeople выбрана два раза, поэтому в зоне таблиц находится таблица Salespeople и ее копия Salespeople_1. Рис. 36.Пример запроса над таблицей Salespeople и ее копией (Salespeople_1). 56 Текст соответствующего SQL-запроса показан ниже: SELECT Salespeople.sname, Salespeople_1.sname, Salespeople_1.comm FROM Salespeople, Salespeople AS Salespeople_1 WHERE (((Salespeople_1.comm)=[Salespeople].[comm]) Имя второй таблицы и ее синоним (Salespeople AS Salespeople_1) содержится в строке с ключевым словом FROM. Результат этого запроса будет содержать все комбинации пар фамилий, которые имею одинаковый рейтинг, в том числе и строки с идентичными фамилиями (см. рис.37). Рис.37. Результат запроса с двумя таблицами Salespeople. Исключить строки с одинаковыми значениями в первом и втором столбцах можно, добавив через логическую связку AND условие типа: Salespeople_1.snum < Salespeople.snum (т.е. «номер продавца в первой таблице должен быть строго меньше номера во второй таблице»). Это позволит исключить строки типа «Веселов=Веселов». В этом случае полный запрос будет выглядеть как показано ниже: SELECT Salespeople.sname, Salespeople_1.sname, Salespeople_1.comm FROM Salespeople, Salespeople AS Salespeople_1 WHERE (((Salespeople_1.comm) = [Salespeople].[comm]) AND ((Salespeople_1.snum) < [Salespeople].[snum])); 57 Результат запроса с дополнительным условием показан на рис.38. Здесь отобрана только одна строка, в которой продавец «Трофимов» имеет комиссионные такие же как и продавец «Змеев», что полностью соответствует поставленному вопросу. Рис.38. Результат отбора строк с дополнительным условием (Salespeople_1.snum < Salespeople.snum); Следует отметить, что конструктор QBE, строит синонимы таблиц по упрощенному алгоритму. В общем случает можно использовать любые синонимы для выбранных таблиц. Вот как будет выглядеть тот же запрос, если мы для первой таблицы Salespeople будем использовать букву A, а для второй таблицы Salespeople - ,букву B: SELECT A.sname, B.sname, B.comm FROM Salespeople AS A, Salespeople AS B WHERE B.comm = A.comm AND B.snum < A.snum; Результат запроса с синонимами таблиц показан на рис.38. Таким образом, вводя в SQL запросах синонимы исходным таблицам базы данных, пользователь может существенно расширить возможности при построении сложных запросов над одной или несколькими таблицами. 3.3.Вложенные запросы Язык SQL позволяет строить вложенные запросы, т.е. такие запросы, которые в условиях используют результаты работы другого запроса. Например, нам известна фамилия продавца (пусть это «Курочкин»), но не известен его номер, а нам необходимо знать все заказы этого продавца. Этот запрос можно выполнить в два этапа: 58 - сначала найти по таблице Salespeople код продавца (выполнив запрос: SELECT snum FROM Salespeople WHERE sname = "Курочкин"); - затем, по коду продавца (код продавца с фамилией «Курочкин» равен ‘0001’) выбрать из таблицы Orders все его заказы (выполнив запрос: SELECT * FROM Orders WHERE snum=’0001’). Такой способ получения результата не очень удобный. Добиться аналогичного результата можно другим способом – построением вложенного запроса. Для этого в Конструкторе в строке «Условия запроса» введем запрос на поиск кода продавца. На рис.39. показано как выглядит вложенный запрос в Конструкторе. Вложенный запрос Рис.39. Построение вложенного запроса в строке «Условие отбора». Текст SQL-запроса с вложенным запросом показан ниже: SELECT * FROM Orders WHERE snum=(SELECT snum FROM Salespeople WHERE sname = "Курочкин") 59 Важным условием корректности исполнения вложенных запросов, является однозначность результата «внутреннего» (вложенного) запроса. В нашем случае мы имеем однозначный результат внутреннего запроса ( код продавца «Курочкина» равен ‘0001’). Результат выполнения вложенного запроса показан на рис. 40. Рис.40. Результат SQL-запроса с вложенным запросом Более сложный вложенный запрос, построенный на основании предыдущего запроса, может выглядеть так: SELECT orders.onum as НОМЕР, orders.odate as ДАТА, Salespeople.sname as ФАМИЛИЯ, price.pname as МАРКА, orders.amount as ЦЕНА FROM Salespeople INNER JOIN (price INNER JOIN orders ON price.pnum = orders.pnun) ON Salespeople.snum = orders.snum WHERE Salespeople.snum =(SELECT snum FROM Salespeople WHERE sname = "Курочкин"); Результат этого запроса, который использует несколько таблиц (Orders, Salespeople и Price) и содержит встроенный запрос, который по фамилии "Курочкин" определяет код продавца показан на рис. 41. Рис.41. Результат сложного запроса с несколькими таблицами и встроенным запросом. 60 Задания для самостоятельной работы. 1. 2. 3. 4. 5. Напишите запрос, который выводит номер заказа, дату заказа, фамилию покупателя и марку автомобиля. Напишите запрос, который выводит код заказа, его стоимость и марку автомобиля для заказчика с конкретной фамилией. Приведите пример запроса, который использует синонимы таблиц. Напишите запрос, который использует вложенный запрос. Вывести все заказы, сумма заказа которых больше средней суммы всех заказов. Самостоятельно выполнить запросы: Содержание запроса Выдать заказы продавцов, которые живут в городе «Тула» Выдать все заказы в таблице со следующими столбцами: номер заказа, дата заказа, фамилия продавца, марка авто, цена Выдать все пары продавцов. Которые имею одинаковые комиссионные Выдать все заказы для продавца с фамилией «Курочкин» Текст SQL-запрос SELECT orders.onum, orders.odate, Salespeople.sname FROM Orders, Salespeople WHERE (Salespeople.snum = orders.snum) AND (Salespeople.saddress ='Тула'); SELECT orders.onum, orders.odate, orders.amount, Salespeople.sname, price.pname, price.price FROM Salespeople INNER JOIN (price INNER JOIN orders ON price.pnum = orders.pnun) ON Salespeople.snum = orders.snum; SELECT A.sname, B.sname, B.comm FROM Salespeople AS A, Salespeople AS B WHERE B.comm = A.comm AND B.snum < A.snum; SELECT * FROM Orders WHERE snum=(SELECT snum FROM Salespeople WHERE sname = "Курочкин") 61 Занятие 4. Запросы на ввод и корректировку данных в таблицах базы. Тема занятия 4: Освоение приемов построения запросов на ввод, изменение и удаление данных в/из таблицы БД. 4.1. Запросы на ввод данных в таблицы Язык SQL не приспособлен для организации удобного ввода данных в таблицы, хотя в его состав включены языковые конструкции, позволяющие выполнить все необходимые операции по манипуляции данными в таблицах. Все команды манипулирования данными объединены команды языка DML (Data Manipulation Language), который включает следующие команды: INSERT (вставить), UPDATE(изменить) и DELETE (удалить), Рассмотрим команду вставки данных в таблицы, структуру которой можно представить следующим образом: INSERT INTO <имя таблицы> VALUES (<значение 1>,< значение 2>,…,< значение N>); Построим пример запроса для вставки новой записи с данными в таблицу. Например, надо добавить нового продавца (т.е. вставить новую запись в таблицу Salespeople) со следующими параметрами: код продавца - 1010, фамилия - Бояринов, адрес - Москва, комиссионные 0.12, телефона - нет, почта - bojar @yandex.ru. Это можно сделать следующим запросом: INSERT INTO Salespeople VALUES ("1010", "Бояринов", "bojar@yandex.ru"); "Москва", 0.12, Null, В результате работы запроса в таблицу Salespeople вставится новая строка для продавца с кодам «1010» ( см. рис. 42). 62 Рис. 42. Пример ввода строки данных в таблицу с помощью команды INSERT INTO…VALUES. В некоторых случаях можно использовать имена столбцов для ввода данных в конкретные поля. Например, если нам надо ввести нового покупателя, о котором известна пока только его фамилия, то для этого можно использовать следующую команду: INSERT INTO Customers (cname, cnum) VALUES ("Синичкин", "2007"); В результате выполнения такого запроса в таблицу покупателей добавится новая строка с кодом «2007» (cnum ="2007"), у которой будет заполнен только один столбец cname (cname="Синичкин"). Можно осуществить вставку данных в текущую таблицу, путем выбора данных по запросу из другой таблицы. Например, имеется отдельная таблица «Жители Москвы» (“CitizenOfMoscow”), в которую мы хотим скопировать всех покупателей, которые живут в городе «Москва». Для переноса данных в таблицу CitizenOfMoscow можно создать SQLзапрос следующего вида: INSERT INTO CitizenOfMoscow SELECT * FROM Customers WHERE caddress='Москва'; В результате в таблицу CitizenOfMoscow будет добавлено 2-е записи., потому что, только два покупателя живут в городе «Москва» Корректное выполнение этого запроса предполагает, что таблица CitizenOfMoscow создана до начала его выполнения и 63 структура таблицы CitizenOfMoscow совпадает со структурой таблицы Customers. Такой режим использования команды INSERT часто используется при обновлении структуры таблицы, когда требуется добавить новый столбец к уже существующей таблице. Для изменения структуры таблицы и добавления нового столбца можно использовать команду ALTER конструкция которой имеет вид: ALERT TABLE <имя таблицы> ADD <тип данных><размер>. Команда ALTER не является стандартной для ANSI, поэтому на практике в Access ее приходится заменять набором команд. Так, например, набор команд на обновление структуры таблицы может состоять из следующих команд: -создание новой таблицы (CREATE), - перенос данных в новую таблицу (INSERT совместно с SELECT) -и удаление старой таблицы (DROP). 4.2. Запросы на изменение данных в таблицах Изменение значений данных в столбцах производится с помощью команды UPDATE, которая имеет следующую конструкцию: UPDATE <имя таблицы> SET <имя столбца 1>=<значение>, <имя столбца 2>=<значение>,…, <имя столбца N>=<значение>, WHERE <условие> Запрос на изменение в Access удобно строить с помощью конструктора в два этапа. Сначала построить простой запрос с условием для отбора строк. Посмотреть результаты отбора и, если, отобранные строки полностью удовлетворяют вашим условиям, трансформировать исходный запрос на запрос в команду UPDATE. Предположим, мы хотим всем покупателям, которые живут в городе «Москва», изменить рейтинг на 125. Выполним запрос на отбор строк с продавцами, которые живут в городе «Москва»: SELECT * FROM Customers WHERE caddress = "Москва"; 64 В результате отберутся только две строчки. Теперь выполним команду ЗапросОбновление и снова войдем в режим просмотра SQL-запросов. Запрос на обновление будет выглядеть, как показано ниже: UPDATE Customers SET WHERE (((Customers.caddress) = "Москва")); В оператор SET добавим имя столбца и новое значение и получим полный запрос на обновление содержимого столбца raiting: UPDATE Customers SET raiting=125 WHERE (((Customers.caddress)="Москва")); Таким образом, используя конструктор и просматривая запросы в режиме SQL, можно строить достаточно сложные запросы на обновление. 4.3. Запросы на удаление данных из таблиц Аналогичным образом строятся и запросы на удаление записей из таблицы. Общая форма запроса на удаления имеет вид: DELETE * FROM <имя таблицы> WHERE <условия отбора записей> Напишем запрос на удаление всех продавцов, которые живут в городе «Тула». Для этого сначала запишем запрос, который отбирает все записи с продавцами, у которых выполняется условие saddress ="Тула": SELECT * FROM Salespeople WHERE saddress ="Тула" ; В результате выберутся только две строки. Теперь войдем в режим конструктов запросов и выберем команду ЗапросУдаление. Запрос на отбор строк трансформируется в запрос на удаление и примет вид: 65 DELETE Salespeople.saddress, * FROM Salespeople WHERE (((Salespeople.saddress)="Тула")); После выполнения запроса на удаление две строки (которые отобраны и просмотрены ранее) будут удалены из таблицы Salespeople. Задания для самостоятельной работы. 1. 2. 3. 4. 5. 6. 7. Вставить новую сроку в таблицу Price Изменить цены в таблице Price для автомобилей определенной марки. Создать новую таблицу для хранения заказов всех продавцов, которые живут в городе «Тула» и перенести в нее данные из таблицы Orders. Удалить все заказы с определенной датой. Вставить запись для нового заказа. Удалить всех продавцов, которые не обслужили ни одного заказа (увольнение неработающих продавцов). Самостоятельно выполнить запросы: Содержание запроса Вставить строку в таблицу продавцов с конкретными данными: код продавца – “1010”, фамилия – “Мишин”, комиссионные – 0.15, телефон – “3452431”, почта – “mishin@yandex.ru” Создать новую таблицу CitizenOfMoscow и перенести в нее данные из таблицы Customers по условию saddress=”Москва”; Выполнить изменение рейтинга в таблице Customers для тех покупателей, которые живут в Москве (caddress = "Москва"). 66 Запрос на SQL INSERT INTO Salespeople VALUES ("1010", "Мишин", "Тула", 0.15, "345-24-31 ", "mishin@yandex.ru"); INSERT INTO CitizenOfMoscow SELECT * FROM Customers WHERE saddress=”Москва”; UPDATE Customers SET raiting=125 WHERE caddress = "Москва"; Провести отбор строк для продавцов, которые живут в городе Тула (saddress ="Тула") и затем удалить эти строки из таблицы. SELECT * FROM Salespeople WHERE saddress ="Тула" ; DELETE * FROM Salespeople WHERE Salespeople.saddress ="Тула"; 67 Занятие 5. Запросы на создание и изменение базы данных. Тема занятия : Освоение запросов, с помощью которых производится изменение базы данных (создание, изменение и удаление таблиц) Команды определения таблиц относятся к разделу языка SQL, который принято называть языком DDL (Data Definition Language), который позволяет реализовать процедуры создания объектов реляционной базы данных. 5.1. Запросы на создание таблиц базы данных В реляционных базах данных таблицы состоят из записей и полей (столбцов). Чтобы создать таблицу, достаточно задать ее имя и описать поля. Описание каждого поля содержит: имя поля, тип данных в поле, (опционально можно задать размер поля и ограничения). Создание таблиц происходит с помощью команды CREATE TABLE, синтаксис которой можно представить так: CREATE <имя таблицы> (<имя поля 1> <тип данных> [<размер>] [ограничения], <имя поля 2> <тип данных> [<размер>] [ограничения], …, <имя поля N> <тип данных> [<размер>] [ограничения] ) Имя таблицы и имена столбцов обычно составляются из латинских букв (хотя Access допускает использование любых алфавитных символов) и желательно без пробелов. Это связано с тем, что если Вам придется использовать созданную базу данных в приложениях, построенных на продуктах других фирм (т.е. не фирмы Microsoft), то могут возникнуть проблемы доступа к таблицам. Особенно чувствительны к именам таблиц и полей Интернет приложения. Наиболее часто используемые типы данных в описании полей следующие: CHAR символьные данные; INTEGERчисловые целые; FLOAT числовые с плавающей запятой; DATE данные типа даты. 68 Полный список типов данных можно получить в команде «Справка» справочной системы Access (разделе: «Эквивалентные типы данных ANSI SQL»). Фрагмент справочной таблицы типов данных Access приведен ниже: Типы данных ANSI SQL Типы данных Microsoft Jet SQL Синоним VARBINARY, BINARY VARYING BIT VARYING DATE, TIME, DATE, TIME (См. DATETIME TIMESTAMP Примечания) DECIMAL DECIMAL NUMERIC, DEC SINGLE, FLOAT4, REAL REAL IEEESINGLE DOUBLE, FLOAT8, DOUBLE IEEEDOUBLE, PRECISION, FLOAT NUMBER (См. FLOAT Примечания) SMALLINT SMALLINT SHORT, INTEGER2 LONG, INT, INTEGER INTEGER INTEGER4 TEXT(n), ALPHANUMERIC, CHARACTER, STRING, CHARACTER, VARCHAR, CHARACTER CHARACTER VARYING, VARYING, NCHAR, NATIONAL CHAR NATIONAL CHARACTER, CHARACTER, NATIONAL NATIONAL CHAR, CHARACTER NATIONAL VARYING CHARACTER VARYING, NATIONAL CHAR VARYING BIT, BIT VARYING BINARY Тип данных Microsoft SQLServer BINARY, VARBINARY DATETIME DECIMAL REAL FLOAT SMALLINT INTEGER CHAR, VARCHAR, NCHAR, NVARCHAR 69 При описании типа данных в полях можно, используя специальные ключевые слова, ввести дополнительные ограничения (columns constraints) на множество допустимых значений. Ниже приведены некоторые ключевые слова, описывающие ограничения: NOT NULL – значение поля не должно быть пустым; UNIQUE – значение поля должно быть уникальным; PRIMERY KEY – определяет принадлежность поля ключу; DEFAULT – автоматическая подстановка конкретного значения; CHECK (<условие>) – проверка условия, которому должен удовлетворять вводимое значение в поле. Рассмотрим пример создания таблицы базы данных, учитывающей сотрудников предприятия. Положим, что таблица Employees (Сотрудники) будет содержать следующие поля: код сотрудника (E_KOD), фамилия (E_FAM), имя (E_NAM), дата рождения (E_DATE) и стаж работы (E_STAG). Создадим описание таблицы Employees с помощью запроса на SQL, выбрав для этого режим ЗапросыСоздатьКонструкторЗапросSQL и выйдем на окно редактора запросов на языке SQL. В редакторе запишем запрос на языке SQL на создание таблицы Employees: CREATE TABLE Employees ( E_KOD CHAR (4) NOT NULL, E_FAM CHAR (30), E_NAM CHAR (30), E_DATE DATE, E_STAG INTEGER ); Выполним созданный запрос и убедимся, что в списке таблиц появилась новая таблица (Employees). Вызвав режим «Конструктор таблиц», проверим правильность описания полей. Отметим, что в созданной таблице не указано ключевое поле. Замечание: При благополучном исполнении запроса на создание новой таблицы Access не выдает никаких сообщений. В случае же обнаружения ошибки синтаксиса или невозможности выполнения запроса будет дано соответствующее сообщение. 70 Усложним запрос на создание таблицы Employees, введя ограничение, которое определяет поле E_KOD как ключевое («первичный ключ»): CREATE TABLE Employees (E_KOD CHAR (4) NOT NULL PRIMARY KEY , E_FAM CHAR (30), E_NAM CHAR (30), E_DAT DATE, E_STAG INTEGER); Ограничение на поле данных можно описать так же отдельной строкой. Например, если необходимо ускорить поиск данных по коду сотрудника (поле E_KOD), то его можно проиндексировать. Иными словами, можно создать специальный список (индекс), который позволит значительно ускорить поиск по полю, к которому «привязан» индекс. Запрос на создание таблицы с индексированным ключевым полем запишется так: CREATE TABLE Employees (E_KOD CHAR (4) NOT NULL , E_FAM CHAR (30), E_NAM CHAR (30), E_DAT DATE, E_STAG INTEGER, CONSTRAINT [Index1] PRIMARY KEY (E_KOD) ); В приложении 1 можно найти полное описание всех таблиц учебной базы данных Avto.mdb (база данных магазина продаж автомобилей). Для описания связей между таблицами и обеспечения целостности базы данных используется ключевое слово FOREIGN KEY, полный синтаксис которого следующим образом: FOREIGN KEY<список [<список столбцов >] столбцов>REFERENCES <имя таблицы> Например, таблица Price («Цена») связана с таблицей Orders («Заказы») через поле pnum (код строки в таблице Price). Поле pnum в таблице Price является ключевым (т.е. оно описано как PRIMARY KEY), а в таблице Orders поле pnum играет роль «внешнего» ключа для 71 связи (FOREIGN KEY).Обычно такая связь отображается на схемах БД как отношение «один-ко-многим» (1:М). Поэтому в таблице Orders поле pnum надо описать как внешний ключ следующим образом: CREATE TABLE Orders (onum CHAR (4) NOT NULL PRIMARY KEY, odate DATE, amont FLOAT, cnum CHAR(4), snum CHAR(4), pnum CHAR(4), FOREIGN KEY (pnum) REFERENCES Price (pnum)); Замечание: Типы данных и размер поля у первичного ключа и у поля внешнего ключа должны быть одинаковые. Если таблица Orders связана с несколькими таблицами, то каждая связь должна быть описана аналогичным способом. 5.2. Запросы на создание индексов в таблицах Для повышения быстродействия базы данных в режиме поиска возможно создание специальных средств типа индексов. Синтаксис команды создания индекса можно представить так: CREATE INDEX <имя индекса> ON <имя таблицы> (<имя столбца 1> [,<имя столбца 2>] …); Описание обязательно должно содержать: имя индекса, имя таблицы, к которой привязан индекс и хотя бы одно имя столбца. Пример использования индекса. Если в базе данных имеется таблица, в которой хранятся данных счетов клиентов (таблица INVOICES), то очень часто требуется наитии счет по его номеру (поле NUM_INV). В этом случае целесообразно создать индекс (имя индекса INDEX1 ) для поля NUM_INV: CREATE INDEX INDEX1 ON INVOICES (NUM_INV); Удаление индекса производится следующей командой: 72 DROP INDEX <имя индекса>. Следует заметить, что в некоторых SQL-системах создание и удаление индексов происходит автоматически в зависимости от потребностей системы. Так что пользователи могут ничего не знать о существовании индексов в системе. 5.3. Запросы на удаление базы данных Удаление таблиц выполняется с помощью команды DROP TABLE <имя таблицы> Например: Удалить таблицу Employees из базы данных Avto.mdbможно SQL запросом, который показан ниже: DROP TABLE Employees 5.4. Модификация таблиц Модификацию таблиц с помощью SQL-запросов можно выполнить следующей последовательностью процедур: - создать новую таблицу с помощью CREATE TABLE NewTab (<описание столбцов>); - перенести данные из старой таблицы в новую с помощью запроса INSERT INTO <условия отбора данных>; - Удалить исходную таблицу с помощью DROP TABLE <имя таблицы>. Изменить структуру созданной таблицы можно с помощью команд - ALTER TABLE - DROP COLUMN - ALTER COLUMN - RENAME COLUMN – добавить столбец; – удалить столбец; – изменить параметры столбца; – переименовать столбец; Пример добавления столбца NewPrice в таблицу Price: ALTER TABLE Price ADD COLUMN NewPrice FLOAT Пример удаления столбеца NewPrice из таблицы Price: 73 ALTER TABLE Price DROP COLUMN NewPrice 5.5 Пример описания базы даны «Автосалон» База данных «Автосалон» (avtoshop.mdb) предназначена для регистрации продаж в автосалоне. База данных avtoshop.mdb состоит из 4-х таблиц: «Продавцы» (salespeople), «Покупатели» (customers), «Цена» (price) и «Заказы»( orders). Описание каждой таблицы на языке SQL приведено ниже: create table Salespeople ( snum char(4) not null primary key, sname char(30) not null, saddress char(60), comm float , stel char(20), semail char(40) ); create table Customers ( cnum char(4) not null primary key, cname char(30) not null, caddress char(60), rating int , ctel char(20), cemail char(40) ); 74 create table Price ( pnun pname peddim price pdate char(4) not null primary key, char(60) not null, char(10), float , datetime Not null ); create table Orders ( onum odate amount snum char(4) not null primary key, datetime Not null, float , char(4) not null, cnum pnun char(4) not null, char(4) not null ); Выполнить каждый из выше приведенных запросов можно в среде СУБД Access в режиме ЗапросыКонструкторРежим SQL. Войдя в режим редактора SQL, скопируйте из методического руководства текст запроса на создание таблицы Orders (см. рис. 43) и выполните его. Рис.43. Пример подготовки запроса на создание таблицы в среде Access (редактор SQL-запросов) Замечание: следует отметить, что при благополучном выполнении запросов СУБД Access не выдает никаких сообщений, а результат выполнения запроса на создание новой таблицы можно просмотреть в режиме Таблицы. В случае обнаружения ошибки в тексте запроса на экран выдается сообщение, комментирующее тип ошибки. В результате реализации всех SQL-запросов в среде СУБД Access получаем базу данных, схема которой приведена на рис.44. ниже. Одно из важных преимущест описания структуры базы данных на языке SQL является то, что отлаженный набор SQL-запросов можно легко перенести в другую СУБД (например, в СУБД SQL Server 2000), что позволяет создать «двух-ступенчатую» технологию разработки баз данных: - сначала отработать схему базы данных в локальной версии СУБД Access; 75 Рис.44. Схема базы данных «Автосалон» (avtoshop.mdb) - затем с минимальными переделками перенести набор отлаженных SQL-запросов в серверную версию СУБД SQL Server 2000, используя для этого Query Analyzer. Вариант SQL-запроса для создания базы данных AvtoShop в среде SQL Server 2000 и запроса создания в новой базе данных таблицы Salespeople показан ниже: create databases avtoshop; use avtoshop; create table salespeople ( snum char(4) not null primary key, sname char(30) not null, saddress char(60), comm float(6,2) default 0, stel char(20), semail char(40) ); 76 Занятие 6. Создание приложений с использованием запросов на языке SQL. Особенно полно преимущества языка SQL, как инструмента доступа к реляционным базам данных, раскрываются в приложениях, разработанных с применением языков программирования типа Си, Visual Basic, Visual Basic for Application, VBScript, JavaScript, JavaScript или Delphi. Мощь процедурных языков в сочетании с гибкостью языка SQL дает принципиально новые возможности для быстрых технологий создания пользовательских диалоговых приложений. Ниже рассматриваются некоторые примеры таких реализаций на VBA и VBScript. 6.1. Приложение в среде VBA Разработка диалоговых приложений в среде VBA подробно разобрано в работе [2]. Поэтому здесь напомним только основные приемы создания модулей для доступа к базам данных через объекты (компоненты объектной библиотеки) ADO (ActiveX Data Object). Для создания приложения будем использовать Ecxel (ПускПрограммыExcel). В Excel перейдем в режим редактора VBA (Alt+F11) и создадим модуль (InsertModule), создадим модуль Test_AvtoShop(). Затем подключим библиотеку MS ADO (ToolsReferences <выбор компоненты MS ADO>) и разработаем скрипт (текст программы), который выполнит следующие процедуры: - коннекция к базе данных; - обработка SQL-запроса; - вывод отобранных данных на лист в форме отчета. Пусть база данных avtoshop.mdb находится в директории D:\Учебное пособие по SQL В Access. Пример простого скрипта, выполняющего эти процедуры применительно к учебной базе данных avtoshop.mdb показан ниже. Sub Test_AvtoShop() '1 - коннекция к базе данных -'--Создание объекта <ADODB > Set Db = CreateObject("ADODB.Connecti on") '---- формирование стринга для связи с базой данных--StrOpen = "Provider=Microsoft.Jet.OLEDB. 4.0;Data Source=D:\Учебное 77 пособие по SQL в Access\AvtoShop.mdb" Db.Open StrOpen '2 - Выполнение SQL-запроса '- Создание объекта типа <запись> -Set rs = CreateObject("ADODB.Recordse t") Set rs.ActiveConnection = Db '------формирование стринга для отбора записей -----StrSQL = "SELECT * FROM Salespeople;" '---- подготовка набора записей rs.Open StrSQL '3 ---Ввывод записей в таблицу ---'-если набор пуст, то товара нет на складе ----If rs.EOF = True Then MsgBox "Записей нет" Exit Sub End If '-- вывод строки заголовков столбзов --Nstr = 1 RabTab = "Лист1" k=1 With Sheets(RabTab) For Each fl In rs.Fields .Cells(Nstr, k).Value = fl.Name k=k+1 Next '------ вывод тела таблицы ----Nstr = 2 Do Until rs.EOF = True k=1 For Each fl In rs.Fields .Cells(Nstr, k ).Value = fl.Value k=k+1 Next '----------rs.MoveNext Nstr = Nstr + 1 Loop '---------------------------------End With End Sub Результат будет выводится в виде отчетной таблицы на Лист1. Более сложный пример, который использует диалоговую форму для выбора SQL-запроса описан в приложении 2. 6.2. Разработка локальных Web-приложений (на VBScript). Аналогичный скрипт, который обеспечивает доступ к базам данных, можно разработать и для Web-среды. Более подробно приемы создания таких скриптов описаны в работе [5]. В данном пособие мы приведем пример простого скрипта, который выполняет те же (см. 6.1) процедуры доступа к учебной базе данных avtoshp.mdb и выводит отчет на экран в форме HTML-файла. Предполагается, что база данных находится (т.е. локализована) на том же компьютере, что Web-среда, через которую пользователь 78 будет осуществлять доступ к данным. Такой режим доступа к базам данным называется – локальным, а приложение – локальным Webприложением. Ниже приведен скрипт, который позволяет вывести отчет по SQL-запросу в окно браузера. <HTML> <HEAD> <SCRIPT language=VBScript> Sub Test_AvtoShop() msgbox "ТЕСТ" '1 - коннекция к базе данных -'--Создание объекта <ADODB > Set Db = CreateObject("ADODB.Connecti on") '---- формирование стринга для связи с базой данных--StrOpen = "Provider=Microsoft.Jet.OLEDB. 4.0;Data Source=D:\Учебное пособие по SQL в Access\AvtoShop.mdb" Db.Open StrOpen '2 -Выполнение SQL-запроса -'----- Создание объекта типа <запись> -Set rs = CreateObject("ADODB.Recordse t") Set rs.ActiveConnection = Db '------формирование стринга для отбора записей -----StrSQL = "SELECT * FROM Salespeople;" '---подготовка набора записей -rs.Open StrSQL '3 --Вывод записей в таблицу '-- если набор пуст, то товара нет на складе ----If rs.EOF = True Then MsgBox "Записей нет" Exit Sub End If '-вывод строки заголовков столбцов --Nstr = 1 RabTab = "Лист1" tt="<HTML><BODY><h2> Отчет </h2><TABLE border=1><TR>" For Each fl In rs.Fields tt=tt & "<TD>" & fl.Name & "</TD>" Next tt=tt & "</TR>" '------ вывод тела таблицы ----Nstr = 2 Do Until rs.EOF = True tt=tt & "<TR>" For Each fl In rs.Fields tt=tt & "<TD>" & fl.Value & "</TD>" Next '----------rs.MoveNext Nstr = Nstr + 1 tt=tt & "</TR>" Loop tt=tt & "</TABLE></BODY></HTML> " '-----------------------------document.write (tt) '-----------------------------End Sub 79 </SCRIPT> </HEAD> <BODY> <h2>Приемер вывода данных из базы данных</h2> <hr> <input name=b1 type=button value="ОТЧЕТ" onclick="Test_AvtoShop()"> </BODY> </HTML> Замечение: Данный скрипт может быть плучен путем простой трансформации скрипта отлаженного в среде VBA (см. 6.1)., путем добавления необходимых тегов и коррекции процедуры «3 –вывода записей в таблицу». Результат будет выводиться в окно браузера в виде таблицы. 6.3. Некоторые приемы ASP-технологии В тех случаях, когда база данных находится на северной стороне т.е. размещена на компьютере, который выполняет функции сервера базы данных, то в этом случает применяют так называемую «клиент-серверную» технологию. Один из популярных подходов решения этой задачи является технология Active Server Page (ASP) фирмы MicroSoft, разработанная для реализации доступа к данным, расположенных на сервере в режиме «клиент-сервер». В основу клиентсерверной концепции положена схема взаимодействия удаленного пользователя с базой данной, которую можно изобразить, как показано на рис. 45 Сервер SQL-Запрос База данных I I S Ответ в HTML-форме Клиент Браузер для просмотра HTMLфайлов Рис.45. Упрощенная схема взаимодействия «клиента» с «сервером» в ASP-технологии 80 В этой схеме клиент, используя браузер, посылает на сервер SQL-запрос, который принимается специальной серверной службой (например, Internet Information Server- IIS) и передается в приложение пользователя (ASP-файл). ASP-приложение обрабатывает запрос, выполняет доступ к базе данных и готовит ответ в формате HTML. Подготовленный по запросу на сервере HTML-файл принимается браузером клиента и разворачивается в форме удобной для восприятии конечным пользователем. Таким образом, для реализации ASP-технологии доступа к базе данных «Автосалон», необходимо выполнить следующее: - Разместить базу avto.mdb на сервере в специальном директории, который сервер IIS воспринимает как доступный для уудаленной обработки. Обычно такой директорий создается автоматически при установке IIS и называется C:/Inetpub/wwwroot/. - Разработать диалоговую HTML-форму для ввода SQL-запроса на стороне клиента. - Разработать ASP-файл, который будет принимать от клиента (от формы) запрос, обрабатывать его и возвращать клиенту готовый HTML-файл с ответом. В частном случае в качестве сервера может выступать тот же компьютер, на котором находится клиент. В этом случает клиент обращается к серверу по адресу 127.0.0.1 (или присваивает ему имя loacalhost). Разработка ASP-проекта начинается с создания диалоговой формы на стороне клиента. В качестве примера создадим Фому, которая будет позволять пользователю выбирать запрос из списка и передавать текст запроса к ASP-процедуре, которая находится на сервере. Создание диалоговой HTML-формы проведем в простом редакторе текстов NotePade. На форме разместим следующие объекты: Произвольный текст; S1 - список запросов (объект <SELECT>); S2 – многострочный бокс (объект <TEXTAREA>); B1 – командная кнопка (объект <INPUT type=button>). Замечание: опытные разработчики могут использовать для создания диалоговых HTML-форм специальные редакторы типа Frontpage. Затем в HTML вводятся тексты скриптов, которые выполняют процедуры обработки событий: 81 - событие Click на строке списка, для выбора нужного запроса из списка S1 и размещение его в боксе S2; - событие Click на кнопке, для передачи SQL-запроса из бокса S2 в ASP-процедуру. Пример текста диалоговой HTML-формы клиента приведен ниже: <HTML> <HEAD> <TITLE>Выбор SQL-запроса</TITLE> <LINK rel="stylesheet" href="TabStyle.css" type="text/css"> <SCRIPT language ="VBScript"> Sub Test() nn=frm.s1.SelectedIndex tt=frm.s1.options(nn).value 'msgbox "Проверка =" & nn & " " & tt frm.S2.value=tt End Sub '----------------------------------Sub Test2() tt=frm.S2.value msgbox "Значение =" & tt document.frm.submit End sub </SCRIPT> <BODY> <FORM name=frm action="http://127.0.0.1/Avto.asp" method="post"> <h1> <p>&nbsp;</p> <center> SQL запросы к базе данных "Автосалон"</center><h1> <hr> <h2>Выбери запрос</h2> <SELECT name=s1 size=3 onclick="Test()"> <OPTION value="SELECT * FROM Salespeople">Просмотр списка сотрудников <OPTION value="SELECT * FROM Customers">Просмот списка покупателей <OPTION value="SELECT * FROM Orders">Просмотр заказов <OPTION value="SELECT pnum as Номер, pname AS Марка, price AS Цена FROM Price">Просмотр прайс листа 82 <OPTION value="SELECT Salespeople.sname AS Сотрудник, Sum(orders.amount) AS Сумма FROM Salespeople INNER JOIN orders ON Salespeople.snum = orders.snum GROUP BY Salespeople.sname"> Суммирование заказов по продавцам </SELECT> <hr> <h2>Выбранный запрос</h2> <p><textarea name="S2" rows="3"cols="40"></textarea></p> <input name=b1 type=button value="Выполнить запрос" onclick="Test2()"> </FORM> </BODY> </HTML> Вид рабочей формы клиента со списком SQL-запросов к базе данных «Автосалон» показан на рис. 46. Рис.46. Пример HTML-формы для выбора SQL-запроса к базе данных. Описание ASP-модулей 83 SQL-запрос, выбранный из списка, помещается в текстовый бокс, где пользователь может выполнить дополнительное редактирование запроса. Затем, нажав кнопку [Выполнить запрос], клиент посылает методом POST содержимое формы на сервер к ASPпроцедуре для дальнейшей обработки. Замечание: Обратите внимание на строку <FORM name=frm action="http://127.0.0.1/Avto.asp" method="post">. В ней указан адрес локального сервера (127.0.0.1). На практике надо указать адрес фактического сервера, на котором установлена ASPпроцедура, обрабатывающая запрос. Процедура Avto.asp принимает запрос от формы клиента и выполняет следующие действия: - создает объект для установки связи с базой данной на сервере и открывает указанную базу данных; - создает объект для чтения набора записей по SQL-запросу и производит фактическое чтение данных из базы; - выводит набор записей в HTML-отчет и передает его на сторону клиента. Пример ASP-процедуры приведен ниже: <%@ language="VBScript" %> <HTML> <LINK rel="stylesheet" href="TabStyle.css" type="text/css"> <BODY> <% adOpenDynamic=2 adLockPessimistic=2 adCmdText=1 '------ прием запроса от клиента -----------------------response.write "<H2> Принятые от формы данные </H2>" StrSQL=Request.form("s2") response.write "SQL запрос =" & StrSQL & "<BR>" '-------- подготовить имя базы данных и провайдера ----Prov="" DbName="Avto.mdb" PtName="C:/Inetpub/wwwroot/" FullDbName=PtName& DbName response.write " Полное имя базы=" & FullDbName '----------открыть базу данных на сервере ---------84 Set Mydb=Server.CreateObject("ADODB.Connection") With Mydb .Provider = "Microsoft.Jet.OleDB.4.0" .ConnectionString = FullDbName '.Mode = adModeShareWrite .Open End With '----------- Создать объект типа запись -----------Set rs = CreateObject("ADODB.RecordSet") rs.Open StrSQL, MyDB, adOpenDynamic, adLockPessimistic, adCmdText response.write "<h3>Отчет по запросу: </h3>" '------- вывод набора записей в таблицу ------------If rs.EOF = True Then response.write "<br>Список пуст<br>" stop End If '--- Вывод таблицы в окно браузера ---rs.MoveFirst tt="<br><TABLE border=1><TR>" '--- Строка с заголовками столбцов -For Each el In rs.Fields tt = tt & "<TD><h4>" & el.Name & "</h4></TD>" Next tt=tt & "</TR>" '------- Вывод тела таблицы ------------Do Until rs.EOF tt=tt & "<TR>" '---- чтение элементов строки ----For Each el In rs.Fields tt = tt & "<TD>" & el.Value & "</TD>" Next '---- переход на седующую строку ---tt=tt & "</TR>" rs.MoveNext Loop '------------- конец формирования таблицы ----tt=tt & "</TABLE>" response.write tt %> <BODY> <HTML> 85 Вариант HTL-отчета, который получает клиент по посланному запросу, показан на рис.47. Таким образом, данный пример использования ASP-технологии демонстрирует широкие возможности применения SQL-запросов на стороне клиента для получения любых отчетов, которые предоставляются ему в HTML-формате. Рис.47. Вариант HTML-отчета, подготовленного на сервере по запросу от клиента. Задания для самостоятельной работы. 1. 86 Разработать диалоговую форму для доступа к локальной базе данных «Поликлиника», которая состоит из следующих трех таблиц: - таблица «Doctor», в которой хранится информация о докторах: код доктора, фамилия доктора, адрес, специальность, стаж работы; - таблица «Patient», в которой находится информация о пациентах: код пациента, 2. 3. Разработать SQL-запросы для создания таблиц базы данных, которая используется для мониторинга бюджетных показателей предприятий холдинга (таблицы : предприятие, подразделение, показатели, период времени). Создать локальное Web-приложение, которое позволяет получать запросы по SQL-запросам. Создать описание базы данных в СУБД Access и перенести это описание в другую СУБД (например, СУБД SQL Server 2000, используя для этого Query Analyzer). Разработать клиентскую диалоговую форму и ASP-файл для ее обработки. 87 Приложение 1. Описание учебной базы данных «Авто салон» (Avto.mdb) Для хранения данных о проданных автомобилях в салоне «МАРС» разработана база данных «Авто салон» (Avto.mdb). Для разработки использовалась СУБД Access. База данных состоит из 4-х таблиц: - Продавцы (Salespeople={snum, sname, saddress, comm., stel}); - Покупатели (Customers={onum,odate,amount,snum,cnum,pnum}); - Прайс (Price={cnum,cname,cadrdress,rating,ctel}); - Журнал для регистрации продаж (Orders ={pnum,peddim, price, pdate}). Замечание: Ключевые поля в таблицах выделены и подчеркнуты. Содержание данных в таблицах на начальном этапе обучения отражено в рис. 48- рис. 51. Учебную базу «Авто салон» (Avto.mdb) можно получить, послав запрос по почте gera01@yandex.ru Рис. 48. Данные в таблице Salespeople 88 Рис. 49. Данные в таблице Customers Рис. 50. Данные в таблице Price Рис. 51. Данные в таблице Orders 89 Приложение 2. Разработка VBA приложения для обработки SQLзапросов. Пример использования SQL-запросов приложениях: Вывод на лист Excel в клиентских результатов выполнения SQL- запросов к базе данных Northwind_Matr. 2.1. Создание нового Excel VBA проекта. Откроем новую книгу в Excel, войдем в режим VBA, подключим к проекту необходимые библиотеки [2]. Затем создадим в проекте новую форму (InserUserForm), присвоим ей имя FRM и изменим свойство Caption=Форма для выполнения SQL-запроса. Теперь на форме FRM разместим объекты: Textbox1 – «текстовый бокс» для ввода SQL-запросов, CommandButton1 – «кнопка» для запуска запроса на исполнение и ScrollBar1 – «полоса прокрутки» для прокрутки и просмотра запросов, а также несколько объектов типа Label – «меток» для вывода текстовых комментариев и сообщений. Вариант размещения объектов на форме FRM показан на рис.52 ниже. 90 Рис.52. Вариант форма для ввода и исполнения SQL-запроса 2.2. Подготовительные операции на листах книги. Выйдем из режима проекта VBA и вернемся листы книги Excel. Лист1 переименуем в «ПАРАМ», на котором разместим основные данные необходимые для организации связи с базой данной: - путь к папке, где находится база данных; - имя азы данных; - тип провайдера (поставщика данных). Пример таблицы с параметрами показан в Таблице 1 ниже. Из описания видно, что мы выбираем базу, созданную в СУБД Access, а в качестве провайдера используем драйвер фирмы MS - Microsoft.Jet.OLEDB.4.0. Таблица 1. Пример основных параметров для проекта (Лист «ПАРАМ») 91 Номер Название параметра Значение параметра D:\Хранилища данных\OLAP 1 Путь к базе технологии\Northwind\ 2 Название базы Northwind_Mart.mdb 3 Драйвер провайдера Microsoft.Jet.OLEDB.4.0 Теперь создадим место для хранения списка запросов. В нашем проекте их будет 10. Для этого Лист2 переименуем в «Запросы» и разместим на нем таблицу запросов, фрагмент которой показан в таблице2. Все запросы необходимо предварительно проверить с среде Access и текст SQL-запроса перенесем на лист «Запросы». Фрагмент таблицы запросов показан ниже: Таблица 2. Фрагмент таблицы запросв к базе данных Nothwind.mdb номер Запросы SQL-форма запроса SELECT Time_Dim.Month, Sum(Sales_Fact.LineltemTotal) AS [Sum-LineltemTotal] FROM Time_Dim INNER JOIN (Product_Dim INNER JOIN Sales_Fact ON Product_Dim.ProductKey = Sales_Fact.ProductKey) ON 1 92 Суммирование Time_Dim.TimeKey = продаж по Sales_Fact.TimeKey месецам WHERE (((Time_Dim.Year)=1997)) GROUP BY Time_Dim.Month SELECT Employee_Dim.EmployeeName, Sum(Sales_Fact.LineltemTotal) AS [Sum-LineltemTotal] FROM Time_Dim INNER JOIN (Employee_Dim INNER JOIN Sales_Fact ON Employee_Dim.EmployeeKey = Sales_Fact.EmployeeKey) ON Time_Dim.TimeKey = Sales_Fact.TimeKey WHERE (((Time_Dim.Year) = Суммирование продаж по 2 сотрудникам 1997)) GROUP BY Employee_Dim.EmployeeName; Просмот 3 таблицы Product SELECT * FROM PRODUCT_DIM Таблицу можно пополнять запросами или на странице «ПАРАМ» ввести дополнительный параметр «Имя рабочей таблице с запросами» и менять значение этого параметра. 93 2.3. Создание процедуры для связи с базой данной. Процедуру для связи с базой данных создадим в отдельном модуле (InsertModule) и назовем ее Main(). Эта процедура будет создавать объект ADO.Connection и формировать его основные параметры. Текст процедуры Main() и блок общих (Public) параметров приведен в скрипте ниже: Public obj As New ADODB.Connection '-------- Процедура для коннекта с базой данных -------Sub main() Dim intCtr As Integer '-1 ------- подготовка имени БД -----------------------PathDb = Sheets("ПАРАМ").Cells(2, 3).Value NameDb = Sheets("ПАРАМ").Cells(3, 3).Value NameProv = Sheets("ПАРАМ").Cells(4, 3).Value FullNameDb = PathDb & NameDb '2 ---------- открытие объекта базы данных ------------With obj '-- определение и открытие объекта --.Provider = NameProv .ConnectionString = FullNameDb .Mode = adModeShareDenyWrite .Open End With '3 ------------------------------------------------------frm.Label2.Caption = "Имя базы данных = " & FullNameDb End Sub Процедура Main() состоит из 3-х разделов: - 1-й раздел подготавливает переменные, которые содержат значения конкретных параметров. Значения находятся на листе «ПАРАМ»; 94 - 2-й раздел создает и открывает объект obj с заданными параметрами; - 3-й раздел выдает сообщение на форму в строку (метку) «сообщение». 2.4. Разработка процедуры чтения записей по SQL-запросу и вывода их на рабочий лист. Для удобства просмотра SQL-запроса перед его исполнением, удобно вывести его текст в текстовый бокс (Textdob1). Просмотр и листание запросов производится с помощью изменения свойств объекта «линейка прокрутки» (ScrollBar1). Тект процедуры показан ниже READ_SQL_QUERY(Nstr): Sub READ_SQL_QUERY(Nstr) RabTab = "Запросы" frm.TextBox1.Text = Sheets(RabTab).Cells(Nstr + 1, 3).Value frm.Label3.Caption = "Номер = " & Nstr End Sub Подключим данную процедуру к обработчику события «изменение положения курсора в полосе прокрутки»: Private Sub ScrollBar1_Change() Nstr = ScrollBar1.Value Call READ_SQL_QUERY(Nstr) End Sub Также свяжем эту процедуру с событием «инициализация формы» (событие UserForm_Initialize), как показано ниже: Private Sub UserForm_Initialize() 95 Call main Call READ_SQL_QUERY(1) End Sub Процедура Main() описании выше. Теперь можем запустить форму (нажав клавишу F5) и убедиться, что форма заполняется правильно и «прокрутка» работает нормально. Пример рабочего состояния формы показан на рис.53 Рис.53. Пример рабочего состояния формы FRM. 2.5. Процедура исполнения запроса Запуск SQL-запроса на исполнение осуществляется процедурой TABLE(), текст которой приведен ниже. Структура процедуры состоит из следующих разделов: 96 0 - подготовка переменных; 1 - создание источника данных; 2 - Подготовка текса SQL-запроса; 3 - Выполнение SQL-запроса и получение набора; 3 - Выполнение SQL-запроса и получение набора записей; 4- Вывод набора записей в таблицу на страницу рабочего листа; 4.1. - Проверка не пустой ли список строк; 4.2. - Вывод таблицы на лист; 4.3. -Вывод тела таблицы. Далее представлен текст процедуры TABLE(). Sub TABLE() ' ---------- объект для связи с базой ---------------------'Выволнение SQL запроса к базе данных на рабочий лист '0 ---------- подготовка переменны -----------------RabTab = "Лист2" NstrBeg = 1 ' номер начальной строки для вывода Call Clear_RabTab(RabTab) '---------------------------------------------------------'1- создание источника данных --' источник создан в Main() '2 ------- Подготовка текса SQL-запроса -----strSQL = frm.TextBox1.Value ' – Текст читается из формы If Trim(strSQL) = "" Then MsgBox "нет запроса" Exit Sub End If '3 ----- Выполнение SQL-запроса и получение набора записей ----Set rs = CreateObject("ADODB.Recordset") rs.Open strSQL, obj, adOpenDynamic, adLockPessimistic, adCmdTex '---------------------------------------------------------'4- Вывод набора записей в таблицу на страницу рабочего листа ---------97 '4.1. --- Проверка не пустой ли список строк ---If rs.EOF = True Then MsgBox "Список пуст" Exit Sub End If '4.2. --- Вывод таблицы на лист ---rs.MoveFirst Nstr = NstrBeg With Sheets(RabTab) '--- Строка с заголовками столбцов -ncol = 1 For Each el In rs.Fields rr = el.Name .Cells(Nstr, ncol).Value = rr ncol = ncol + 1 Next '4.3.---- Вывод тела таблицы ---Nstr = Nstr + 1 Do Until rs.EOF ncol = 1 '---- чтение элементов строки ----For Each el In rs.Fields rr = trans(el.Value) If IsNumeric(rr) = True And (ncol > 1) Then rr = rr * 1 .Cells(Nstr, ncol).Value = rr ncol = ncol + 1 Next '---- переход на следующую строку ---Nstr = Nstr + 1 rs.MoveNext Loop End With End Sub После ввода текста процедуры, необходимо привязать ее к событию Click на кнопке формы FRM как показано ниже: Private Sub CommandButton1_Click() Call TABLE 98 End Sub 2.5. Вспомогательные процедуры для запуска проекта в момент загрузки книги Excel. Для обеспечения автоматического запуска формы можно разработать следующие процедуры: Sub Auto_Open() frm.Show End Sub Этой процедуре можно присвоить «горячие клавиши» (например, Ctr+q) и затем можно будет выполнять ее в любой момент времени. 2.6. Процедура очистки рабочей таблицы перед заполнение данными. Эту процедуру можно предварительно сгенерировать в режиме «Атоматичекое создание макросов», а затем откорректировать текст так как необходимо для проекта. Sub Clear_RabTab(RabTab) ' Clear_RabTab Макрос ' Макрос записан 18.03.2006 (Nik) Sheets(RabTab).Select Cells.Select Selection.Delete Shift:=xlUp Range("A1").Select End Sub 99 2.7 Процедура Main() для коннекции с SQL Server. Для подключения к серверным базам данных необходимо указать не только провайдера, но сервер, где находится база данных. Лучше всего это сделать, используя DSN, которое описывается в администраторе ODBC. Создадим в ODBC DSN с именем LocalServer, с которым свяжем драйвер Microsoft OLE DB Provider for SQL Server и базу данных Northwind_Mart . Для реализации связи с сервером напишем процедуру Sub Main_SQL_Server() '-1 ------- подготовка имени БД -----------------------PathDb = Sheets("ПАРАМ").Cells(2, 3).Value NameDb = Sheets("ПАРАМ").Cells(3, 3).Value NameProv = Sheets("ПАРАМ").Cells(4, 3).Value FullNameDb = PathDb & NameDb '2 ---------- открытие объекта базы данных ------------conn = NameProv MsgBox "БД на SQL SERVER 2000" & Chr(10) & conn Set obj = CreateObject("ADODB.Connection") obj.Open conn '3 ---------- Вывод сообщения на форму ---------------------------frm.Label2.Caption = " Имя базы данных = " & FullNameDb End Sub 100 Литература. 1. Дженнингс Р. Руководство разработчика баз данных на Visual Basic –М., Изд. Дом «Вильямс», 1999, 976 с 2. ФедоровА., Елманова Н., Введение в OLAP-технологии Microsoft – «Диалог МИФИ», М., 2002, с 272 3. Герасимов Н.А., Практикум по разработке диалоговых приложений в среде VBA- РЭА им. Г.В. Плеханова, М.,2003 г. 59 с 4. Герасимов Н.А, Диалоговая система мониторинга бюджета Российской федерации - Тезисы докл. «Семнадцатые межд. плехановские чтения», РЭА им. Г.В.Плеханова, М., 2004 г., стр.263 5. Герасимов Н.А, Практикум по разработке диалоговых систем и баз данных в Web-среде - РЭА им. Г.В. Плеханова, М.,2005, 109 с. 6. Герасимов Н.А, Разработка диалоговых баз данных в среде VBA (учебно-методическое пособие) - Гос.ун-т – Высшая школа экономики. -М., 2005, 124 с 7. Дунаев В.В., Базы данных язык SQL для студента – «БХВПетербург», Санкт-Петербург, 2006, с. 279 101