Subject Re: [IBO] Refreshing fields calculated via a SP
Author Helen Borrie
At 03:21 PM 22/07/2003 +0930, you wrote:
>An IB_Query contains something like:
>(Ignore imprecise syntax)
>
>SELECT ID, F1, (SELECT Total FROM Calc_Total(ID)) as TotalUsed
> FROM TableA
>
>I have set KeyLinks and Insert/Update/Delete SQL statements in the IB_Query.
>
>The values display correctly when the query is opened.
>
>After inserting a new row, the field determined by the Calc_Total SP are not
>updated and appear as NULLs.

This is as expected. At this point, the new row exists only in the client
buffer.


>AutoCommit is set to True.
>
>I have tried setting CommitAction to caRefresh and caInvalidateCursor, because
>I don't know what effect they have -- and in this case they had none.

No. This wasn't an update or a delete, so there was no row to either
invalidate or refresh, since it didn't previously exist.


>If IB_Query.Refresh(); is placed in the AfterPost event, the calculated field
>appears with correct values for each row.
Until the record is posted, the server doesn't even know that new record
exists - so there is no way that calculated column is going to pop up with
a value in it.

You won't ever see the result of a server-calculated output column *except*
when the statement is requeried after the DML is committed. With
autocommit, posting the record also commits it so, when you call Refresh()
explicitly, you see the refreshed view of the output set, now included the
row you just inserted and the result of the output calculation.

>What is the proper way of refreshing the calculated field after posting the
>record, and not necessarily committing the transaction?

Calling Refresh after the Post seemed to work for you under your
conditions. Of course, it will only work like this in the AfterPost as
long as you use Autocommit - which is a hack to mimic the VCL behaviour, of
treating every database system as if it were Paradox. If you take control
of the transaction yourself, the earliest you could reasonably call for a
refreshed view of the dataset would be after you had ensured that the
commit had succeeded, i.e.
procedure TForm1.UpdateMeClick(Sender: TObject);
var
Arg1: whatever;
Arg2: whatever;
begin
with MyQuery do
try
....
Post;
try
ib_transaction.Commit;
except
... <get info about the exception>;
Arg1 := something;
Arg2 := summat;
HandleThisException (Arg1, Arg2);
end;
Refresh;
except
... <get info about the exception>;
Arg1 := quelquechose;
Arg2 := autrement;
HandleThatException (Arg1, Arg2);
end;
end;

Helen