Процессор баз данных Borland Database Engine


Любое приложение баз данных имеет в своем составе или использует сторонний механизм доступа к данным, который берет на себя подавляющее большинство стандартных низкоуровневых операций работы с базами данных. Например, любое такое приложение при открытии таблицы БД должно выполнить примерно одинаковый набор операций.

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

Очевидно, что если все стандартные функции доступа к данным реализовать в виде специальной программы, сервиса или динамической библиотеки, то это существенно упростит разработку приложений баз данных, которым для выполнения той или иной операции достаточно будет вызвать готовую процедуру.
Одним из традиционных способов взаимодействия приложения, созданного в среде разработки Delphi, и базы данных является использование процессора баз данных Borland Database Engine 5. Он представляет собой набор динамических библиотек, функции которых позволяют не только обращаться к данным, но и эффективно управлять ими на стороне приложения.
Для работы с источниками данных при посредстве BDE в Delphi имеется специальный набор компонентов, расположенных на странице BDE Палитры компонентов. Эти компоненты для работы с базами данных используют возможности BDE, обращаясь к его функциям и процедурам. Механизм доступа к BDE инкапсулирован в базовом классе TBDEDataSet. (Подробно базовые классы компонентов доступа к данным рассмотрены далее в этой части.) Поэтому в процессе программирования у вас не будет необходимости использовать функции BDE напрямую. Почти все, что можно сделать путем прямого обращения, можно сделать и через компоненты — это проще и надежнее.
Тем не менее внутреннюю организацию механизма доступа к данным всегда полезно знать. Кроме этого, всегда полезно знать и уметь использовать дополнительные возможности, которые BDE может предоставить разработчику.
BDE взаимодействует с базами данных при посредстве драйверов. Для особенно распространенных локальных СУБД разработан набор стандартных драйверов. Работа с наиболее распространенными серверами БД осуществляется при помощи драйверов системы SQL Links. Кроме этого, если для базы данных существует драйвер ODBC, то можно использовать и его. Достаточно зарегистрировать этот драйвер в BDE.
Однако BDE не претендует на всеобъемлющую универсальность и имеет некоторые недостатки. Это, например, снижение скорости работы приложения, недостатки реализации некоторых драйверов и т. д. В документации к Delphi 7 содержится предупреждение, что после 2002 года фирма Borland перестанет поддерживать BDE и рекомендует использовать технологию dbExpress, которая также рассматривается в настоящей книге.
В этой главе обсуждаются следующие вопросы.

  •  архитектура и составные части BDE;
  •  что такое псевдонимы БД и настройка драйверов BDE;
  •  использование утилиты BDE Administrator;
  •  способы прямого использования функций API BDE;
  •  компоненты доступа к данным BDE.

 

Архитектура и функции BDE


BDE представляет собой набор динамических библиотек, которые "умеют" передавать запросы на получение или модификацию данных из приложения в нужную базу данных и возвращать результат обработки. В процессе работы библиотеки используют вспомогательные файлы языковой поддержки и информацию о настройках среды.
В составе BDE поставляются стандартные драйверы, обеспечивающие доступ к СУБД Paradox, dBASE, FoxPro и текстовым файлам. Локальные драйверы (1) устанавливаются автоматически совместно с ядром процессора. Один из них можно выбрать в качестве стандартного драйвера, который имеет дополнительные настройки, влияющие на функционирование процессора БД.
Доступ к данным серверов SQL обеспечивает отдельная система драйверов — SQL Links. С их помощью в Delphi можно без особых проблем разрабатывать приложения для серверов Oracle 8, Informix, Sybase, DB2 и, естественно, InterBase. Эти драйверы необходимо устанавливать дополнительно.
Помимо этого, в BDE имеется очень простой механизм подключения любых драйверов ODBC (к примеру, Microsoft Access) и создания на их основе сокетов ODBC.
Примечание 
С точки зрения пользователя процесс подключения локального драйвера и драйвера SQL Links практически не отличается, за исключением деталей настройки. Настройка драйверов и собственных параметров BDE осуществляется при помощи специальной утилиты — BDE Administrator и рассматривается далее в этой главе.
В состав BDE входят следующие функциональные подсистемы.

  •  Администратор системных ресурсов управляет процессом подключения к данным — при необходимости устанавливает нужные драйверы, а при завершении работы автоматически освобождает занятые ресурсы. Поэтому BDE всегда использует ровно столько ресурсов, сколько необходимо.
  •  Система обработки запросов обеспечивает выполнение запросов SQL или QBE от приложения к любым базам данных, для которых установлен драйвер, даже если сама СУБД не поддерживает прямое использование запросов SQL.
  •  Система сортировки является запатентованной технологией и обеспечивает очень быстрый поиск по запросам SQL и через стандартные драйверы аля Paradox и dBASE.
  •  Система пакетной обработки представляет собой механизм преобразования данных из одного формата в другой при выполнении операций над целыми таблицами. Эта система использована в качестве основы для компонента TBatcMove и утилиты DataPump (автоматического переноса структур данных между базами данных), входящей в стандартную поставку BDE.
  •  Менеджер буфера управляет единой для всех драйверов буферной областью памяти, которую одновременно могут использовать несколько драйверов. Это позволяет существенно экономить системные ресурсы.
  •  Менеджер памяти взаимодействует с ОС и обеспечивает эффективное использование выделяемой памяти. Ускоряет работу драйверов, которые для получения небольших фрагментов памяти обращаются к нему, а не к ОС. Дело в том, что менеджер памяти выделяет большие объемы оперативной памяти и затем распределяет ее небольшими кусками между драйверами согласно их потребностям.
  • Транслятор данных обеспечивает преобразование форматов данных для различных типов БД.
  •  Кэш BLOB используется для ускорения работы с данными в формате BLOB.
  •  SQL-генератор транслирует запросы в формате QBE в запросы SQL.
  •  Система реструктуризации обеспечивает преобразование наборов данных в таблицы Paradox или dBASE.
  •  Система поддержки драйверов SQL повышает эффективность механизма поиска при выполнении запросов SQL.
  •  Таблицы в памяти. Этот механизм позволяет создавать таблицы непосредственно в оперативной памяти. Используется для ускорения обработки больших массивов данных, сортировки, преобразования форматов данных.
  •  Связанные курсоры обеспечивают низкоуровневое выполнение межтабличных соединений. Позволяют разработчику не задумываться над реализацией подобных связей при работе на уровне VCL — для этого достаточно установить значения нескольких свойств.
  •  Менеджер конфигурации обеспечивает разработчику доступ к информации о конфигурации драйверов.

Перечисленные функции реализованы в динамических библиотеках, которые, собственно, и называются процессором БД (табл. 16.1).
Таблица 16.1. Ядро процессора баз данных ВОЕ 5

Кроме этого имеется шесть дополнительных DLL, обеспечивающих работу BDE с серверами Oracle и Microsoft SQL Server.
Псевдонимы баз данных и настройка ВDЕ
Для успешного доступа к данным приложение и BDE должны обладать информацией о местоположении файлов требуемой базы данных. Задание маршрута входит в обязанности разработчика.
Самый простой способ заключается в явном задании полного пути к каталогу, в котором хранятся файлы БД. Но в случае изменения пути, что случается не так уж редко, например, при переносе готового приложения на компьютер заказчика, разработчик должен перекомпилировать проект с учетом будущего местонахождения БД или предусмотреть специальные элементы управления, в которых можно задать путь к БД.
Для решения такого рода проблем разработчик может использовать псевдоним базы данных, который представляет собой именованную структуру, содержащую путь к файлам БД и некоторые дополнительные параметры. В первом приближении можно сказать, что вы просто присваиваете маршруту произвольное имя, которое используется в приложении. Тогда при переносе приложения на компьютере заказчика достаточно создать стандартными средствами BDE одноименный псевдоним и настроить его на нужный каталог. При этом само приложение не требует переделок, т. к. оно обращается к псевдониму с одним именем, а вот BDE уже "знает" куда отправить запрос приложения, использовавшего этот псевдоним.
Помимо маршрута к файлам базы данных, псевдоним BDE обязательно содержит информацию о драйвере БД, который используется для доступа к данным. Наличие других параметров зависит от типа драйвера, а значит, от типа СУБД.
Для управления псевдонимами баз данных, настройки стандартных и дополнительных драйверов в составе BDE имеется специальная утилита — BDE Administrator (исполняемый файл BDEADMIN.EXE). Стандартная конфигурация BDE сохраняется в файле IDAPI.CFG. При необходимости текущую конфигурацию можно сохранить в новом файле с расширением cfg или загрузить заново при помощи команд Save As Configuration и Open Configuration из меню Object.
В верхней части окна утилиты расположена Панель инструментов, кнопки которой используются при работе с конкретным элементом настройки BDE. Рабочая область утилиты BDE Administrator представляет собой двухстраничный блокнот.
Страница Databases (2) содержит иерархическое дерево, в узлах которого расположены установленные в системе на данный момент псевдонимы БД. При выборе какого-либо псевдонима в правой части панели появляется путь к файлам базы данных и перечень параметров драйвера, соответствующего псевдониму, которые можно настраивать вручную.
Страница Configuration (3) используется для настройки параметров драйверов BDE, предназначенных для обеспечения доступа к локальным СУБД и серверам БД. Также здесь определяется системная конфигурация BDE, которая включает параметры числовых форматов, форматов даты и времени. Вся информация на этой странице также структурирована в виде иерархического дерева.
При выборе в левой части панели утилиты какого-либо узла, в правой части на странице Definition отображается вся необходимая информация для этого объекта.
Сохранение изменений осуществляется при помощи команд меню Object, всплывающего меню или при перемещении на другой псевдоним.
Для создания нового псевдонима требуется выбрать команду New из меню Object или из всплывающего меню узла Databases на одноименной странице. Затем в появившемся простом диалоге задается необходимый драйвер.
Отметим, что один из четырех стандартных локальных драйверов устанавливается на странице Configuration в качестве предопределенного, поэтому в списке он доступен под названием STANDARD, а остальные не видны вообще. Из драйверов SQL Links доступны те, которые были установлены при инсталляции Delphi или позже.
Кроме того, в списке можно выбрать один из драйверов ODBC, установка которых осуществляется стандартными системными средствами на Панели управления Windows.
После выбора драйвера в дереве псевдонимов БД появляется новый узел, для драйвера которого требуется установить необходимые параметры (см. ниже).
Для четырех локальных драйверов список параметров в правой части панели утилиты на странице Definition ограничивается параметрами стандартного драйвера (STANDARD), подробная настройка для каждого драйвера осуществляется на странице Configuration.
Назначение параметров локальных драйверов BDE (Paradox, dBASE, FoxPro, ASCII) представлено в табл. 16.2.
Таблица 16.2. Параметры драйверов BDE для локальных баз данных

Примечание 
Драйвер текстовых файлов ASCIIDRV имеет параметры стандартного драйвера.
Назначение параметров драйверов SQL Links для серверов SQL представлено в табл. 16.3. Сначала приведены параметры, которые встречаются в двух и более драйверах, затем уникальные для каждого драйвера параметры. Драйверы для серверов InterBase и Sybase не представлены, т. к. содержат только общие для двух серверов параметры.
Таблица 16.3. Параметры драйверов ВОЕ для серверов SQL

После настройки параметров драйвера и сохранения текущей конфигурации новый псевдоним становится доступен для любого приложения, использующего BDE.
Страница Configuration, помимо настройки установленных в BDE драйверов, позволяет редактировать параметры, используемые BDE при инициализации приложения. Эти параметры доступны при выборе узлов System, a затем INIT иерархического дерева. Назначение параметров представлено в табл. 16.4.
Таблица 16.4. Параметры инициализации приложения

Также на странице Configuration устанавливаются параметры форматов даты, времени и чисел. Доступ к параметрам осуществляется через узлы System и Format.
Интерфейс прикладного программирования ВDЕ
Как уже говорилось выше, любое приложение Delphi, работающее с базами данных и написанное с использованием стандартных компонентов доступа к данным, обращается к данным и получает результат при помощи BDE. При этом механизм доступа к данным использует вызовы функций из API BDE.
Достаточно сложно представить себе такую ситуацию, когда возникает необходимость создания приложения, использующего только функции BDE, без применения компонентов доступа к данным VCL. А вот отдельные функции вполне могут понадобиться в любой программе. Поэтому рассмотрим процесс работы приложения, использующего вызовы BDE, т. к. это дает хорошую возможность понять механизм доступа к данным, который реализован в Delphi.
Итак, для создания приложения на основе вызовов функций BDE необходимо выполнить следующие операции:
1. Инициализация BDE (функция DbiInit).
2. Открытие объекта базы данных (функция DbiOpenDatabase).
3. Определение рабочего каталога (функция obiSetDirectory), если на предыдущем этапе не задается псевдоним БД.
4. Определение временного каталога (функция DbiSetPrivateoir).
5. Открытие набора данных и создание курсора (функции DbOреnТаblе, DbiQExec и пр.; дескриптор курсора hDBICur).
6. Заполнение структуры cuRProps, содержащей данные о курсоре и наборе данных (функция DbiGetCursorProps).
7. Выделение памяти для буфера записи.
8. Навигация набору данных (функции DbiSetToBegin, DbiSetToEnd, DbiSetToCursor и пр.)
9. Чтение необходимой записи (функции DbiGetRelativeRecord,  DbiGetNextRecord, DbiGetRecord, DbiGetPriorRecord и др.).
10. Чтение или обновление необходимого поля (функции DMGetFieid, DbiPutField).
11. Освобождение всех ресурсов (освобождение буфера записи, закрытие курсора, таблицы, BDE).
При использовании в программе функций из API BDE необходимо включить в секцию uses модуль BDE.
В прикладном программировании задачи, которые требовали бы выполнения всех описанных выше операций, практически не встречаются. Между тем, включение в программный код отдельных функций API BDE оправдано. В качестве примера рассмотрим приложение, которое позволяет очистить таблицу базы данных (4).
Дело в том, что при удалении записи из таблицы локальной СУБД (например Paradox) размер файла таблицы остается прежним, даже если удалить все записи. То есть на самом деле запись не удаляется, а только становится недоступной. При интенсивном использовании базы данных файлы таблиц могут занимать значительные объемы дискового пространства при довольно умеренном числе записей.
Полная очистка таблиц базы данных осуществляется функцией DbiErr.ptyTable из API BDE. Именно она используется в демонстрационном приложении для радикального уменьшения размера таблиц.
Примечание 
Функция DbiEmptyTable используется в методе EmptyTable компонентов доступа к данным (см. гл. 17).
В листинге 16.1 приведен исходный код этого приложения. Помимо указанной функции, в нем используются функции создания списка параметров доступных баз данных и таблиц текущей базы данных.
 Листинг 16.1. Модуль главной формы приложения BDEEmptyTable 
unit Main; 
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
StdCtrls, BDE, ExtCtrls, DBCtrls, Grids, DBGrids, Db, DBTables, Buttons;
type
TMainForm = class(TForm)
AliasesList: TComboBox;
TablesList: TComboBox;
EmptyBtn: TBitBtn;
Labell: TLabel;
Label2: TLabel;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure AliasesListChange(Sender: TObject);
procedure EmptyBtnClick(Sender: TObject); private
hDB: hDBIDB;
hCursor: hDBICur;
DBDesc: DBDesc;
TblDesc : TBLBaseDesc;
 public
{ Public declarations } 
end;
var
MainForm: TMainForm;
implementation 
{$R *.DFM}
procedure TMainForm.FormShow(Sender: TObject); 
var Rslt: DBIResult;
 begin
AliasesList.Items.Clear;
 TablesList.Items.Clear; hDB := Nil; 
try
DbiInit(Nil); // Инициалы BDE
 BDE DbiOpenDatabaseList(hCursor) ;
 repeat
Rslt:= DbiGetNextRecord(hCursor, dbiNOLOCK, @DBDesc, nil) ;
 if (Rslt 0 DBIERR_EOF) then
AliasesList.Items.Add(StrPas(DBDesc.szName));
 until (rslt <> DBIERR_NONE); DbiCloseCursor(hCursor) ;
 except
on E:EDBEngineError do ShowMessage ('OiiMSKa MHMunajiM3auMM BDE');
end; 
end;
procedure TMainForm.FormClose(Sender: TObject;
 var Action: TCloseAction); 
begin
 try
finally
if hDB <> Nil then DbiCloseDatabase(hDB);// Закрытие базы данных
 DbiExit; // Закрытие сеанса работы с ВОЕ 
end
 end;
procedure TMainForm.AliasesListChange(Sender: TObject); 
begin
 try
if hDB <> Nil
then DbiCloseDatabase(hDB);// Закрытие базы данных 
DbiOpenDatabase // Открытие базы данных 
(
PChar(AliasesList.Text), // Псевдоним базы данных 
Nil, // Тип базы данных 
dbiReadWrite, // Режим редактирования данных
 dbiOpenShared, // Режим разделения данных
 Nil, // Пароль
0, // Число дополнительных параметров 
Nil, // Перечень полей для доп. параметров Nil, 
// Список доп. параметров hDB 
// Дескриптор базы данных 
);
DbiSetPrivateDir('с:\temp');// Определение временного каталога
DbiOpenTableList(hDb, False, False, '*.DB', hCursor);
TablesList.Items.Clear;
TablesList.Clear;
while DbiGetNextRecord(hCursor, dbiNOLOCK, @TblDesc, nil) = dbiErr_None
do TablesList.Items.Add(TblDesc.szName);
 DbiCloseCursor(hCursor);
 except
on E:EDBEngineError do ShowMessage('Ошибка открытия базы данных');
 end;
 end;
procedure TMainForm.EmptyBtnClick(Sender: TObject); 
begin
try
DbiEmptyTable(hDB, Nil, PChar(TablesList.Text), '');
except
on E:EDBEngineError do ShowMessage('Неверно задана таблица'}; 
end; 
end;
end.
При открытии главной формы (метод-обработчик FormShow) функция Dbiinit осуществляет инициализацию BDE. Затем функция DbiOpenDatabaseList создает в памяти временную таблицу, в которую записываются характеристики каждой зарегистрированной базы данных. Для этого применяется структура DBDesc. Курсор hcursor обеспечивает доступ к записям о базах данных.
После этого функция DbiGetNextRecord позволяет осуществить последовательное считывание имен псевдонимов баз данных (для этого в параметре передается указатель на структуру DBDesс) и их запись в список компонента AliasesList типа TComboBox.
При выборе из этого списка конкретного псевдонима работает метод-обработчик AliasesListchange. В нем открывается соответствующая база данных (функция DbiOpenDatabase), доступ к которой в дальнейшем осуществляется через дескриптор hDB.
Функция DbiopenTableList создает временную таблицу в памяти, в которую помещаются данные о таблицах выбранной базы данных в соответствии с форматом структуры TBLBaseDesс. Функция DbiGetNextRecord позволяет передать эту информацию в список компонента TablesList типа TCombоВох.
При щелчке на кнопке EmptyBtn в методе-обработчике EmptyBtndick работает функция DbiEmptyTabie, которая очищает выбранную ранее в компоненте TablesList таблицу.
Теперь рассмотрим пример простейшего приложения, которое может отображать два поля из таблицы COUNTRY. DВ в демонстрационной базе данных DBDEMOS. Эта база данных поставляется в комплекте Delphi. В примере использованы только функции API BDE.
Проект называется DirectBDE и имеет только одну форму, в которой отображаются сведения из таблицы COUNTRY. DB о государствах и их столицах (5). Кнопки в нижней части формы позволяют перемещаться по набору данных.
 Листинг 16.2. Модуль главной формы приложения DirectBDE 
unit Unitl; 
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, Buttons, BDE, ExtCtrls;
type
TMainForm = class(TForm)
PriorBtn: TBitBtn;
Panel2: ТPanel;:
NextBtn: TBitBtn;
Label3: ТLabel;
CountryEdit: TEdit;
Label1: TLabel;
CapitalEdit: TEdit;
procedure PriorBtnClick(Sender: TObject);
procedure FormShow(Sender: TObject};

procedure FormClose(Sender: TObject;
 var Action: TCloseAction);
procedure NextBtnClick(Sender: TObject); 
private
hDB: hDBIDB;
hCur: hDBICur;
CursProps: CurProps;
RecBuf: pByte;
FValue: array [0 .. 255] of Char;
IsEmpty: Bool;
procedure OnBDEError;
 public
 end;
var
MainForm: TMainForm;
implementation ($R *.DFM}
procedure TMainForm.OnBDEError;
var ErrInfo: dbiErrlnfo; // Структура, содержащая информацию об ошибках
AStr: String; 
begin
DbiGetErrorlnfo(True, Errlnfo);// Функция возвращает информацию об ошибке c
ase Errlnfo.iError of
9733: AStr := 'Для создания записи недостаточно параметров'; 
10024: AStr := 'Ошибка доступа к данным'; 
10245: AStr := 'База данных занята другим пользователем';
 10038: AStr := 'Значение поля задано неверно';
11871: AStr := 'Несоответствие типов';
11959: AStr := 'В выражении отсутствует оператор GROUP BY';
 else
AStr := 'Ошибочная операция с данными'; 
end;
ShowMessage(AStr) ; 
end;
procedure TMainForm.FormShow(Sender: TObject);
 begin
hDB := Nil; hCur := Nil;
Dbilnit(Nil); // Инициализация системы 
BDE DbiOpenDatabase // Открытие базы данных 
(
'DBDEMOS', // Псевдоним базы данных
Nil, // Тип базы данных
dbiReadWrite, // Режим редактирования данных
dbiOpenShared, // Режим разделения данных
Nil, // Пароль
0, // Число дополнительных параметров
Nil, // Перечень полей для доп. параметров
Nil, // Список доп. параметров
hDB // Дескриптор базы данных
);
DbiSetPrivateDir('с:\temp'); // Определение временного каталога
DbiOpenTable // Открытие таблицы
(
hDB, // Дескриптор базы данных 
PChar('COUNTRY'), // Название таблицы
PChar(szParadox), // Тип таблицы (только для локальных БД)
 Nil, // Название индекса (необязательный)
 Nil, // IndexTagName — только для dBASE 
0, // 0 — использовать первичный индекс 
dbiReadWrite, // Режим редактирования данных
 dbiOpenShared, // Режим разделения данных
 xltField, // Режим трансляции данных
False, // Признак одностороннего перемещения курсора
 Nil, // Дополнительные параметры
 hCur // Дескриптор курсора таблицы );
DbiGetCursorProps // Определение параметров курсора 

hCur, // Дескриптор курсора таблицы
CursProps // Структура параметров курсора
 );
GetMem // Вьщеление памяти под буфер записи 
(
RecBuf,
CursProps.iRecbufSize*SizeOf(Byte) );
DbiSetToBegin(hCur); // Установка курсора в начало набора данных
 DbiGetNextRecord // Перемещение на первую запись
 (
hCur, // Дескриптор курсора таблицы 
dbiNoLock, // Режим ограничения доступа
 RecBuf, // Буфер записи 
Nil // Параметры записи );
DbiGetField // Получение значения поля
 (
hCur, // Дескриптор курсора таблицы 
1, // Номер поля в структуре таблицы 
RecBuf, // Буфер записи
@FValue, // Переменная, в которую передается значение
 IsEmpty // Признак пустой ячейки );
MainForm.CountryEdit.Text := FValue;
 DbiGetField(hCur, 2, RecBuf, @FValue, IsEmpty);
 MainForm.CapitalEdit.Text := FValue;
 end;
procedure TMainForm.FormClose(Sender: TObject; 
var Action: TCloseAction);
 begin try
finally
FreeMem(RecBuf); // Освобождение памяти буфера записи DbiCloseCursor(hCur); // Закрытие курсора 
DbiCloseDatabase(hDB); // Закрытие базы данных
 DbiExit; // Закрытие сеанса работы с ВОЕ
end 
end;
procedure TMainForm.PriorBtnClick(Sender: TObject);
begin
try
if DbiGetPriorRecord(hCur, dbiNoLock, RecBuf, Nil) = DBIERR_BOF
then PriorBtn.Enabled := False
else 
begin
if Not NextBtn.Enabled then NextBtn.Enabled := True;
 DbiGetField{hCur, 1, RecBuf, SFValue, IsEmpty); 
MainForm.CountryEdit.Text := FValue;
 DbiGetField(hCur, 2, RecBuf, @FValue, IsEmpty);
 MainForm.CapitalEdit.Text := FValue; 
end; 
except
OnBDEError; 
end;
 end;
procedure TMainForm.NextBtnClick(Sender: TObject);
 begin 
try
if DbiGetNextRecord(hCur, dbiNoLock, RecBuf, Nil)=DBIERR_EOF
 then NextBtn.Enabled := False
 else
begin
if Not PriorBtn.Enabled then PriorBtn.Enabled := True;
 DbiGetFieldfhCur, 1, RecBuf, @FValue, IsEmpty); 
MainForm.CountryEdit.Text := FValue;
DbiGetField(hCur, 2, RecBuf, @FValue, IsEmpty);
 MainForm.CapitalEdit.Text := FValue;
 end; 
except
OnBDEError; 
end;
 end;
end.
При показе главной формы приложения в процедуре Formshow проводится инициализация BDE, открытие базы данных и таблицы. При этом создаются дескрипторы базы данных hDB и курсора таблицы hour, которые играют в дальнейшей работе приложения важную роль. Если при создании базы данных не указывать псевдоним БД, то обязательно нужно определить рабочий каталог базы данных с помощью функции DbiSetoirectory.
После этого отводится память под буфер записи, в который будут передаваться значения полей текущей строки таблицы. Размер буфера определяется при помощи Структуры CURPropS.
Затем курсор устанавливается на начало набора данных и на первую запись и осуществляется чтение значений двух полей таблицы.
Навигация по набору данных реализована в методах-обработчиках на нажатие кнопок формы. Их действие аналогично за исключением направления перемещения. При щелчке на кнопке выполняется переход на следующую или предыдущую запись, данные из новой записи помещаются в буфер записи RecBuf. Оттуда при помощи функции DMGetFieid осуществляется чтение значений полей. При достижении начала или конца набора данных кнопка деактивируется.
При закрытии формы проводятся операции по освобождению памяти буфера записи, закрытию базы данных и BDE.
 
Соединение с источником данных
Все обращения из приложения к таблицам одной базы данных осуществляются через одно соединение, на которое замыкаются все компоненты доступа к данным, имеющие соответствующие значения свойства DatabaseName (см. ниже).
Все управление одиночным соединением с какой-либо базой данных в BDE осуществляется компонентом TDatabase (табл. 16.5). В процессе работы компонент активно использует параметры псевдонимов и драйверов BDE.
Таблица 16.5. Свойства и методы компонента TDatabase

Обычно компонент TDatabase размешается в модуле данных приложения.
Для определения базы данных (сервера), с которой приложение устанавливает соединение при помощи компонента TDatabase, чаще используется свойство AliasName. Свойства DatabaseName и DriverName предоставляют альтернативный способ создания соединения.
Если соединение задано свойством AliasName,то свойство DatabaseName
можно использовать для создания временного псевдонима, который будет доступен только для компонентов доступа к данным внутри приложения. При щелчке на кнопке списка доступных псевдонимов свойства DatabaseName в Инспекторе объектов для любого компонента доступа к данным в списке будет доступен и временный псевдоним компонента TDatabase.
Например, при переключении приложения на другую базу данных можно изменить только значение псевдонима в компоненте TDatabase. Если все компоненты наборов данных подключены к временному псевдониму компонента TDatabase, то они автоматически переключатся на новую БД.
Дополнительные возможности управления наборами данных при переключении соединения предоставляют свойства Connected и KeepConnection. Они позволяют одновременно с соединением закрыть все активные наборы данных.
Если наборы данных приложения подключены к базе данных через компонент TDatabase, то перед их открытием необходимо установить соединение с БД. Соединение с БД устанавливается при помощи метода open. Если попытаться активизировать набор данных без этого метода, то соединение будет установлено автоматически.
Аналогичная картина возникает при закрытии наборов данных и отключении от БД. Дополнительное средство управления в этом случае предоставляет свойство KeepConnection. Если оно равно значению True, то при закрытии последнего открытого набора данных соединение остается открытым. В противном случае соединение автоматически закрывается.
Это позволяет управлять соединением в различных исходных ситуациях. При большой загруженности сервера бывает необходимо прерывать соединение каждый раз. Если требуется разгрузить сетевой график, то соединение лучше оставлять включенным.
При подключении к базе данных довольно часто требуется задать значения для параметров драйвера BDE. Для этого используется свойство Params, представляющее собой обычный список. В нем необходимо задавать названия изменяемых параметров и их новые значения:
USERNAME=SYSDBA 
PASSWORD=masterkey
Значения параметров можно задавать как статически, так и динамически во время выполнения.
Компонент TDatabase может облегчить подключение к базам данных с регистрацией пользователей. При регистрации на сервере достаточно задать имя пользователя, пароль в свойстве Params (см. выше) и установить для свойства LoginPrompt значение False. Эта комбинация работает как во время выполнения, так и во время разработки.
Примечание
Для организации доступа к защищенным паролем таблицам Paradox используется метод AddPassword компонента TSession (см. выше).
Дополнительные возможности обработки регистрации пользователя дает единственный метод-обработчик onLogin, программный код которого выполняется вместо появления стандартного диалога ввода имени и пароля. Это позволяет разработчику создавать собственные сценарии регистрации пользователей.
Для обеспечения доступа к функциям API BDE используется свойство Handle (BDE играет важную роль при создании соединения).
Управление выполнением транзакций осуществляется при помощи методов StartTransaction, Commit и RollBack.
 
Компоненты доступа к данным
Компоненты доступа к данным, используемые при разработке приложений BDE, располагаются на странице BDE Палитры компонентов. Их общими предками являются классы TBDEDataSet и TDBDataSet (см. 1). Они обеспечивают работоспособность основных компонентов доступа к данным BDE — TTable, TQuery, TStoredProc.
Класс TBDEDataSet
Этот класс является потомком класса TDataSet, его значение трудно переоценить: именно TBDEDataSet обеспечивает работоспособность важнейших механизмов набора данных за счет обращения к функциям BDE (табл. 16.6). Например, класс TBDEDataSet перекрывает абстрактные методы своего предка TDataSet, отвечающие за такие важнейшие операции, как чтение данных и сохранение изменений в базе данных, навигация по записям набора данных, фильтрация.
Напомним, что все эти механизмы не созданы "с нуля", а только дополнены обращениями к функциям BDE в необходимых местах методов, изначально описанных в классе TDataSet. Например, для обеспечения фильтрации записей набора данных к классу добавлено новое свойство:
type
TFilterOption = (foCaselnsensitive, foNoPartialCompare);
TFilterOptions = set of TFilterOption;
property FilterOptions: TFilterOptions;
Оно определяет дополнительные параметры отбора записей по фильтру (чувствительность к регистру символов и отбор по текстовому шаблону).
Дополнительно к существующим добавлен механизм кэширования изменений. Теперь все вносимые пользователем изменения могут накапливаться в специальном буфере, а их передачей в базу данных можно управлять.
 Примечание
Эта возможность очень полезна при создании клиентских приложений в архитектуре клиент/сервер и играет ключевую роль при обеспечении возможности редактирования наборов данных сложных запросов SQL.
Дополнительно к методам работы с полями класса TDataSet добавлены функции использования полей в формате BLOB.
Для обеспечения использования функций API BDE на программном уровне добавлено свойство, содержащее дескриптор курсора, соответствующего текущей записи набора данных:
type HDBICur: Longint; 
property Handle: HDBICur;
Также класс обеспечивает возможность программного управления вторичными индексами набора данных в зависимости от типа таблицы базы данных.
Таблица 16.6. Свойства и методы класса TBDEDataSet

 
Класс TDBDataSet
Класс TDBDataSet является непосредственным предком основных компонентов доступа к данным ттаblе, TQuery и TstoredProc. Новые свойства и методы класса обеспечивают соединение набора данных с базой данных и используют функции BDE (табл. 16.7).
В процессе соединения важнейшую роль играет свойство DatabaseName, которое должно содержать псевдоним или полный путь к файлам БД. Для управления отдельным соединением с базой данных можно применять специальный компонент TDatabase. Указатель на экземпляр такого компонента содержится в свойстве Database.
Многие функции API BDE используют в своей работе дескриптор специальной структуры, описывающей подключенную базу данных. Доступ к этому дескриптору можно получить через свойство DBHandie.
Приложение баз данных одновременно может использовать несколько наборов данных, каждый из которых подключен к собственной базе данных. Совокупность соединений управляется в рамках сеанса работы, который инкапсулируется компонентом TSession. Указатель на экземпляр такого компонента можно использовать в наборе данных при помощи свойства DBSession.
Для работы с удаленными серверами в класс введено свойство Provider, обеспечивающее доступ к интерфейсу iProvider.
Таблица 16.7. Свойства и методы класса TDBDataSet

Компонент TTable


Компонент Tтаblе инкапсулирует таблицу реляционной базы данных, причем независимо от типа базы данных. Для доступа к данным компонент использует функции BDE (см. выше).
Необходимая для работы база данных задается свойством DatabaseName, в котором можно указать зарегистрированный в BDE псевдоним БД или полный путь к файлам БД.
Таблица БД, на основе которой создается набор данных, определяется свойством TableName. При необходимости тип таблицы задается свойством TаblеТуре, хотя обычно это свойство имеет значение ttDefault (см. табл. 16.4), которое включает автоматическое определение типа таблицы по расширению файла.
 Примечание 
Свойство ТаblеТуре работает только в локальных БД. Обратите внимание, что возможные значения свойства соответствуют основным типам локальных драйверов BDE.
При помощи методов Open и close набор данных открывается и закрывается. О его состоянии можно судить по значению свойства Active. Более подробно о состоянии набора данных расскажет свойство state (см. ниже).
Записи в набор данных можно отбирать при помощи свойств Filter, Filtered, FilterOptions, создающих фильтр, ограничивающий набор данных по значениям данных в одном или нескольких полях.
Методы SetRangeStart, SetRangeEnd, SetRange, ApplyRange, EditRangeStart, EditRangeEnd создают специальный диапазон включаемых в набор данных записей, отбор в диапазон проводится по задаваемым граничным значениям любых полей набора данных.
Поиск нужной записи можно осуществлять методами Lookup или Locate (достаточно просто, но не очень быстро) или, используя существующие в таблице базы данных индексы, методом FindKey (сложнее, но очень быстро).
От предков компонент унаследовал инструменты для работы с закладками. Это свойство Bookmark и методы GetBookmark, FreeBookmark, GotoBookmark.
Работа с полями осуществляется целой группой свойств и методов, среди которых особое место занимает свойство Fields, представляющее собой индексированный список всех полей набора данных. Это свойство удобно использовать в процессе разработки для организации доступа к полям.
Использование индексов обеспечено свойствами indexName, indexFieids, IndexFieldNames, IndexFiles.
Свойства MasterSource, MasterField, IndexName дают возможность установить отношение типа главный/подчиненный с другой таблицей.
Очень полезны в практическом использовании методы и свойства для работы С буфером изменений (свойства CachedUpdates, PendingUpdates, UpdateRecordTypes, МСТОДЫ ApplyUpdates, CancelUpdates, CommitUpdate, RevertRecord). Буфер применяется в клиентских приложениях многоуровневых систем доступа к данным.
От классов TDataSet и TBDEDataSet унаследован обширный набор методов-обработчиков событий, позволяющий решать любые задачи по управлению набором данных.
В табл. 16.8 приведена справочная информация о свойствах и методах компонента ттаble. После этого рассматриваются подробности применения основных механизмов набора данных.

Таблица 16.8. Свойства и методы класса Tтаblеl

Компонент TQuery


Компонент TQuery реализует все основные функции стандартного компонента запроса, описанные в гл. 12. Прямым предком компонента является класс TDBDataSet.
Для подключения к базе данных используется свойство DatabaseName, в котором задается псевдоним BDE или путь к базе данных.
Текст запроса определяется свойством SQL, для задания которого применяется простой редактор, открывающийся при щелчке на кнопке свойства в Инспекторе объектов (6).
Для управления текстом запроса во время выполнения приложения можно использовать возможности класса TStrings.
Основные свойства и методы компонента TQuery представлены в табл. 16.9.
Таблица 16.9. Свойства и методы компонента TQuery

 
Компонент TStoredProc
Компонент TStoredProc обеспечивает использование в приложениях BDE хранимых процедур. Прямым предком компонента является класс TDBDataSet. Поэтому результатом выполнения хранимой процедуры может быть не только одиночный результат, но и полноценный набор данных.
Основные функции компонента TStoredProc соответствуют возможностям стандартного компонента хранимой процедуры, описанного в гл. 12. Свойства и методы компонента TStoredProc представлены в табл. 16.10.
Средствами классов-предков выполняется и подключение компонента к базе данных. Свойство DatabaseName определяет базу данных.
Свойство storedProcName задает имя хранимой процедуры.
Перед выполнением хранимую процедуру необходимо подготовить. В частности, на этом этапе осуществляется передача параметров и выделение ресурсов. Эта операция выполняется автоматически при использовании методов ЕхесРгос и Open, или задается явно методом Prepare.
Явная подготовка процедуры полезна при неоднократном вызове хранимой процедуры. Если перед первым вызовом процедуры выполнить метод Prepare, то все последующие вызовы будут осуществляться без подготовки, которая уже была сделана. В противном случае подготовка будет производиться автоматически перед каждым выполнением хранимой процедуры.
Таблица 16.10. Свойства и методы компонента TstoredProc

 

Резюме


Процессор баз данных Borland Database Engine 5 реализует стандартные функции доступа к данным и является ПО промежуточного слоя между приложением и базой данных. При помощи системы драйверов и псевдонимов BDE обеспечивает универсальный способ доступа к данным. Специальный набор компонентов доступа к данным Delphi использует BDE. Но при необходимости разработчик может применять функции API BDE напрямую.

 

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г. Яндекс.Метрика