
- •Раздел 1. Проектирование баз данных. 2
- •Раздел 2. Разработка приложений для работы с Базами Данных в среде Delphi. 25
- •Раздел 1. Проектирование баз данных.
- •1.1. Основы построения баз данных. Модели данных.
- •1.1.1. Реляционная модель данных.
- •1.1.2. Нормализация базы данных.
- •1.2. Проектирование базы данных методом “сущность-связь”.
- •Раздел 2. Разработка приложений для работы с Базами Данных в среде Delphi.
- •2.1. Технология создания информационной системы.
- •2.1.1.Создание таблиц базы данных в Database Desktop.
- •2.1.2. Целостность базы данных.
- •Программа bde Administrator и модули данных.
- •Компоненты доступа и работы с данными. Тема: Наборы данных. Состояние и режимы наборов данных.
- •Тема: Объекты поля. Операции с полями.
- •Тема. Отображение и выбор значения поля.
- •Тема. Визуальные компоненты отображения записей из набора данных.
- •Закладки.
- •Тема. Ограничения на вводимые значения.
- •Тема. Сортировка набора данных.
- •Тема. Операции с таблицей базы данных.
- •Тема. Фильтрация записей.
- •Тема. Поиск записей.
- •Тема. Модификация набора данных.
- •Тема. Работа с отчетами
- •Отчет для связанных наборов данных
- •Составной отчет
- •Модули данных
- •Конструктор отчетов Rave Report
- •Реляционный способ доступа к данным.
- •Основные сведения о языке sql.
- •Оператор выбора Select.
- •Агрегирование и группирование записей.
- •Объединение таблиц.
- •Вложенные запросы.
- •Модификация записей.
- •Примеры баз данных
Тема. Фильтрация записей.
Фильтрация – это задание ограничений для записей, которые отбираются в набор данных. Система Delphi позволяет выполнить фильтрацию записей по выражению и по диапазону. Для реализации фильтрации по выражению используются следующие свойства компонента Table:
Filter: String; - определяет текущий фильтр (условие) для набора данных. Содержит определенные ограничения на значения полей.
При записи условий фильтрации можно использовать:
имена полей таблицы, кроме имен вычисляемых полей !!
литералы,
операции отношения =, >, >=, <, <=, <> ,
арифметические операции + - * /
логические операции and, or и not,
круглые скобки.
Например,
TbTovar.Filter:=’Cena<=1000 and Cena>100’;
DM2.TbTovar.Filter:='T_Nazv='+'''к*''';
или DM2.TbTovar.Filter:='T_Nazv='+#39+'к*'+#39;
TbSotruniki.Filter:='S_Birthday>'''+ DateToStr(StrToDate(Edit1.Text))+'''';
TbSotruniki.Filter:='S_Birthday>'''+ DateToStr(StrToDate('01.12.1981'))+'''';
Filtered: Boolean – определяет, будут ли доступны все записи набора данных (false) или только отфильтрованные (true).
Например,
{В поле Edit1 задается условие фильтрации, а по кнопке Button1 задается режим фильтрации}
procedure Tform1.Button1Click (Sender:TObject);
begin
Table1.Filter:=Edit1.Text;
Table1.Filtered:=True;
end;
Примеры выражения, формируемого в поле Edit1:
T_Kol_vo<21 AND T_Kol_vo>10
T_Nazv='с*'
P_Date>'31.12.2006' OR P_Kol_vo<50
FilterOptions: TFilterOptions - параметры фильтрации, свойство множественного типа и может принимать комбинации двух значений:
foCaseInsensitive – регистр букв не учитывается,
foNoPartialCompare – выполняется проверка на полное соответствие содержимого поля и значения, заданного для поиска. При выключенном значении для фильтра Tovar=’K*’ будут отобраны все записи, для которых в поле Tovar первым символом является символ K.
По умолчанию обе опции выключены.
Например, DM2.TbTovar.FilterOptions:=[foCaseInsensitive];
Пример. Формирование выражения из значений различных компонентов для текстового и числового поля:
Table1.Filter:=ComboBox1.Text+Edit1.Text+''''+Edit2.Text+'''';
где ComboBox1.Text- имя поля, Edit1.Text – отношение, Edit2.Text – значение.
Пример 1. Фильтрация по выражению в таблице Sotrudniki. (Alias:Sotrudniki)
-
procedure TForm1.FormCreate(Sender: TObject);
begin
TbSotrudniki.Filter:='';
TbSotrudniki.FilterOptions:=[foCaseInsensitive];
TbSotrudniki.Filtered:=true;
end;
-
procedure TForm1.btnFilterClick(Sender: TObject);
begin
// Фильтровать по дате рождения
if rbBirthday.Checked then TbSotrudniki.Filter:='S_Birthday>'''+
DateToStr(dtpbirthdaymin.Date)+''' AND S_Birthday<'''+
Datetostr(dtpbirthdaymax.Date)+'''';
// Фильтровать по выражению
if rbexpression.Checked then TbSotrudniki.Filter:=Edexpression.Text;
// Фильтрация отсутствует
if rbnofilter.Checked then begin
TbSotrudniki.Filter:='';
Edexpression.Text:='';
end;
end;
Фильтрация по диапазону. В набор данных включаются записи, значения которых попадают в заданный диапазон. Условием фильтрации является выражение вида:
значение>нижняя_граница AND значение<верхняя_граница
Фильтрация по диапазону ведется индексно-последовательным методом и применяется для индексированных полей. Индекс поля должен быть установлен текущим с помощью свойств IndexName или IndexFieldNames. Если текущий индекс не установлен, то по умолчанию используется главный индекс. Для реализации фильтрации по диапазону используются следующие свойства и методы набора данных Table.
Методы:
SetRangeStart – устанавливает нижнюю границу диапазона.
SetRangeEnd – устанавливает верхнюю границу диапазона.
ApplyRange – устанавливает фильтр, который ограничивает диапазон записей для просмотра с использованием индексированного поля.
Например,
// формирование списка записей, количество которых – двузначное число.
procedure TForm1.BtnFilterClick(Sender: TObject);
begin
TbTovar.IndexFieldNames:='Kol_vo';
TbTovar.SetRangeStart;
TbTovar.Fields[2].AsInteger:=10; // поле Kol_vo
TbTovar.SetRangeEnd;
TbTovar.Fields[2].AsInteger:=99;
TbTovar.ApplyRange;
end;
CancelRange – отменяет фильтрацию по диапазону, установленную методом ApplyRange.
Например,
// отмена фильтрации по диапазону
procedure TForm1.BtnAllRecordClick(Sender: TObject);
begin
TbTovar.CancelRange;
end;
Свойство:
KeyExclusive: Boolean – определяет как учитывается заданное граничное значение: если =true – записи, значения которых совпадают с границами диапазона не включаются в набор данных, если = false – то включаются. Свойство действует отдельно для верхней и нижней границ.
Например,
// установка верхней границы
TbTovar.IndexFieldNames:='Cena';
TbTovar.SetRangeEnd;
TbTovar.KeyExclusive: = true;
TbTovar.FieldByName (‘Cena’).AsFloat:=200;
Если одна из границ диапазона фильтрации не задана, то диапазон считается открытым.
Если фильтрация выполняется по нескольким полям, то после вызова методов SetRangeStart и SetRangeEnd должны быть записаны несколько операторов присваивания, каждый из которых задает границу по одному полю.
Метод
SetRange(const StartValues, EndValues: array of const) – устанавливает начальное и конечное значение ранга доступных записей. Параметр StartValues указывает значение поля, даваемое первой записи в ранге, параметр EndValues – последней записи в ранге. Выполняется назначение ранга набору данных. Отменяется такая фильтрация методом CancelRange.
Например,
procedure TForm1.BtnFilterClick(Sender: TObject);
begin
TbTovar.IndexFieldNames:='Tovar;Cena';
TbTovar.SetRange(['тетрадь',10],['тетрадь',100]);
end;
Для фильтрации по частичному совпадению значений символьных полей задаются начальные символы строки как нижняя граница, а как верхняя граница задается та же строка, дополненная символами ‘яяя’.
Например,
TbTovar.SetRange([‘т’], [‘т’+’яяя’]);
Фильтрация по событию OnFilteredRecord ??!!
Пример.
// фильтрация по ограничениям для значений двух полей
procedure TForm1.Button2Click(Sender: TObject);
begin
TbTovar.IndexFieldNames:='T_Nazv';
TbTovar.SetRangeStart;
TbTovarT_Nazv.AsString:=Edit1.Text;
TbTovar.SetRangeEnd;
TbTovarT_Nazv.AsString:=Edit3.Text;
TbTovar.ApplyRange;
TbTovar.IndexFieldNames:='T_Cena';
TbTovar.SetRangeStart;
TbTovarT_Cena.AsFloat:=strtofloat(Edit2.Text);
TbTovar.SetRangeEnd;
TbTovarT_Cena.AsFloat:=strtofloat(Edit4.Text);
TbTovar.ApplyRange;
end;
Пример-2. Фильтрация по диапазону по нескольким полям, одно из полей типа PickList.
procedure TForm1.FormCreate(Sender: TObject);
var i:integer;
begin
TbTovar.FilterOptions:=[foCaseInsensitive];
TbTovar.Filtered:=False;
// формирование списка ComboBox значений PickLista из поля Prim
for i:=0 to DBGTovar.Columns[4].PickList.Count-1 do
CmbPrim.Items.Add(DBGTovar.Columns[4].PickList.Strings[i]);
CmbPrim.Text:=CmbPrim.Items[0];
end;
procedure TForm1.BtnFilterClick(Sender: TObject);
begin
with TbTovar do
if (CmbPrim.Text<>'') and (EdMin_Tovar.Text<>'') and (EdMax_Tovar.Text<>'') then begin
IndexName:='ind_PrimTovar';
SetRangeStart; KeyExclusive:=False;
FieldByName('T_Prim').AsString:=CmbPrim.Text;
FieldByName('T_Nazv').AsString:=EdMin_Tovar.Text;
SetRangeEnd; KeyExclusive:=False;
FieldByName('T_Prim').AsString:=CmbPrim.Text;
FieldByName('T_Nazv').AsString:=EdMax_Tovar.Text;
ApplyRange
end
else ShowMessage('Заполните все поля фильтрации!');
end;
procedure TForm1.BtnAllClick(Sender: TObject);
begin
TbTovar.CancelRange;
end;
Пример-3. Фильтрация по полю подстановки для БД Pokupka.
procedure TForm1.FormCreate(Sender: TObject);
begin
// сортировка по наименованию товара
DM2.TbTovar.IndexName:='ind_tovar';
// формирование списка наименований товаров из таблицы Tovar
ComboBox1.Items.Clear;
DM2.TbTovar.First;
while not DM2.TbTovar.Eof do begin
ComboBox1.Items.Append(DM2.TbTovarT_Nazv.AsString);
DM2.TbTovar.Next;
end;
ComboBox1.Text:=ComboBox1.Items[0];
end;
procedure TForm1.BtnFilterClick(Sender: TObject);
var cod:integer;
s : string;
begin
if ComboBox1.Text<>'' then begin
s:=ComboBox1.Text; DM2.TbTovar.First;
while not DM2.TbTovar.Eof do begin
if DM2.TbTovarT_Nazv.AsString=s then
cod:=DM2.TbTovarT_Code.AsInteger;
DM2.TbTovar.Next;
end;
DM2.TbPokupka.IndexFieldNames:='P_Tovar';
DM2.TbPokupka.SetRange([cod],[cod]);
end
else ShowMessage('Выберите наименование товара!');
end;
procedure TForm1.BtnAllClick(Sender: TObject);
begin
DM2.TbPokupka.CancelRange;
DM2.TbPokupka.First;
end;
procedure TDM2.TbTovarAfterPost(DataSet: TDataSet);
begin
// сортировка по наименованию товара
DM2.TbTovar.IndexName:='ind_tovar';
// формирование списка наименований товаров из таблицы Tovar
Form1.ComboBox1.Items.Clear;
DM2.TbTovar.First;
while not DM2.TbTovar.Eof do begin
Form1.ComboBox1.Items.Add(DM2.TbTovarT_Nazv.AsString);
DM2.TbTovar.Next;
end;
Form1.ComboBox1.Text:=Form1.ComboBox1.Items[0];
end;
procedure TDM2.TbTovarAfterDelete(DataSet: TDataSet);
begin
TbTovarAfterPost(DataSet);
end;
Связанные таблицы.
Delphi позволяет создать приложение для двух таблиц, связанных между собой с помощью полей связи. Поля связи обязательно должны быть индексированными.
Таблицы связываются по принципу "главный-подчиненный" (один-ко-многим, один-к-одному, многие-ко-многим). При перемещении по записям главной таблицы будут автоматически доступны те записи подчиненных таблиц, у которых значения поля связи равно значению поля связи текущей записи главной таблицы. Такой отбор записей подчиненной таблицы подобен фильтрации.
Для установления связи между главной (Master) и подчиненной (Detail) таблицами используются следующие Свойства подчиненной таблицы (набор данных Table):
MasterSource: TDataSource; - имя компонента источника данных главной (родительской) таблицы для установления отношения между таблицами типа главная-подчиненная (родительская-дочерняя). Набор данных, который ассоциируется с указываемым источником данных, становится главной таблицей, а текущая таблица – подчиненной.
IndexName: String; - текущий индекс подчиненной таблицы.
IndexFieldNames: String; - поле или поля связи текущего индекса подчиненной таблицы.
MasterFields: String; - поле или поля из главной таблицы, которые служат для связи с соответствующими полями данной подчиненной таблицы. Поля в списке отделяются точкой с запятой. Двойным щелчком мышью в поле значения свойства MasterFields откроется диалоговое окно Field Link Designer. В этом окне нужно указать какое поле подчиненной (Detail) таблицы будет связано с полем главной (Master) таблицы. Указанное поле станет значением свойства MasterFields.
где:
Available Indexes – список индексов подчиненной таблицы,
Detail Fields – поля, входящие в выбранный индекс подчиненной таблицы,
Master Fields – поля главной таблицы,
Joined Fields – связь между полями двух таблиц.
При работе со связанными таблицами необходимо учитывать следующее:
при изменении (редактировании) поля связи записи главной таблицы нужно соответственно изменять значения поля связи всех подчиненных записей.
При удалении записи главной таблицы нужно удалять и соответствующие ей записи в подчиненной таблице (каскадное удаление).
При добавлении записи в подчиненную таблицу значение поля связи формируется автоматически по значению поля связи главной таблицы.
Пример. Работа со связанными таблицами Tovar и Prodaga.
(Листинг программы).
Между таблицами устанавливается связь "главный-подчиненный". Таблица Tovar – главная, таблица Prodaga – подчиненная. Для связи используются поля: T_Code (в главной таблице), P_Code (в подчиненной).
В верхней части главной формы приложения выводится информация о товарах, а в нижней части информация о продаже товара. При выборе в таблице Товары (Tovar) записи о товаре в таблице Продажа (Prodaga) автоматически отображаются только те записи, которые соответствуют продаже именно этого товара.
Модификация данных таблиц с помощью компонентов DBGrid запрещена. Добавление и удаление записей главной таблицы выполняется с помощью кнопок Добавить и Удалить.
При удалении записи с данными о товаре сначала удаляются все соответствующие записи подчиненной таблицы, а затем удаляется запись с данными о товаре в главной таблице.
Переключатель Показать все записи позволяет разорвать связь между таблицами. Сначала он выключен, и связь между таблицами существует.