Subject | Re: [IBO] More Params info |
---|---|
Author | Ryan Nilsson-Harding |
Post date | 2003-07-18T02:11:30Z |
Thanks Helen for the (as always!) detailed description.
I am beginning to get this now, but I would like to clarify a couple
of things, as this is a feature which I have obviously implemented
poorly from the beginning, and it is spread throughout my app in
various ways.
AV's.
Also, I much rather use the tools the way they are intended, instead
of coming up with an "OK workaround". Hence, I am now going to truly
get this concept burnt into my skull.
menu)
couple of brief questions (below your code)
thought I read somewhere that InvalidateSQL should be accompanied by
a refresh. But now that doesn't make sense as the query is closed,
then opened.
2- What is the reason you explicitly call close on the query (in the
button event)? Does InvalidateSQL not do this?
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?
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;
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?
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?
Thanks again for your help. I have been a little verbose, but this
HAS to be properly understood by me before I move on.
Thanks, and kind regards,
-Ryan
I am beginning to get this now, but I would like to clarify a couple
of things, as this is a feature which I have obviously implemented
poorly from the beginning, and it is spread throughout my app in
various ways.
> Yes, it will AV if you intervene in what the SQL parser is doing -which is
> just what you do when you try to set SQLWhere yourself. Whetheryou have
> something that "worked properly before" or not, it was not a goodapproach
> to go in there and mess around with SQLWhere, since SQLWhereItemssurfaces
> the right way (from the parser's point of view) to safely changethe WHERE
> clause.OK, it's now clearer as to why accessing SQLWhere directly causes
AV's.
Also, I much rather use the tools the way they are intended, instead
of coming up with an "OK workaround". Hence, I am now going to truly
get this concept burnt into my skull.
> You haven't explained what event the code below happens in so, forYour assumption is correct, it's tied to an action item (button &
> simplicity, let's assume it's a button click on MyEventButton.
menu)
> >if (currentView = vwCurrent) thenRegarding your code suggestions below, could you please answer a
> >qry.ParamByName('rp_id').AsInteger := posHISTORY;
> >else begin
> >qry.DisableControls;
> >qry.SQLWhere.Clear;
> >qry.SQLWhere.Add('WHERE Q.RP_ID = :rp_id');
> >if not qryQuote.Prepared then
> >qry.Prepare; <== This is never called...
> >
> >qry.Params[0].AsInteger := posHISTORY; <== AV caused here
> >{If I use ParamByName('rp_id'), I get an error stating there is no
> >such field 'rp_id'}
> >
> >qry.Open;
> >qry.EnableControls;
couple of brief questions (below your code)
> procedure MyForm.MyEventButtonClick(Sender: TObject);1- Is InvalidateSQL all that's needed to trigger OnPrepare? I
> 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;
thought I read somewhere that InvalidateSQL should be accompanied by
a refresh. But now that doesn't make sense as the query is closed,
then opened.
2- What is the reason you explicitly call close on the query (in the
button event)? Does InvalidateSQL not do this?
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?
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;
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?
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?
Thanks again for your help. I have been a little verbose, but this
HAS to be properly understood by me before I move on.
Thanks, and kind regards,
-Ryan