
Полная версия:
Базы данных на Delphi 7

Сергей Талипов
Базы данных на Delphi 7
ЛЕКЦИЯ № 1
1. СОЗДАНИЕ ПО НА ОСНОВЕ БАЗ ДАННЫХ В DELPHI
Программирование баз данных – очень большой и серьезный раздел самого что ни на есть практического программирования, многие программисты большую часть своего времени тратят именно на проектирование баз данных и разработку приложений, работающих с ними. Это неудивительно – в настоящее время каждая государственная организация, каждая фирма или крупная корпорация имеют рабочие места с компьютерами. Имеется масса данных, которые нужно не только сохранить, но и обработать, получить комплексные отчеты. Без баз данных сегодня не обойтись. А завтра они будут еще нужней.
Недостаточно просто написать программу, взаимодействующую с БД. Нужно уметь правильно спроектировать эту базу данных. Проектирование баз данных, в общем, является первым шагом разработки приложения. Только когда база данных спроектирована, программист приступает непосредственно к проекту приложения.
При написании программ работы с базами данных (БД) на «Делфи» обычно используется метод доступа через BDE – систему. BDE – система представляет из себя набор драйверов, связывающих прикладную программу на «Делфи» с физическими файлами БД.

В «Делфи» понятие «таблица данных» и «база данных» различаются. Таблицей называется совокупность данных, нормализованных в табличную форму. Примером таблиц служат классические БД типа FoxPro и DBase. База данных – это файл, содержащий в себе несколько таблиц, которые имеют, как правило, внутренние взаимосвязи по ключевым полям. Базы данных используются в крупных промышленных СУБД типа «ORACLE» и других клиент – серверных системах.
Для ознакомления с программированием баз данных будем пользоваться таблицами типа DBase и FoxPro. Для начала любой работы с БД из под «Делфи» необходимо настроить BDE – систему. Для этого служит специальная программа «BDE Administrator». Для создания таблиц и наполнения их данными можно воспользоваться программой «DataBase Desktop» из установленного комплекта «Делфи».
2. ПРОСТЕЙШАЯ ПРОГРАММА
Для создания простейшей программы понадобится одна форма, не визуальные компоненты «DataSource» и «Table» из вкладки «Data Access», и визуальные компоненты «DBGrid» и «DBGrid» из вкладки «Data Controls». Расположите компоненты на форме как показано на рис.1.

Рис. 1
Не визуальный компонент «Table» предназначен для непосредственного доступа к таблице данных через BDE – систему. Визуальный компонент «DBGrid» служит для просмотра/редактирования записей в таблице данных, компонент «DBNavigator» служит для перемещения (навигации) по таблице данных. Не визуальный компонент «DataSource» служит посредником между компонентом «Table» и всеми визуальными компонентами.


Программная часть программы состоит из двух обработчиков событий «OnActivate» и «OnClose» для формы. Ниже приведен исходный текст данных обработчиков.
procedure TForm1.FormActivate(Sender: TObject);
begin
try { Установка защиты на операторы }
Table1.DatabaseName:='c:\uoo\dbf'; { Установка пути к таблице данных }
Table1.TableName:='u2_spec.dbf'; { Указание имени файла таблицы данных с расширением }
DataSource1.DataSet:=Table1; { Связуем компонент Table1 с компонентом DataSource1 }
DBGrid1.DataSource:=DataSource1; { Связуем компонент DBGrid1 с компонентом DataSource1 }
DBNavigator1.DataSource:=DataSource1; { Связуем компонент DBNavigator1 с компонентом DataSource1 }
if not Table1.active then Table1.Open; { Если таблица еще не открыта, то открыть ее }
except { Если произошла ошибка при открытии таблицы данных, то выдать сообщение }
showmessage('Error !');
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin { Если таблица данных открыта, то закрыть ее }
try if Table1.active then Table1.Close; except end;
end;
ЛЕКЦИЯ № 2
1. МЕТОДЫ И СВОЙСТВА КОМПОНЕНТ ДОСТУПА К ТАБЛИЦАМ ДАННЫХ
Компонент “TTable” служит для непосредственной связи с базой данных (таблицей). Данный компонент имеет ряд основных методов:
Open – открытие базы данных
Close – закрытие базы данных
Refresh (для BDE) / Requery (для ADO) – обновление базы данных с диска
Edit – перевод БД в режим редактирования текущей записи
Post – запоминание изменений для редактируемой текущей записи (вызывается после метода «Edit»)
Cancel – отмена изменений для редактируемой текущей записи (вызывается после метода «Edit», если нужно отменить изменения)
Insert – вставка новой пустой записи в БД
Append – добавление в конец новой пустой записи в БД
Delete – удаление текущей записи из БД
EmptyTable – удаление всех данных в таблице
DeleteTable – удаление БД с диска
First – переход на первую запись БД
Last – переход на последнюю запись БД
Next – переход на следующую запись БД
Prior – переход на предыдущую запись БД
MoveBy (-10) – переход на -10 записей БД (можно на любой целое число до начала или конца БД)
DisableControls – запретить отображение значений из БД во всех связанных с ней визуальных компонентах
EnableControls – разрешить отображение значений из БД во всех связанных с ней визуальных компонентах
Компонент “TTable” имеет ряд основных свойств:
Active – если «True», то база данных открыта
RecNo – выдает номер текущей записи БД
RecordCount – выдает количество записей в БД
FieldValues – доступ к значению поля БД
Modified – если «True», то текущая запись была изменена
Bof – если «True», то текущая запись – первая
Eof – если «True», то текущая запись – последняя
ЛЕКЦИЯ № 3
1. КОМПОНЕНТЫ ОТОБРАЖЕНИЯ ЗАПИСЕЙ БД
Компонент “DBEdit” служит для отображения и изменения значения одного конкретного поля текущей записи базы данных. Основные свойства этого компонента:
DataField := ‘CODE’; // Имя поля БД для отображения
DataSource := DataSource1; // Имя компонента типа “ DataSource” для связи с БД

Компонент “DBText” служит только для отображения значения одного конкретного поля текущей записи базы данных. Основные свойства этого компонента:
DataField := ‘CODE’; // Имя поля БД для отображения
DataSource := DataSource1; // Имя компонента типа “ DataSource” для связи с БД

Компонент “DBMemo” служит для отображения значения одного конкретного memo-поля для текущей записи БД. . Основные свойства этого компонента:
DataField := ‘CODE’; // Имя поля БД для отображения
DataSource := DataSource1; // Имя компонента типа “ DataSource” для связи с БД

Компонент “DBImage” служит для отображения значения одного конкретного Image-поля для текущей записи БД. Компонент поддерживает только «bmp» формат. Основные свойства компонент:
DataField := ‘CODE’; // Имя поля БД для отображения
DataSource := DataSource1; // Имя компонента типа “ DataSource” для связи с БД
Для “DBImage”:
Stretch := true; // Включение режима масштабирования рисунка

procedure TForm1.N1Click(Sender: TObject);
{ Скопировать картинку из таблицы данных в буфер обмена }
begin
DBImage1.CopyToClipboard;
end;
procedure TForm1.N2Click(Sender: TObject);
{ Вставить картинку из буфера обмена в поле таблицы данных }
begin
DBImage1.PasteFromClipboard;
end;
procedure TForm1.N3Click(Sender: TObject);
{ Загрузить картинку из файла в таблицу данных }
begin
if opendialog1.Execute=true then begin
try ADOTable1.edit; except end;
DBImage1.Picture.LoadFromFile(OpenDialog1.FileName);
try ADOTable1.post; except end;
end;
end;
procedure TForm1.N4Click(Sender: TObject);
{ Сохранить картинку из таблицы данных в файл }
begin
if savedialog1.Execute=true then
DBImage1.Picture.SaveToFile(SaveDialog1.FileName);
end;
procedure TForm1.Button3Click(Sender: TObject);
{ Удаление картинки из базы }
begin
try ADOTable1.Edit;
ADOTable1['Oblochka']:=null;
ADOTable1.Post; except end;
end;
Компонент “DBLookupComboBox” служит для выбора конкретной записи БД по значению из конкретного поля базы данных. Данный компонент представляет собой выпадающий список с перечнем значений поля БД для всех записей:
KeyField := ‘CODE’; // Имя поля БД для отображения

ListSource := DataSource1; // Имя компонента типа “ DataSource” для связи с БД
Компонент “DBLookupListBox” служит для выбора конкретной записи БД по значению из конкретного поля базы данных. Данный компонент представляет собой прокручиваемый список с перечнем значений поля БД для всех записей:
KeyField := ‘CODE’; // Имя поля БД для отображения

ListSource := DataSource1; // Имя компонента типа “ DataSource” для связи с БД
Компонент “DBGrid” служит для отображения значения всех записей и полей БД. Основные свойства этого компонента:
DataSource := DataSource1; // Имя компонента типа “ DataSource” для связи с БД

2. ПРИМЕР ИСПОЛЬЗОВАНИЯ МЕТОДОВ И СВОЙСТВ КОМПОНЕНТА «TTABLE»
procedure TForm1.Button1Click(Sender: TObject);
begin
Table1.Append;
Table1.FieldValues['Name'] := Edit1.text;
Table1. ['Year'] := StrToInt(Edit2.text);
Table1.Post;
end;
* * * *
Table1.Edit;
Table1.FieldByName(‘Name’).AsString := ‘Fred’;
Table1.Post;
* * * *
Table1.Insert;
Table1['Name'] := 'Russia';
Table1['Sity'] := 'Moscow';
Table1.Post;
* * * *
if MessageDlg('Сохраннить запись?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then Table1.Post else Table1.Cancel;
* * * *
procedure TForm1.Button1Click(Sender: TObject);
var i: integer; k: real;
begin
k:=0;
with ProgressBar1 do begin
Min := 0; Max := Table1.RecordCount;
Table1.First;
for i := Min to Max do begin
Position := i; s:=s+ Table1[‘sum’];
Table1.Next;
end;
end;
end;
* * * *
with Table1 do begin
DisableControls;
try
First;
while not EOF do Delete;
finally
EnableControls;
end;
end;
ЛЕКЦИЯ № 4
1. СОЗДАНИЕ ПОЛЕЙ ВЫБОРА И ВЫЧИСЛЯЕМЫХ ПОЛЕЙ
Поля выбора «Lookup» используются для создания виртуальных полей, данные в которых пользователь не набирает вручную, а выбирает из выпадающего списка. После выбора значения из списка оно отображается на экране, а в файл БД записывается код выбранного значения из выпадающего списка в соответствующее поле БД. Выпадающий список формируется из каких либо двух полей другой таблицы. Одно поле другой таблицы хранит код записи, а другое соответствующий текст, который появляется в выпадающем списке. Lookup-поля используются для подключения к основной таблице вспомогательных таблиц-справочников БД. Рассмотрим применение полей выбора на примере.
Например, имеется следующие таблицы:
Таблица 1. Диски – CD (Table_CD)
Код дискаНазвание дискаКод фирмы(Name_CD)(Kod_Firm)0000001Итнернет – 2001000010000002Суперсистемный диск 2k2000020000003English Platinum (2)000030000004All stars disco 2000040000005Золотая бухгалтерия 200100002Таблица 2. Фирмы – поставщики (Table_Firm)
Код фирмы (Kod_Firm)Название фирмы (Name_Firm)00001Красные Челны00002Технопром00003CD-маркер00004МегаполисДанные таблицы имеют общее поле «Код фирмы». Необходимо сделать так, чтобы при просмотре первой таблицы вместо кодов фирм выходило соответствующее название фирмы. Для этого необходимо в первой таблице поле «код фирмы» сделать невидимым для визуальных компонент, и добавить к таблице «Lookup»-поле. Данное поле просмотра будет смотреть код фирмы в первой таблице у каждой записи, находить соответствующую запись с данным кодом во второй таблице, брать из второй таблицы соответствующее коду название фирмы и подставлять его в качестве своего значения. В результате первая таблица будет отображаться следующим образом:
Таблица 1. Диски – CD (Table_CD)
Код дискаНазвание дискаФирма (Loolup-поле)(Name_CD)(nFirm)0000001Итнернет – 2001Красные Челны0000002Суперсистемный диск 2k2Технопром0000003English Platinum (2)CD-маркер0000004All stars disco 2Мегаполис0000005Золотая бухгалтерия 2001ТехнопромЕсли при просмотре таблицы 1 мы поменяем для первой записи значение фирмы «Красные челны» на «Технопром» (через выпадающий список), то в поле «Код фирмы» таблицы 1 запишется значение «00002», взятое из таблицы 2. Таким образом, поля просмотра позволяют хранить в базе данных только нужные коды, а их текстовые значения брать из другой базы данных и подставлять для просмотра и выбора.
Для создания поля выбора необходимо иметь два компонента «Table», один для основной базы, другой – как справочник с расшифровкой поля. Пусть таблица «Table_CD» будет соответствовать таблице 1, а второй компонент «Table_Firm» будет соответствовать таблице 2. Таблица «Table_CD» будет иметь поля «Kod», «Name_CD» и «Kod_firm», а таблица 2 «Table_Firm» будет иметь поля «Kod_firm» и «Name_firm».
Настроим у обоих компонент «Table» путь к БД и имена таблиц. Откроем базу данных «Table_CD», установив свойству «Active» значение «True». После этого щелкнем на компоненте «Table_CD» правой кнопкой мыши. В появившемся меню выберем опцию «Fields Editor». Откроется окно редактора полей. В редакторе полей нажмите правую кнопку мыши и выберите пункт «Add all fields». После этой команды в редакторе полей появится список из имеющихся полей в базе данным, например, поля «Kod», «Name_CD» и «Kod_firm». Эти три поля являются физическими полями, хранящимися в файле базы данных.
Если для компонента «Table» не указаны явно поля через редактор полей, то база данных будет также работоспособна, как и с указанием полей. Отличие заключается лишь в том, что нельзя создавать поля выбора и вычисляемые поля без явного указания всех имеющихся физических полей в редакторе полей.
Создадим дополнительное «Lookup» поле выбора «nFirm» у компонента «Table_CD». Для этого в редакторе полей нужно щелкнуть правой кнопкой мыши и выбрать пункт «New Field». Откроется окно создания нового поля. Зададим параметру «Name» имя создаваемого «lookup» поля, – «nFirm». Тип поля зададим в параметре «Type». Выберем денежный тип «String» с размером «Size» равным 20 символам. После этого укажем в разделе «Field type» значение «Lookup». Это означает, что создаваемое поле будет полем выбора. Далее зададим в параметре «KeyFields» значение «Kod_firm». Это поле таблицы «Table_CD», в котором хранится код фирмы. Далее зададим параметр «Dataset» равным «Table_Firm». Этим параметром указывается имя подчиненной таблицы с расшифровкой кодов фирм. В параметре «Lookup Keys» зададим значение «Kod_firm». Это значение является именем поля таблицы «Table_Firm» с кодами фирм. В параметре «Result Field» укажем имя «Name_firm». Это значение является именем поля таблицы «Table_firm» с названием фирмы. Нажмем теперь на кнопку «Ok». Поле просмотра создано.
После создания поля просмотра в таблице «Table_CD» поле «Kod_firm» можно сделать невидимым в компонентах просмотра БД, т.к. теперь это поле более наглядно отображает и позволяет изменять значение созданное поле просмотра с именем «nFirm».
В программе Lookup-поля просмотра можно использовать только для чтения. Присваивать значение или изменять их в программе нельзя.
Схема создания Lookup-поля:
Table1 -> Active -> Fields Editor -> Add All Fields -> New Field:
Name: nFirm, Field Type: Lookup, Type: String, Size: 20
Key Fields: ‘Kod_Firm’ (поле Table1),
DataSet: ‘Table_Firm’ (ссылка на Table2),
Lookup Keys: ‘Kod_Firm’ (поле Table2), Result Field: ‘Name_Firm’(поле Table2)
2. СОЗДАНИЕ ВЫЧИСЛЯЕМЫХ ПОЛЕЙ У КОМПОНЕНТА «TABLE»
Вычисляемые поля – это виртуальные поля, которые формируются динамически в процессе выполнения программы. В базе данных вычисляемые поля не сохраняются. Вычисляемое поле формирует для каждой записи базы данных значение, получаемое по какой-либо формуле из значений других полей для той же самой записи. Например, имеется БД с полем «Количество товара» и полем «Цена товара». Необходимо определить стоимость каждого товара. Для определения стоимости нужно для каждой записи находить произведение значений из поля «Количество товара» и поля «Цена товара». Введение вычисляемого поля в компонент «Table» позволяет автоматизировать эту задачу: у каждой записи появится новое поле, содержащее готовое произведение цены товара на его количества. Рассмотрим на примере как это сделать.
Нанесем на форму компонент «Table». Настроим у него путь к БД и имя таблицы. Откроем базу данных, установив свойству «Active» значение «True». После этого щелкнем на компоненте «Table» правой кнопкой мыши. В появившемся меню выберем опцию «Fields Editor». Откроется окно редактора полей. В редакторе полей нажмите правую кнопку мыши и выберите пункт «Add all fields». После этой команды в редакторе полей появится список из имеющихся полей в базе данных, скажем, поля «Cena» и «Kolichestvo». Эти два поля являются физическими полями, хранящимися в файле базы данных.
Создадим дополнительное вычисляемое поле «Summ» у компонента «Table». Для этого в редакторе полей нужно щелкнуть правой кнопкой мыши и выбрать пункт «New Field». Откроется окно создания нового поля. Зададим параметру «Name» имя создаваемого вычисляемого поля, – «Summ». Тип поля зададим в параметре «Type». Выберем денежный тип «Currency». После этого укажем в разделе «Field type» значение «Calculated». Это означает, что создаваемое поле будет вычисляемого вида. Нажмем теперь на кнопку «Ok». Вычисляемое поле создано. Данное поле имеет имя «Summ», а полное имя будет «Table1Summ». Полное имя поля можно посмотреть, выбрав в редакторе полей нужное поле и посмотреть его свойство «Name» в инспекторе объектов.
После создания вычисляемого поля необходимо описать алгоритм его формирования. Для этого нужно в Инспекторе Объектов найти событие «OnCalcFields» для компонента «Table» (в котором создано вычисляемое поле) и создать для данного события обработчик (обработчик создается двойным щелчком по белому пространству, напротив от названия события).
В созданной пустой процедуре-обработчике вычисляемых полей компонента «Table» напишем следующую строку:
Table1Summ . Ascurrency := Table1Cena . Ascurrency * Table1Kolichestvo . Ascurrency;
В обработчике вычисляемых полей можно обращаться к полям только текущей записи, причем поля должны быть записаны в полной форме, т.е. нужно писать не «Summ», а «Table1Summ». После имени поля через точку указывается его тип. Команды перемещения по записям в БД, удаления записей, вставки и др. команды не допустимы в обработчике вычисляемых полей.
В основное программе вычисляемые поля можно использовать только для чтения. Присваивать значение или изменять его в основной программе нельзя. Все операции по корректировки вычисляемых полей должны производится в обработчике «OnCalcFields» компонента «Table».
Если в компоненте «Table» создано несколько вычисляемых полей, то все их алгоритмы формирования описываются в одном и том же обработчике события «OnCalcFields», например:
procedure TForm1.Table1CalcFields(DataSet: TDataSet);
begin
Table1Summ . Ascurrency := Table1Cena . Ascurrency * Table1Kolichestvo . Ascurrency;
Table1Summ2 . Ascurrency := (Table1Cena . Ascurrency * Table1Kolichestvo . Ascurrency) – Table1Nalog . Ascurrency;
end;
Схема создания вычисляемого поля:
Table1 -> Active -> Fields Editor -> Add All Fields -> New Field:
Name: Summ, Field Type: Calculated, Type: Currency
ЛЕКЦИЯ № 5
1. ФИЛЬТРАЦИЯ И ПОИСК ЗАПИСЕЙ В ТАБЛИЦАХ ДАННЫХ
Фильтрация записей в базе данных позволяет временно делать невидимыми записи, которые не удовлетворяют заданному условию. При включении режима фильтрации база данных будет состоять только из записей, соответствующих заданному условию, это отразится на всех командах поиска, просмотра и перемещения, хотя физически база данных не изменяется на диске.
Для включения режима фильтрации необходимо установить в «True» значение свойства «Filtered» у компонента «Table». Значение «False» свойства «Filtered» выключает режим фильтрации базы данных. Перед включением режима фильтрации необходимо указать условие («фильтр») для отбора записей. Для установки фильтра служит свойства «Filter».
Фильтр может содержать символ «*», означающий любое количество любых символов. Кроме этого в фильтре допускаются операторы «AND» и «OR».
Свойство «FilterOptions» служит для установки параметров фильтрации. Значение «foCaseInsensitive » служит для выключения (true=буквы без различия регистра, false=буквы с различием регистра) различия регистра букв, а значение «foNoPartialCompare» служит для включения режима, при котором символ «*» в фильтре является просто символом «*», а не любым количеством любых символов (false=* знак замены, true=* просто символ). По умолчанию данные параметры не установлены: регистр букв различается и * – знак подстановки.
Рассмотрим примеры фильтрации данных:
// Различение режима букв, * – шаблон
Table1.Open;
Table1.Filtered:=false;
Table1.Filter:=’name=’’Сер*’’’;
Table1.FilterOptions:=[];
Table1.Filtered:=true;
for i:=1 to Table1.recordcount do begin
…
end;
* * * * * * *
// Регистр не различается, * – шаблон
Table1.Filtered:=false;
Table1.Filter:=’((name=’’Сер*’’) and (Fam=’’T_л*’’)) or (Fam=’’К*)’;
Table1.FilterOptions:=[foCaseInsensitive];
Table1.Filtered:=true;
* * * * * * *
// Регистр различается, * – символ
Table1.Filtered:=false;
Table1.Filter:=’corporation=’’*TSN*’’’;
Table1.FilterOptions:=[foNoPartialCompare];
Table1.Filtered:=true;
2. ФИЛЬТРАЦИЯ ЗАПИСЕЙ ДЛЯ КОМПОНЕНТА «ADOTABLE»
Для включения режима фильтрации необходимо установить в «True» значение свойства «Filtered» у компонента «AdoTable». Значение «False» свойства «Filtered» выключает режим фильтрации базы данных. Перед включением режима фильтрации необходимо указать условие («фильтр») для отбора записей. Для установки фильтра служит свойства «Filter».
Фильтр может содержать символ «%», означающий любое количество любых символов. Кроме этого в фильтре допускаются операторы «AND» и «OR» и оператор «LIKE».
AdoTable1.Filtered:=false;
AdoTable1.Filter:=’name like ’’Сер%’’’;
AdoTable1.Filtered:=true;
for i:=1 to AdoTable1.recordcount do …