Board index » delphi » help: querying the results of a SQL Query...

help: querying the results of a SQL Query...

Question from a DelphiDB {*word*269}...

I'm trying to design a form similar to the windows help system, where
as one types in an edit box, the choices that partially or fully match
are displayed in a listbox below.

So far i've got a TQuery component hooked to a DBlookupListbox,
and a plain-old TMemo.

When TMemo.OnChange is fired, the following code executes:

procedure TForm1.Memo1Change(Sender: TObject);
var
   MyString: String;

begin
  if Memo1.Lines.Text <> '' then
  begin
     with DataModule1.Query1 Do
      begin
          Close;
          SQL.Clear;
         SQL.Add('SELECT DESCR FROM mytable');  
        MyString := 'WHERE DESCR like upper("%' + Memo1.Lines.Text
+'%")';
         SQL.Add(MyString);
        Open;
      end;
  end;
end;

This does work, however it is _slow_. (the whole dataset is ~ 5000
records)

I'm gathering from the code what's happening is that every time a
character is entered, the event fires, the SQL statement runs through
all 5000 records and filters the ones that contain mytext
appropriately.

However, it would be much faster if I could query the results of the
previous query -- (ie, start with 5000 records, then as the person
types more of the complete search string, the number of records gets
whittled down so SQL has to search fewer records with each successive
search) -- like a bracketed search.

I am at a loss as to how to perform a SQL statement on the resultset
of a previous SQL statement.  

the docs have been less than illuminating;  any & all tips
appreciated.
adam

------------------
A. Wolf Farkas, MD
afar...@umich.edu

 

Re:help: querying the results of a SQL Query...


In article <34239444.37016...@news2.ibm.net>,

Quote
afar...@umich.edu (Adam Farkas) wrote:
>Question from a DelphiDB {*word*269}...

>I'm trying to design a form similar to the windows help system, where
>as one types in an edit box, the choices that partially or fully match
>are displayed in a listbox below.

>So far i've got a TQuery component hooked to a DBlookupListbox,
>and a plain-old TMemo.

>When TMemo.OnChange is fired, the following code executes:

>procedure TForm1.Memo1Change(Sender: TObject);
>var
>   MyString: String;

>begin
>  if Memo1.Lines.Text <> '' then
>  begin
>     with DataModule1.Query1 Do
>      begin
>          Close;
>          SQL.Clear;
>         SQL.Add('SELECT DESCR FROM mytable');  
>        MyString := 'WHERE DESCR like upper("%' + Memo1.Lines.Text
>+'%")';
>         SQL.Add(MyString);
>        Open;
>      end;
>  end;
>end;

>This does work, however it is _slow_. (the whole dataset is ~ 5000
>records)

I'm using a similar technique, looking up a name in a table with 20K records.
First, the Name field is indexed, but not the Primary key.
Second, I'm first firing off a SQL-query from an OnChange event only after the
length of the string is more than a userdefined value. :
SELECT COUNT(*) FROM CUST WHERE NAME LIKE 'HANS%';
If the result is higher than another userdefined value, like 10, I don't
do anything.
If the hit count is lower, I send the 'full' SQL string, receiving all the
matching records, where the user picks one from a list box if there's more
than one.
An alternative (my preferred way of doing it) is that the user enters a
userdefined key when she wants the search to start, like when entering a
'>', the search starts. Combined with the maxhit, this works very well.

This works pretty fast, using ODBCExpress and Solid Server.

Quote
>I'm gathering from the code what's happening is that every time a
>character is entered, the event fires, the SQL statement runs through
>all 5000 records and filters the ones that contain mytext
>appropriately.

>However, it would be much faster if I could query the results of the
>previous query -- (ie, start with 5000 records, then as the person
>types more of the complete search string, the number of records gets
>whittled down so SQL has to search fewer records with each successive
>search) -- like a bracketed search.

I don't think you can do that without creating a temporary table to hold the
records? But I don't know if that is any faster? What takes time, on my
system anyway, is the actual fetching of a lot of unneeded records.
I'm not familiar with the BDE, but if you get the first results in a list
box kind of control, can't you search the contents of the listbox after the
first query? Or maybe assign the strings of the Listbox to another stringlist,
and then remove all items that doesn't fit the growing search string?

--
|| Bjorn K. Nilssen      // http://home.sn.no/~bjoernk/  // mainly 3D ||

Re:help: querying the results of a SQL Query...


Try to use the filter property of TQuery.

Gook luck!

Other Threads