Subject Re: [IBO] More Params info
Author Helen Borrie
At 02:11 AM 18/07/2003 +0000, you wrote:

>Regarding your code suggestions below, could you please answer a
>couple of brief questions (below your code)
>
> > procedure MyForm.MyEventButtonClick(Sender: TObject);
> > begin
> > .... stuff...
> > with dm.qry do
> > begin
> > Close;
> > DisableControls;
> > if (currentView <> vwCurrent) then
> > InvalidateSQL; // signals IBO to reprepare
> > EnableControls;
> > Open;
> > end;
> > end;
> >
> > // this proc only gets called if the SQL is invalidated
> >
> > procedure dm.qryPrepareSQL(Sender: TIB_Statement);
> > var
> > condition: integer;
> > begin
> > if [xxx] then
> > condition := 1
> > else if [yyy] then
> > condition := 2
> > else
> > condition := 3;
> > qry.SQLWhereItems.Clear;
> > case condition of
> > 1: qry.SQLWhereItems.Add('q.RP_ID = :rp_id');
> > 2: qry.SQLWhereItems.Add('q.YYY = :yyy');
> > 3: qry.SQLWhereItems.Add('q.ZZZ = :zzz');
> > end;
> > end;
> >
> > procedure dm.qryBeforeOpen(IB_Dataset: TIB_Dataset);
> > begin
> > if not Prepared then Prepare;
> > qry.Params[0].Value := posHISTORY;
> > end;
>
>1- Is InvalidateSQL all that's needed to trigger OnPrepare?

Yes.

>I
>thought I read somewhere that InvalidateSQL should be accompanied by
>a refresh.

InvalidateSQL will *always* be accompanied by a re-doing of the entire
statement object. Are you getting confused with some of the other
Invalidate.. methods like InvalidateRowNum, InvalidateRows or
InvalidateBookmark?

>But now that doesn't make sense as the query is closed,
>then opened.

That's right. Everything in the statement object depends on the SQL
specification so, when that changes, much more happens to the object.

>2- What is the reason you explicitly call close on the query (in the
>button event)? Does InvalidateSQL not do this?

No. Remember, this stuff is all event-driven. So InvalidateSQL signals
that the query specification will have to be rebuilt next time it (or any
things that depend on it) is accessed.

>3- You explicitly call SQLWhereItems.Clear in OnPrepareSQL, but it
>states in the GSG that this is done automatically in this event and
>is unnecessary. Is this necessary?

In some cases it might be. At the point where we want to add all-fresh
WhereItems, we want to be sure that we have nothing left over from
before. It doesn't hurt to call Clear on an empty stringlist, but it does
hurt not to do so if something hasn't yet cleared it.


>4- Confirmation please: I have only one parameter, but the column
>the parameter refrences may change. (There are three fields the user
>can select to narrow down the WHERE)
>4a- When the parameter value changes, BUT the referenced column is
>the same, all I need to do is:
>myQry.Params[0].Value := xxx;

Correct. The OnPrepareSQL handler will only get called if the params
object itself changes, not if just the values being applied to the existing
params object are changing.

>This seems to do the refresh, and it's clean & quick (i.e. I don't
>need Disable/Enable controls to prevent flickering) Is my
>understanding of this correct?

Yes. On a slow system you might see flickering as the control gets updated
but, essentially, swapping new rows into the same dataset object wouldn't
have any greater visual impact than say a mode shift or a scroll action.

>4b- (Last one!!) When the referenced column DOES change (or the
>number of parameters changes) is this the only time I use
>InvalidateSQL. Is my understanding of this correct?

Yes. In my case, my "epiphany" with datasets came the day I realised that
the dataset is just a container for a SQL specification. If the spec
doesn't change, the container doesn't change.

Search arguments (the column list in your WHERE clause) and ORDER BY
arguments (the column list in your ORDER BY clause) are part of the
STRUCTURE of the specification. If you change the COLUMNS that are used
for these arguments, you change the structure of the specification and so
the container gets emptied and reconstructed to reflect the structural
change. If the only thing you change in the WHERE clause is the value that
gets pushed into the search spec, you aren't changing the
structure. (Alternative ORDER BY always changes the structure...)


>Thanks again for your help. I have been a little verbose, but this
>HAS to be properly understood by me before I move on.

Yep - agreed - and when the penny drops, you tend to move on faster. :-))

Helen