
3)Запрос на обновление.
Этот запрос позволяет обновить значения в записях, которые соответствуют задаваемым условиям. Конструкция запроса следующая:
UPDATE “<файл с таблицей>”
SET <поле> = <значение>{, <поле> = <значение>}
[WHERE <условие отбора>]
Рассмотрим некоторые части запроса:
SET – зарезервированное слово, с которого начинается оператор, задающий список подставляемых значений;
<поле> = <значение>{, <поле> = <значение>} – список полей и значений, которые задаются этим полям;
[WHERE <условие отбора>] – оператор, задающий условие отбора тех записей, в которых следует обновить данные.
4)Запрос на удаление.
Этот запрос позволяет удалить из таблицы записи, удовлетворяющие заданным условиям. Конструкция запроса следующая:
DELETE FROM “<файл с таблицей>”
[WHERE <условие отбора>]
Пример № 2: Создание SQL-запроса.
Создадим несколько видов SQL-запросов в среде DataBase Desktop 7.0:
Откроем DBD 7.0 известным нам способом.
Создадим SQL-запрос для получения списка, отсортированного по алфавиту, фамилий людей, у которых есть рабочий телефон:
Создадим SQL-запрос командой меню File|New|SQL File.
Введем в появившемся окне текстового редактора следующий текст:
SELECT DISTINCT D.Family
FROM “<путь к файлу>\People.db” D, “<путь у файлу>\Tel.db” D1
WHERE
(D1.IDPeople = D.IDPeople) AND (D1.Type = “раб.”)
ORDER BY D.Family ASC
Выполним запрос командой SQL|Run SQL.
В появившемся окне Table::Priv:ANSWER.DB будет выведен результат выполнения запроса.
2.5. Сохраним запрос под именем Order командой File|Save As.
Создадим SQL-запрос для получения списка фамилий людей с указанием количества, имеющихся у них телефонов:
3.1.Создадим SQL-запрос командой меню File|New|SQL File.
Введем в появившемся окне текстового редактора следующий текст:
SELECT DISTINC D.Family, COUNT(D1.IDTel)
FROM “<путь к файлу>\People.db” D, “<путь к файлу>\Tel.db” D1
WHERE
(D1.IDPeople = D.IDPeople)
GROUP BY D.Family
Выполним запрос, и в появившемся окне будет выведен результат выполнения запроса.
Сохраним запрос под именем Group.
Добавим в таблицу People.db Коноплева Дмитрия Юрьевича:
4.1.Создадим SQL-запрос командой меню File|New|SQL File.
Введем в появившемся окне текстового редактора следующий текст:
INSERT
INTO “<путь к файлу>\People.db” (Family, Name, SecName)
VALUES (‘Коноплев’, ‘Дмитрий ’, ‘Юрьевич’)
Выполним запрос, и в появившемся окне будет выведен результат выполнения запроса.
Сохраним запрос под именем Inserted.
Изменим в таблице People.db имя Дмитрий на Генадий у всех людей, чья фамилия Коноплев:
5.1.Создадим SQL-запрос командой меню File|New|SQL File.
Введем в появившемся окне текстового редактора следующий текст:
DELETE
FROM “<путь к файлу>\People.db”
WHERE
(Family = ‘Коноплев’)
Выполним запрос, и в появившемся окне будет выведен результат выполнения запроса.
Сохраним запрос под именем Deleted.
Запрос к БД (Query):
Использование одной компоненты Table позволяет работать только с одной таблицей. Поэтому, когда необходимо работать с несколькими связанными таблицами, нужно создавать соответствующее число компонент Table. В этом случае целесообразно взять компоненту Query класса TQuery, являющегося потомком класса TDBDataSet. Эта компонента позволяет определить набор данных на основе нескольких таблиц с помощью SQL-запроса. Ее также удобно применять, когда таблица БД чрезмерно велика; в этом случае с помощью запроса можно ограничить набор рассматриваемых данных. Использование этой компоненты связано со знанием языка SQL.
Отметим сразу, что можно создать оператор Delphi SQL при помощи компоненты Query следующим образом:
Поместить на форму объекты Query, DataSource и связать их вместе.
Присвоить псевдоним свойству DataBaseName объекта TQuery.
С помощью свойства SQL ввести указание SQL.
Установить свойство Active в значение True. Если каждый шаг был завершен правильно и если BDE установлено корректно, сетка должна будет содержать записи из указанной таблицы.
Если работа идет с локальными данными, то можно подставить полностью определенный путь подкаталога для псевдонима. При использовании последнего метода лучшим будет не включать настоящее название таблицы, а включить только подкаталог, в котором содержится одна или несколько таблиц.
Delphi позволяет создавать SQL-запросы к БД как статические, в которых текст запроса остается неизменным, так и динамические (или запросы с параметрами). Динамические SQL-запросы содержат параметры, определенные в условиях отбора записей, которые в процессе выполнения программы могут изменяться. Таким образом, с помощью одного динамического запроса можно получать различные результаты при выполнении приложения. Синтаксическая конструкция динамических запросов аналогична статическим, за исключением того, что у них в секции, определяющей условия отбора записи, вместо значения записывается “:<параметр>”, где параметр – имя параметра, вместо которого при выполнении приложения будет подставляться значение.
У класса TQuery отметим следующие наиболее важные свойства, которые он добавляет к наследуемым от классов TDataSet, TBDEDataSet и TDBDataSet:
Local – определяет расположение таблиц (True – локальные таблицы, False – таблицы на SQL-сервере); свойство только для чтения.
RequestLive – свойство логического типа (по умолчанию имеет значение False), определяет возможность изменять набор данных, полученный в результате выполнения запроса. Эта возможность имеется, если свойство имеет значение True, и только у запросов, которые основаны на одной таблице и не используют сортировку и агрегатные функции. У остальных запросов результат доступен только для чтения независимо от значения данного свойства. В этих случаях можно посмотреть свойство CanModify для того, чтобы увидеть успешен ли запрос, если же нужно откорректировать таблицу с помощью запроса SQL, то следует использовать команду SQL Update.
SQL – свойство типа TStrings, определяет текст SQL-запроса, который используется при выполнении методов Open или ExecSQL.
UniDirectional – определяет направление перемещения курсора по набору данных, полученному в результате выполнения запроса.
UpdateMode – свойство типа TUpdateMode, определяет способ обновления записей из промежуточного буфера.
Следующие свойства компоненты TQuery используются в динамических SQL-запросах (приведем некоторые из них):
DataSource – свойство типа TDataSource, определяет источник данных, значения полей которого используются как параметры для динамического запроса.
Params[Index] – свойство типа TParams, задает список элементов типа TParams, которые определяют параметры в динамическом запросе. С помощью этого свойства в редакторе значений параметров задаются начальные величины параметров. Чтобы перейти к редактору значений параметров запроса, нужно активизировать мышью значение этого свойства.
Класс TQuery добавляет к наследуемым от классов TDataSet, TBDEDataSet и TDBDataSet следующие методы (некоторые из них):
ExecSQL – процедура выполняет SQL-запрос.
Prepare – процедура посылает запрос в BDE для проверки синтаксиса и оптимизации. Рекомендуется выполнять для динамических запросов.
События, которые обрабатываются компонентой TQuery, полностью наследуются от класса TDataSet.
При подстановке переменных связи в динамический запрос программным методом с помощью свойства Params выполняются обычно следующие шаги:
Необходимо убедиться в том, что таблица закрыта.
Подготавливается объект TQuery с помощью выдачи команды Prepare.
Свойству Params присваиваются корректные значения.
Открывается запрос.
Иногда требуется соединить данные из одной таблицы с данными из другой так, что результирующий набор данных содержит информацию из обеих таблиц. Операция слияния двух таблиц называется соединением и является одной из фундаментальных операций, которые выполняются на наборе двух или более таблиц. Отметим также, что имеется существенной отличие между связанными курсорами и соединенными таблицами, однако у них есть две общие вещи:
в них входят две или более таблиц;
каждая из таблиц связана с другой через поля совместного использования.
Операцию соединения таблиц можно выполнить с помощью одиночного оператора SQL, использование которого будет показано в следующем примере.
Пример № 3: Создание запроса для вывода записей, имеющих фамилию, начинающуюся с одной и той же буквы, из БД «Телефонная книжка».
Для работы с электронной телефонной книжкой, как с обычной, желательно иметь возможность просматривать абонентов только с фамилиями, начинающимися на одну букву. Для этого воспользуемся запросом с параметром:
Загрузим заготовку проекта, созданную в лабораторной работе № 2. Зададим свойству Caption формы значение «Информация о людях (запрос)». Сразу же сохраним все составные части проекта в файлах с теми же именами, что и прежние, но с добавлением цифры «5» в конце имени: MyExUnitDB5.pas, MyExUnitDMDB5.pas, MyExampleDB5.dpr.
В тексте модуля формы Form1 заменим раздел объявления используемых модулей в секции implementation
USES MyExUnitDMDB;
на раздел
USES MyExUnitDMDB5;
Перейдем к модулю DataModule1. Со страницы DataAccess поместим в окно модуля компоненту Query (Запрос), которая получит в тексте модуля имя Query1.
Выберем компоненту Query1, активизируем свойство SQL и в появившемся текстовом редакторе введем следующие строки, которые задают запрос на языке SQL:
SELECT D.*, D1.*
FROM “<путь к файлу>\People.db” D, “<путь к файлу>\Tel.db” D1
WHERE
(D.IDPeople = D1.IDPeople) AND (D.Family Like :FirstChar
Оператор Like позволяет отобрать записи, которые определяются параметром FirstChar в поле Family. Затем активизируем свойство Params и в появившемся окне редактора параметров запроса DataModule1.Query1 Parameters сделаем следующее. Выберем из списка Parameter Name (Название параметра) FirstChar, в строке ввода со списком DataType (тип данных) выберем String и в строке Value (Значение) введем А% - начальное значение. Завершим настройку нажатием кнопки ОК.
Установим у свойств Active и RequestLive компоненты Query1 значение True, используя инспектор объектов.
Со страницы DataAccess палитры компонент поместим в модуль DataModule1 еще одну компоненту DataSource. она получит в тексте модуля имя DataSource3. Активизируем ее и установим свойство DataSet в Query1.
Перейдем к форме Form1. Справа от компоненты DBGrid1 поместим со страницы Standart палитры компонент две компоненты Label. которые в тексте модуля получат имена Label6 и Label7 соответственно. Свойству Caption компоненты Label6 зададим значение «Постраничный», а свойству Caption компоненты Label7 – «просмотр :»
Ниже, под компонентами Label6 и Label7, поместим со страницы Standart кнопку Button, она получит в тексте модуля имя Button1. Изменим ее свойство Caption на «Просмотр». При нажатии на эту кнопку будет происходить переход на новую форму, на которой будет реализован постраничный просмотр БД «Телефонная книжка». Активизируем ее и в появившемся обработчике события OnClick введем следующее:
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Visible := True;
end;
Свойство Visible обеспечивает отображение формы на экране после своего создания.
Добавим в форму Form1 со страницы Additional палитры компонент компоненту Bevel, она получит в тексте модуля имя Bevel1. Поместим ее позади компонент Label6, Label7 и Button1. с помощью нее эта группа компонент будет выделяться на форме. Изменим ее свойство Style на bsRaised (она будет выпуклой).
Создадим теперь выше указанную форму. Для этого выполним следующие действия:
8.1. Добавим в проект форму командой главного меню File|New Form.
8.2. Изменим свойство Caption формы Form2 на «Постраничный просмотр» и сохраним форму под именем MyExUnitQuery.pas.
8.3. В верхний левый угол формы поместим компоненту ComboBox со страницы Standart палитры компонент, которая получит в тексте модуля имя ComboBox1. Изменим ее свойство Text на “A”. Затем активизируем свойство Items и в появившемся окне редактора введем на каждой строке последовательно по одной букве от «А» до «Я», за исключением, быть может, букв «Ь» и «Ъ». Завершим ввод нажатием кнопки ОК.
8.4. Со страницы Standart палитры компонент с помощью мыши поместим рядом с компонентой ComboBox1 компоненту Button, которая получит в тексте модуля название Button1. Изменим ее свойство Caption на «Страница». Затем активизируем кнопку и в появившемся обработчике события OnClick введем оператор, задающий отображение в форме результатов выполнения запроса в компоненте Query1. Обработчик будет иметь следующий вид:
procedure TForm2.Button1ClickSender: TObject);
begin
WITH DataModule1.Query1 DO
BEGIN
Close;
Prepare;
Params[0].AsString := ComboBox1.Text + ‘%’;
Open;
END;
end;
8.5. Поместим на форму Form2 еще одну компоненту Button, справа от компоненты Button1. Она получит в тексте модуля имя Button2. Изменим ее свойство Caption на «<Назад». При помощи этой кнопки мы сможем вернуться к форме Form1 во время работы приложения. Активизируем кнопку Button2 и в открывшемся обработчике события OnClick введем следующее:
procedure TForm2.Button2Click(Sender: TObject);
begin
Close;
end;
8.6. Ниже помещенных нами компонент разместим на всю оставшуюся часть формы компоненту DBGrid со страницы DataControls палитры компонент. При помощи редактора списка полей Editing DBGrid1.Columns определим поля, которые будут отображаться в таблице (эти действия были описаны в лаб./раб. №2): Family, Name, SecName, Number, Type; задавая при этом через сложное свойство Titel заголовки столбцов в DBGrid1: «Фамилия», «Имя, «Отчество», «Номер», «Тип» соответственно.
8.7. В тексте модуля Form2 в секции implementation напишем следующую строчку для связи данной формы с DataModule1:
USES MyExUnitDMDB5;
Перейдем снова к форме Form1. В тексте ее модуля установим связь с Form2, для чего в секции implementation допишем имеющуюся строчку следующим образом:
USES MyExUnitDMDB5, MyExUnitQuery;
Поместим в низ формы Form1, приблизительно в центр, еще одну кнопку Button, которая в тексте модуля будет иметь имя Button2. Изменим ее свойство Caption на «Выход» (выход из приложения). Активизируем ее и в обработчике события напишем:
procedure TForm1.Button2Click(Sender: TObject);
begin
Close;
end;
Запустим программу командой Run|Run. в результате появится окно, в котором при нажатии на кнопку «Просмотр» появиться еще одно окно, где, выбирая в выпадающем списке разные буквы и нажимая кнопку «Страница», можем видеть, как меняется набор отображаемых записей в таблице DBGrid в соответствии с первой буквой значения фамилии.
Завершим работу нажатием кнопки «Выход» в основном окне.
Сохраним все изменения в проекте.
При программном использовании TQuery следует сначала закрыть текущий запрос и удалить все строки, которые уже могут находиться в свойстве SQL:
Query1.Close;
Query1.SQL.Clear;
При этом всегда безопасно вызывать Close, т.к. если запрос уже закрыт, то это не вызовет никакой ошибки. Следующим шагом является добавление новых строк, которые необходимо выполнить, например,:
Query1.SQL.Add(‘Select * From People.db’);
Можно использовать свойство Add для добавления в запрос SQL от одной до x строк.
Для того, чтобы Delphi обработало операторы SQL и вернуло курсор с результатами запроса, требуется написать следующий оператор:
Query1.Open;
Если возвращать курсор не обязательно, то можно сделать вызов ExecSQL. Вызывать ExecSQL также требуется, если происходит вставка, исключение и корректировка данных, т.е. вместо строки Query1.Open нужно будет записать:
Query1.ExecSQL;
Query1.Refresh;
Отметим также, что операторы Select возвращают курсор и поэтому требуют вызова Open. Delete, Insert и Update не возвращают курсор и поэтому сопровождаются вызовом ExecSQL.
Если требуется составить серию операторов, то ускорить работу можно за счет использования динамических запросов.
Пример № 4: Создание запроса для ограничения числа отображаемых записей из БД «Телефонная книжка» (программный путь).
В телефонной книжке, как правило, располагается весьма много записей и просмотр всех их последовательно затруднителен. Рассмотрим простейшее разбиение таких записей на следующие две части: в первую войдут те, которые содержат фамилию, начинающуюся на буквы от «А» до «М», а во вторую – от «Н» до «Я», причем записи будут выводиться в алфавитном порядке. Будем использовать TQuery программно.
Загрузим заготовку проекта, созданную в предыдущем примере. Зададим свойству Caption формы Form1 значение «Информация о людях (запрос 2)». Сразу же сохраним все составные части проекта в файлах с теми же именами, что и прежние, но с добавлением цифры «6» в конце имени: MyExUnitDB6.pas, MyExUnitDMDB6.pas, MyExUnitQuery6.pas и MyExampleDB6.dpr. В тексте модуля формы Form1 заменим раздел объявления используемых модулей в секции implementation
USES MyExUnitDMDB5, MyExUnitQuery;
на раздел
USES MyExUnitDMDB6, MyExUnitQuery6;
А в тексте модуля формы Form2 заменим раздел объявления используемых модулей в секции implementation
USES MyExUnitDMDB5;
на раздел
USES MyExUnitDMDB6;
А ее свойство Caption изменим на «Ограниченный просмотр».
Изменим немного вид формы Form1: изменим свойство Caption у компоненты Label6 с «Постраничный» на «Ограниченный».
Перейдем к форме Form2. Удалим из нее две компоненты – ComboBox1 и Button1 (кнопка «Страница»).
На место удаленных компонент поместим со страницы Standart две компоненты Button, они получат в тексте модуля имена Button1 и Button3 соответственно, а у компоненты DBGrid1 свойство DataSource сделаем пустым, чтобы первоначально в ней не было никаких записей.
Выберем кнопку Button1 и изменим ее свойство Caption на «А – М». Активизируем ее и в появившемся обработчике события OnClick введем следующие строки:
procedure TForm2.Button1Click(Sender: TObject);
begin
WITH DataModule1.Query1 DO
BEGIN
Close;
SQL.Clear;
SQL.Add('SELECT D.*, D1.*');
SQL.Add('FROM "<путь к файлу>\People.db" D, "<путь к файлу>\Tel.db" D1');
SQL.Add('WHERE');
SQL.Add('(D1.IDPeople = D.IDPeople)AND(D.Family < "Н")');
SQL.Add('ORDER BY D.Family ASC');
Open;
END;
DataModule1.DataSource3.DataSet := DataModule1.Query1;
DBGrid1.DataSource := DataModule1.DataSource3;
end;
Выберем кнопку Button3 и изменим ее свойство Caption на «Н – Я». Активизируем ее и в появившемся обработчике события OnClick внесем следующее:
procedure TForm2.Button3Click(Sender: TObject);
begin
WITH DataModule1.Query1 DO
BEGIN
Close;
SQL.Clear;
SQL.Add('SELECT D.*, D1.*');
SQL.Add('FROM "<путь к файлу>\People.db" D, "<путь к файлу>\Tel.db" D1');
SQL.Add('WHERE');
SQL.Add('(D1.IDPeople = D.IDPeople)AND(D.Family >= "Н")');
SQL.Add('ORDER BY D.Family ASC');
Open;
END;
DataModule1.DataSource3.DataSet := DataModule1.Query1;
DBGrid1.DataSource := DataModule1.DataSource3;
end;
Запустим программу командой Run|Run.
Перейдем ко второй форме, нажав кнопку «Просмотр». Там, нажимая кнопки «А – М» и «Н – Я», можем видеть, как меняется набор отображаемых записей.
Завершим работу приложения.
Сохраним все изменения в проекте.