Базы Данных с нуля
Поиск в наборе данных

Одной из важнейших функций любой Информационной Системы является поиск данных в большом массиве информации, которой и является База Данных. Поиск представляет собой переход к записи на основании заданного условия. Поиск в чем-то похож на фильтрацию, но его главной особенностью является переход только к одной, самой первой записи, удовлетворяющей заданному условию. Эта особенность также является и его недостатком.

Для поиска в Базе Данных служат несколько методов. Для поиска данных по неиндексированным полям Базы Данных служат два метода Locate и LookUp. Для использования этих методов нужно указать поле, по которому будет произведен поиск данных, значение условия поиска и список возможных параметров. Здесь также существует возможность поиска сразу по нескольким полям. Для этого нужно перечислить поля через точку с запятой.

В качестве параметров служат следующие параметры:

  • loCaseInsensitive - Регистр букв не учитывается.
  • loPartialKey - Допускается частичное совпадение значения поиска.

Существует возможность указать сразу все эти параметры для поиска, либо вообще не указывать их. Если в качестве параметра указать параметр loPartialKey, то автоматически будет добавлен и параметр loCaseInsensitive. Рассмотрим пример:

procedure TForm1.ButtonFindClick(Sender: TObject);
begin
 Table1.Locate('Town', 'Москва', [loCaseInsensitive]);
 Query1.Locate('Fam', 'Иванов', [loPartialKey]);
end;

Иногда требуется найти определенную запись на основании нескольких условия для поиска, то есть сразу по нескольким полям. Для этого нужно воспользоваться функцией VarArrayOf. Если указать не равное число полей и соответствующих им значений, это приведет к исключительной ситуации. Рассмотрим пример:

procedure TForm1.ButtonFindClick(Sender: TObject);
begin
 Table1.Locate('Code;Fam', VarArrayOf(['2', 'Петров']), [loPartialKey]);
 Query1.Locate('Name;BirthDay', VarArrayOf(['Сидор', '01.04.85']), [loCaseInsensitive]);
end;

На практике удобней создать отдельную форму для поиска, на которой расположить некоторое количество переключателей, соответствующих полям Базы Данных, такое же число однострочных редакторов и кнопку для поиска. И вот как это примерно будет выглядеть для нашей Базы Данных:

procedure TForm1.ButtonFindClick(Sender: TObject);
begin
 Try
   If rbCode.Checked Then Table1.Locate('Code', edtCode.Text, [loPartialKey])
     Else
   If rbName.Checked Then Table1.Locate('Name', edtName.Text, [loPartialKey])
     Else
   If rbFam.Checked Then Table1.Locate('Fam', edtFam.Text, [loPartialKey])
     Else
   If rbBirthDay.Checked Then Table1.Locate('BirthDay', edtBirthDay.Text, [loPartialKey])
     Else
   If rbTown.Checked Then Table1.Locate('Town', edtTown.Text, [loPartialKey])
 Except
   MessageDlg('Не заданы условия поиска.', mtError, [mbOK], 0);
 End;
end;

Перед началом поиска идет проверка того переключателя, который находиться во включенном состоянии. И если какой-либо переключатель включен, то производиться поиск на основании значения поиска, введенного в редактор, по соответствующему полю Базы Данных. Если в редактор не было введено ни какого значения, то это приводит к исключительной ситуации. На этот случай предусмотрена конструкция Try .. Except. Проверку на отсутствие введенного значения можно также проводить и в начале процедура поиска.

Для поиска также служит метод LookUp. Данный метод похож на метод Locate, но указатель не перемещается на найденную запись, а данные просто считываются из этой записи. Еще одним отличием является поиск на полное соответствие условия поиска. При использовании данного метода вместо параметров нужно указать перечень полей, которые будут получены в результате успешного поиска. Если поиск завершился неудачей, то метод вернет значение Null. Здесь так можно использовать поиск сразу по нескольким полям одновременно.

procedure TForm1.Button3Click(Sender: TObject);
begin
 Query1.Lookup('Code', '3', 'Code;Town;BirthDay');
 Table1.Lookup('Name;Town', VarArrayOf(['Сергей', 'Минск']), 'Code;Name');
end;

Для набора данных Table существуют методы для поиска только по индексированым полям. Для их использования нужно задать текущий индекс с полем или полями, по которым будет производиться поиск. Если индекс будет построен по нескольким полям, то поиск также можно производить сразу по нескольким полям. Одним из таких методов является метод FindKey. Данный метод производит поиск записи в наборе данных, у котрой значения полей совпадают со значениями поиска, указанными в параметре функции. То есть, сколько полей входят в текущий индекс, столько условий поиска можно указать в команде. Рассмотрим пример:

procedure TForm1.ButtonSearchClick(Sender: TObject);
begin
 // Создаем индекс
 Table1.Close;
 Table1.AddIndex('indCodeName', 'Code;Name', []);
 Table1.IndexName:='indCodeName';
 Table1.Open;
 // Производим поиск
 Table1.FindKey(['3', 'Петр']);
 // Удаляем созданный индекс
 Table1.Close;
 Table1.DeleteIndex('indCodeName');
 Table1.Open;
end;

Интересным способом поиска является совокупность методов SetKey и GotoKey. При помощи метода SetKey набор данных переводиться в режим поиска. Затем для перехода к записи используется метод GotoKey. Задание условий поиска производиться обычным присваиванием. Рассмотрим пример:

procedure TForm1.ButtonSearchClick(Sender: TObject);
begin
 Table1.IndexName:='indTown';
 Table1.SetKey;
 Table1.Fields[4].Text:='Санкт-Петербург';
 Table1.GotoKey;
end;

Не менее удобным способом для поиска данных существует метод FindNearest. Данный метод производит поиск записи на частичном совпадении условия поиска. Сравнение производиться с самого первого символа, стоящего в поле Базы Данных и поэтому вероятность положительного поиска достаточно велика. Здесь также можно производить поиск сразу по нескольким полям БД. Рассмотрим пример:

procedure TForm1.ButtonSearchClick(Sender: TObject);
begin
 Table1.IndexFieldNames:='Town';
 Table1.FindNearest(['Б']);

 Table2.IndexFieldNames:='Code;Name';
 Table2.FindNearest(['2', Edit1.Text]);
end;

На основании рассмотренных методов поиска можно сделать вывод, что на практике удобней всего использовать методы Locate и FindNearest.

Вернуться в оглавление
Вернуться на главную страницу
Hosted by uCoz