Reputation: 11
When I made a commit, I naively believed that the physical file of the database would be updated (changing the modification date), but obviously it does not work like that. The physical file of the database is modified when the database is closed !!!
i wrote a little test application with (delphi 10.2.3) * FDConnection1: TFDConnection; (all default setting) (cachedupdate is false) * FDQuery1: TFDQuery; (all default setting)
My SQLite database has just one table
CREATE TABLE t_stritems
( IdItels
INTEGER, St01
VARCHAR (200), St02
VARCHAR (200), St03
VARCHAR (200), PRIMARY KEY(IdItels
) )
My code is very simple
Connect the database :
FDConnection1.Connected := false;
FDConnection1.Params.Clear;
FDConnection1.Params.Add('DriverID=SQLite');
FDConnection1.Params.ADD('Database=' + Edit1.text);
FDConnection1.Connected := true;
Insert rows into the database
FDQuery1.Connection := FDConnection1;
FDQuery1.close;
fdquery1.sql.clear;
fdquery1.sql.add('DELETE FROM t_stritems');
FDConnection1.StartTransaction;
fdquery1.ExecSQL;
FDConnection1.Commit;
fdquery1.sql.clear;
fdquery1.sql.add('SELECT * FROM t_stritems');
fdquery1.Open;
for i := 0 to 15 do
begin
for j:= 1 to 2000 do
begin
FDQuery1.append;
FDQuery1.FieldByname('IdItels').asInteger := (i*2000) + j;
FDQuery1.FieldByname('St01').asString := 'Text 01 Number : ' + FDQuery1.FieldByname('IdItels').asString;
FDQuery1.FieldByname('St02').asString := 'Text 02 Number : ' + FDQuery1.FieldByname('IdItels').asString;
FDQuery1.FieldByname('St03').asString := 'Text 03 Number : ' + FDQuery1.FieldByname('IdItels').asString;
FDQuery1.post;
end;
// FDConnection1.Commit;
end;
end;
Test Process : Connect the database : (the t_stritems file of my database contains 32000 records; the size of the database file is 2338 ko) After the delete sql, I have in the directory of my database file a journal file (xxxx.db-journal). the database file size is 2338 ko after the first commit, I have always in the directory of my database file the journal file (xxxx.db-journal). the database file size is 2338 ko (no physical update) The program then adds 32000 records The modification date of the file (.db) of the database will be modified only when I leave my application. !!! the journal file (.db-log) will be deleted at the end of my application
Questions : How to make the commit save data to the database ? Is this normal ? That the physical file of the database is modified only at the closing of the application (and at the same time of the connection) ?
Thank you in advance for your answer Best regards Romuald
Upvotes: 0
Views: 1875
Reputation: 27
It seems that you are confused on how to use databases in Delphi.
1) First of all you need to add try/finally in your code in order to catch any exceptions and prevent memory leaks.
2) Use connection.StartTransaction - connection.Commit paired.
3) Commit must be used at the end of your loop. When you finsih with updating your data, then you call Commit to perform all the updates you made on your fields.
Here is how I would re-write your code in order to implement my suggestions above:
FDConnection1.Connected := false;
FDConnection1.Params.Clear;
FDConnection1.Params.Add('DriverID=SQLite');
FDConnection1.Params.Add('Database=' + 'Edit1.text');
FDConnection1.Connected := true;
FDQuery1.Connection := FDConnection1;
// your first transaction
// just use ExceSQL directly to run your SQL query
FDQuery1.ExecSQL('DELETE FROM t_stritems');
try
// start your transaction and use query.Open()
FDConnection1.StartTransaction;
FDQuery1.Open('SELECT * FROM t_stritems');
for i := 0 to 15 do
begin
for j := 1 to 2000 do
begin
FDQuery1.FieldByName('IdItels').asInteger := (i * 2000) + j;
FDQuery1.FieldByName('St01').AsString := 'Text 01 Number : ' + FDQuery1.FieldByName('IdItels').AsString;
FDQuery1.FieldByName('St02').AsString := 'Text 02 Number : ' + FDQuery1.FieldByName('IdItels').AsString;
FDQuery1.FieldByName('St03').AsString := 'Text 03 Number : ' + FDQuery1.FieldByName('IdItels').AsString;
FDQuery1.Post();
end;
// Dont use Commit inside loop. You should call Commit after you loop logic
// FDConnection1.Commit;
end;
FDConnection1.Commit;
finally
FDConnection1.Close();
FDQuery1.Free();
FDConnection1.Free();
end;
Upvotes: 0