Subject Please. A solution with TRANSACTIONS for this problem
Author pepmallorca
Hello:
======

I have a problem. I THINK I'M INCOMPATIBLE WITH THE TRANSACTIONS...
I think the better is that I explain what I wan't to do and I hope
someone can help me how to do it.

I wan't to do a program that stores in a table all the words of a
document and the number of ocurrences of each word.

After of that, the user have to see the results in a grid and then
can exit or commit. Only if the user wants the information would
store physical in the table (by default NO)

I need it's go fast, and if it's possible the minimum writes in the
physical database (ONLY the writes that was necessary)... Is possible
all that I need in a program...?

===========
My solution
===========

*** I have a table like this:

CREATE TABLE TEST (ID VARCHAR(6) NOT NULL,
NAME VARCHAR(50) NOT NULL,
NUMB INTEGER,
PRIMARY KEY (ID));

***
*** I have created a procedure like this:
***

CREATE PROCEDURE INS_UPD (PID VARCHAR(6),
PNAME VARCHAR(50))
AS
begin insert into test(id,name,numb) values ( :pId, :pName, 1);
when sqlcode -803 do
update test
set numb=numb+1
where id=:pId;
end

***
*** And my program is this. The bucle is 'like find all the words of
a document'...:
***

I have a component: IB_DATABASE and an IB_QUERY with a GRID to view
the results.


***
*** This is the BUTTON
***

procedure TForm1.Button1Click(Sender: TObject);

var i:integer;
vDateIni,vDateFin:TDateTime;
vDateElp:TDateTime;
Hour, Min, Sec, Msec:Word;

begin


vDateIni:=Time;


// if not IB_transaction1.InTransaction
then // //IB_transaction1.starttransaction;

with ib_dsql1 do
begin
sql.text:='';
sql.add('execute procedure ins_upd(:po,:p1)' );
prepare;
end;


for i:=1 to 10000 do
begin
ib_dsql1.Params[0].AsString:=IntToStr(i);
ib_dsql1.Params[1].AsString:=IntToStr(i);
ib_dsql1.execute;
end;


vDateFin:=Time;
vDateElp:=vDateFin - VDateIni;
DecodeTime( vDateElp, Hour, Min, Sec, MSec );

TimeDif.caption := IntToStr( Hour * 60 + Min ) + ' min, ' +
IntToStr( Sec ) + 'seg, ' + IntToStr( MSec )+'
mseg';



// if IB_transaction1.InTransaction then IB_transaction1.commit;
// IB_transaction1.commit;
// IB_database1.commit;



end;


Problems
--------

It works, but sometimes spends 30 secs, sometimes 49 secs...
With i=100000, sometimes 3 min, sometimes 6 min...

It writes continuosly in the disk, and I think there is another way
of do it working more in memory (CacheUpdates... or using
transactions...)

The MAIN PROBLEM is that I don't know how use the TRANSACTIONS in
this problem. I'll try the next: Create an IB_CONNECTION, and a
IB_TRANSACTION, deletes the component IB_DATABASE1 (or not...) and if
I associate the IB_QUERY and the DSQL component to the IB_CONNECTION
and IB_TRANSACTION, I ALWAYS get the 'NICE' message:

* TRANSACTION HAS NO CONNECTIONS *

Someone can helps me?.... if is possibly completing this example...



THANK YOU VERY MUCH,