Мир программирования

 


Найти: на:


Меню
Партнеры
Счетчики
Реклама

Быстрый поиск в базах данных


Я представляю на Ваш суд утилиту быстрого поиска по базе данных. Данная технология производит поиск по полям, преобразуя их значения в строки (все значения преобразуются в верхний регистр, включая действительные числа). Данное решение может быть не самым быстрым, однако на поверку оно оказывается быстрее остальных, обнаруженных мною в Интернете (может вам повезет больше). Более того, представьте, что действительное значение какого-либо поля равно 4.509375354, а значение поиска равно 7, в этом случае утилита засчитает "попадание". Утилита удобна также тем, что она за один проход производит поиск более, чем в одном поле. Это удобно, если у Вас имеются, к примеру, два поля с адресами. Это моя первая "серьезная" разработка, так как первое, с чем я столкнулся, изучая Delphi, стала необходимость включения процедуры поиска в любое приложение, работающее с базой данных. А так как поиск - вещь тоже сугубо специфическая, как и любое приложение, то мне пришлось побороть свой страх перед "крутым программированием" и попробовать написать свой поисковый механизм, удовлетворивший меня (и, надеюсь, других) своей скоростью и возможностью "мульти"-поиска по нескольким полям. Я надеюсь, что он поможет тем программистам, кто часто сталкивается с подобными задачами. Технология довольно легка для понимания, но если у Вас возникли какие-либо вопросы, пошлите мне письмо электронной почтой, я буду рад Вам помочь. Посмотрев код, можно легко узнать поддерживаемые типы полей (добавить новые не составит проблем). Если кто-либо обнаружит ошибочный код или расширит функциональность утилиты, пожалуйста, пошлите это мне, я буду весьма благодарен. Спасибо.

 

 

unit Finder;

interface

uses
DB, DBTables, SysUtils;

function GrabMemoFieldAsPChar(TheField : TMemoField): PChar;
function DoFindIn(TheField : TField; SFor : String ): Boolean;
function FindIt(TheTable : TDataSet; TheFields : array of integer;

SearchBackward : Boolean; FromBeginning : Boolean; SFor : String ): Boolean;

{ применение функции FindIt -

if FindIt(NotesSearchT,

[NotesSearchT.FieldByName('Leadman').Index],

False, True, SearchText.Text) then DoSomething; }


implementation

function
GrabMemoFieldAsPChar(TheField : TMemoField): PChar;
begin
with
TBlobStream.Create(TheField, bmRead) do

begin

GetMem(Result, Size + 1 );

FillChar(Result^, Size + 1 , #0 );

Read(Result^, Size);

Free;

end ;

end ;

function DoFindIn(TheField : TField; SFor : String ): Boolean;
var

PChForMemo : PChar;

begin
Result := False;
case TheField.DataType of

ftString :

begin

if (Pos(SFor, UpperCase(TheField.AsString)) > 0 ) then

Result := True;

end ;

ftInteger :

begin

if (Pos(SFor, TheField.AsString) > 0 ) then Result := True;

end ;

ftBoolean :

begin

if SFor = UpperCase(TheField.AsString) then

Result := True;

end ;

ftFloat :

begin

if (Pos(SFor, TheField.AsString) > 0 ) then Result := True;

end ;

ftCurrency :

begin

if (Pos(SFor, TheField.AsString) > 0 ) then Result := True;

end ;

ftDate .. ftDateTime :

begin

if (Pos(SFor, TheField.AsString) > 0 ) then Result := True;

end ;

ftMemo :

begin

SFor[Ord(SFor[ 0 ]) + 1 ] := #0 ;

PChForMemo := GrabMemoFieldAsPChar(TMemoField(TheField));

StrUpper(PChForMemo);

if not (StrPos( PChForMemo, @SFor[ 1 ] ) = nil ) then Result :=

True; FreeMem(PChForMemo, StrLen(PChForMemo + 1 ));

end ;

end ;

end ;

function FindIt(TheTable : TDataSet; TheFields : array of integer;

SearchBackward : Boolean; FromBeginning : Boolean; SFor : String ): Boolean;

var

i, HighTheFields, LowTheFields : integer;

BM : TBookmark;

begin
TheTable.DisableControls;
BM := TheTable.GetBookmark;
try
LowTheFields := Low(TheFields);
HighTheFields := High(TheFields);
SFor := UpperCase(SFor);
Result := False;
if FromBeginning then TheTable.First;
if SearchBackward then

begin

TheTable.Prior;

while not TheTable.BOF do

begin

for i := LowTheFields to HighTheFields do

begin

if DoFindIn(TheTable.Fields[TheFields[i]], SFor) then

begin

Result := True;

Break;

end ;

end ;

if Result then Break else TheTable.Prior;

end ;

end else

begin

TheTable.Next;

while not TheTable.EOF do

begin

for i := LowTheFields to HighTheFields do

begin

if DoFindIn(TheTable.Fields[TheFields[i]], SFor) then

begin

Result := True;

Break;

end ;

end ;

if Result then Break else TheTable.Next;

end ;

end ;

finally
TheTable.EnableControls;
if not Result then

TheTable.GotoBookmark(BM);

TheTable.FreeBookmark(BM);
end ;

end ;

end .

 

[Оглавление]

Опрос

Конкурсы
Реклама

 

Web дизайн: Бурлаков Михаил    

Web программирование: Бурлаков Михаил

Используются технологии uCoz