Subject Re: [IBO] How to commit an update from code?
Author Helen Borrie
At 04:26 PM 2/04/2004 -0500, you wrote:
>I am running an update query in code. I construct the query manually and
>then run it using ExecSQL. But the update never seems to take place
>
>This is my code (where qryTemp is a TIB_Query)

The reason you are having problems getting DML to "take" is that you are
using Cache methods. Caching applies to datasets, not DML statements, and
it's rarely useful to use caching with IBO, anyway.

You don't need (and should avoid) a TIB_Query for DML. Use a TIB_Cursor or
a TIB_DSQL for any straight "execute" queries.

You EXECUTE DML statements, you OPEN datasets.


>With DataAccessMod.qryTemp do
>Begin
> Active := False;
> SQL.Clear;
>
> // construct the query
> SQL.Add('UPDATE "UserAccounts" SET ');
> SQL.Add('"Credits" = ' + IntToStr(iAmount) + ' ');
> SQL.Add('WHERE "AccountID" = ' + IntToStr(iUserID));
>
> // run the query
> ExecSQL;
>
> // After doing this I have tried each of the following: (one at a time)
>
> ApplyUpdates;
>
> CommitAction := caRefresh;
>
> CommitAction := caClose;
>End;

All of that CommitAction (and also RefreshAction) stuff applies to datasets.

>Can somebody help me?
>
>Thank you,
Here goes. Drop a TIB_DSQL onto your form or DM and hook up its
ib_transaction and ib_connection props appropriately.

It makes sense to apply a whole SQL statement in a single hit only if you
are gong to recycle this object for totally different statements. If you
plan to reuse it over and over for the same statement with simply different
SET and WHERE criteria, then do the SQL as an IDE property, as follows:

UPDATE "UserAccounts"
SET "Credits" = :iAmount
WHERE "AccountID" = :iUserID

The run-time stuff is like this (in the BeforeExecute event):

with MyDSQL do
begin
if not IB_Transaction.Started then
IB_Transaction.StartTransaction;
if not Prepared then Prepare;
ParamByName('"Credits").AsCurrency := iAmount;
ParamByName('"AccountID"').AsInteger := iUserID;
end;

On your button-click:
begin
MyDSQL.Execute;
MyDSQL.IB_Transaction.Commit;
end

You'll want to include a try..except block in your execute method, too, so
you can handle any exceptions.

With a DML statement, there is no dataset, so there is nothing to
"Refresh". You won't see what you want to see unless you have an object
capable of displaying the stuff. If you do, then that's the object you
have to refresh.

Helen