Subject Re: [IBO] More Params info
Author Helen Borrie
At 07:07 AM 17/07/2003 +0000, you wrote:
>Hi Geoff,
>
>Thanks for your two detailed replies.
>I appreciate everything you have told me, and I have changed the
>OldParameterOrdering option, restarted server, but my problem still
>persists.
>
>Also, I don't think that what you have pointed out is relevant for
>me, because I only ever have one parameter, so I don't see how it
>could be getting confused with other params...

Agreed - now that you have come up with the problem description. :-)


>Here is the actual code:
>Note that the IF statement checks to see if it is the same parameter
>being used, and if so simply changes the value. This is OK.
>It's the ELSE section that was working until today, and is now
>causing AV's

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. Whether you have
something that "worked properly before" or not, it was not a good approach
to go in there and mess around with SQLWhere, since SQLWhereItems surfaces
the right way (from the parser's point of view) to safely change the WHERE
clause.

You haven't explained what event the code below happens in so, for
simplicity, let's assume it's a button click on MyEventButton.

Your code:


>if (currentView = vwCurrent) then
>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;
>
>Because the AV is happening before the query is sent to the server,
>it never shows up in the monitor.
>
>Thanks again for your advice, and any other suggestions you may have.
>I'm sure this is something quite small..

OK.

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;

Helen