Приветствую Вас Гость | RSS

Меню сайта

Реклама

Категории раздела
ADO [17]
ASCII и CSV [12]
Access [20]
Alias [24]
BDE [37]
BLOB поля [19]
Clipper [2]
DB2 [2]
DBASE и DBF [26]
Fox Pro [1]
Interbase [21]
MSSQL [0]
ODBC [10]
Oracle [0]
Paradox [0]
SQL [29]
Sybase [1]
База данных [0]
Закладки [2]
Записи [0]
Индексы [10]
Компоненты и Базы данных [0]
Модуль данных [3]
Отчеты [2]
Ошибки БД [17]
Поиск [16]
Поля [0]
Сортировка и Фильтр [6]
Таблицы [0]

Наш опрос
Какие компоненты добавлять больше?
Всего ответов: 48

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Форма входа

Главная » Статьи » Базы данных » Поиск

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

Я представляю на Ваш суд утилиту быстрого поиска по базе данных. Данная технология производит поиск по полям, преобразуя их значения в строки (все значения преобразуются в верхний регистр, включая действительные числа). Данное решение может быть не самым быстрым, однако на поверку оно оказывается быстрее остальных, обнаруженных мною в Интернете (может вам повезет больше). Более того, представьте, что действительное значение какого-либо поля равно 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.
Категория: Поиск | Добавил: Skinner (07.07.2008)
Просмотров: 358 | Рейтинг: 0.0/0
  Delphi Lab   Главная   Регистрация   Вход  
Интересная Цитата

Поиск

Магазин


Copyright MyCorp © 2024 Хостинг от uCoz