Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil
Шрифт:
Поскольку в данном примере для сохранения изменений использовался метод Commit, то необходимо перезапустить приложение, чтобы увидеть вставленные записи в DBGridl.
Локальная сортировка и локальная фильтрация
TpFIBDataSet позволяет разработчику оптимизировать работу с базой данных, используя в случае необходимости локальную сортировку данных и локальную фильтрацию. Термин "локальный" в данном случае означает, что в этих механизмах не используются дополнительные запросы к серверу. Таким образом,
Локальная сортировка
Рассмотрим локальную сортировку на примере Sorting, который входит в поставку FIBPlus.
Как и все остальные примеры, приложение Sorting вы можете наши на сайте http://www.fibplus.net
Пример использует таблицу EMPLOYEE из базы данных Employee.gdb (рис. 2.67)
Рис 2.67. Внешний вид формы приложения, демонстрирующего локальную сортировку в TpFIBDataSet
MainDS.SelectSQL: SELECT * FROM EMPLOYEE
Все записи, полученные от сервера в результате запроса, сохраняются в локальном буфере компонента TpFIBDataSet.
Это одна из причин, из-за которой не рекомендуется использовать TpFIBDataSet для слишком больших выборок, - вам просто может не хватить оперативной памяти и работа приложения замедлится.
Предположим, что пользователь хочет отсортировать записи по полю FIRST_NAME. Очевидно, что мы можем сформировать новый запрос:
SELECT * FROM EMPLOYEE
ORDER BY FIRST_NAME
Чтобы получить новый порядок записей, необходимо переоткрыть наш запрос. Это работает, но означает, что мы будем повторно получать от сервера все •записи, несмотря на то что нам нужно было всего лишь поменять их визуальный порядок. Если предполагать, что нашим приложением могут пользоваться одновременно несколько пользователей, то затраты на подобные "сортировки" могут оказаться довольно значительными. Тем не менее выход существует, поскольку TpFIBDataSet позволяет сортировать данные внутри своего локального буфера, т. е. без необходимости получения всех записей заново.
Для этого мы должны воспользоваться одним из возможных вариантов метода DoSort или DoSortEx:
procedure DoSort(Fields: array of const; Ordering: array of Boolean); virtual;
procedure DoSortEx(Fields: array of integer; Ordering: array of Boolean); overload;
procedure DoSortEx(Fields: TStrings; Ordering: array of Boolean); overload;
Метод DoSortEx доступен в FIBPlus начиная с версии Delphi 4.
Первый параметр всех трех процедур - это список полей, по которым мы хотим отсортировать данные. В случае DoSort это могут быть названия полей или номера полей. Первый вариант DoSortEx позволяет нам использовать только список с номерами полей, а второй вариант DoSortEx предполагает, что мы заполнили список Fields
DoSort(['FIRSN_NAME'], [True]);
Или: DoSortEx([1], [True]);
[True] означает, что поле сортируется по возрастанию (ASCENDING).
В сущности, использование этих методов очевидно, однако иногда возникает вопрос, связанный с динамическим формированием списков полей. Рассмотрим подробнее наш пример, который демонстрирует, как создавать параметры для DoSortEx динамически. Предполагается, что пользователь сможет нажимать на заголовки DBGridl, указывая, таким образом, поле, которое будет участвовать в сортировке. Повторное нажатие на колонку, которая уже участвует в сортировке, будет изменять порядок сортировки по этой колонке на противоположный. Сначала мы опишем вспомогательный класс для хранения информации о молях, которые будут участвовать в сортировках.
type
TOrderStringList = class(TStringList)
protected
function GetAscending(Index: Integer): boolean;
procedure SetAscending (Index: Integer; Value: boolean);
public
property Ascending[Index: Integer]: boolean read
GetAscending write SetAscending;
end;
...
{ TOrderStringList }
function TOrderStringList.GetAscending(Index: Integer):
boolean;
begin
Result := boolean(integer(Objects[Index]));
end;
procedure TOrderStringList.SetAscending(Index: Integer; Value:
boolean);
begin
Objects [ Index] := pointer (integer (Value));
end;
Очевидно, что данный класс является списком строк - названия полей, а также хранит для каждого поля, включенного в список, порядок сортировки в виде свойства Ascending. Ниже вы видите описание класса формы, а также два основных обработчика событий (OnCreate, OnDestroy). При создании формы мы создаем экземпляр класса TOrderStringList, а при ее уничтожении - удаляем.
TMainForm = class(TForm)
MainDB: TpFIBDatabase;
MainDS: TpFIBDataSet;
MainTr: TpFIBTransaction;
DataSourcel: TDataSource;
DBGridl: TDBGrid;
Buttonl: TButton;
Label2: TLabel;
procedure DBGridlTitleClick(Column: TColumn);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ButtonlClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
SortFields: TOrderStringList;
procedure ReSort;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
SortFields := TOrderStringList.Create;
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
SortFields.Free;
end;
Теперь напишем обработчик события OnTitleClick у компонента DBGridl:
procedure TMainForm. DBGndlTitleCiiCK (Column: TColumn);
const OrderScr: array [boolean] of string = ('(DESC)',