简体   繁体   English

delphi firedac sqlite提交

[英]delphi firedac sqlite commit

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; 我用(delphi 10.2.3)编写了一个小测试应用程序* FDConnection1:TFDConnection; (all default setting) (cachedupdate is false) * FDQuery1: TFDQuery; (所有默认设置)(cachedupdate为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 ) ) 我的SQLite数据库只有一个表CREATE TABLE t_stritemsIdItels 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). 测试过程:连接数据库:(我数据库的t_stritems文件包含32000条记录;数据库文件的大小为2338 ko)删除sql之后,我在数据库文件目录中有一个日志文件(xxxx.db-日志)。 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). 第一次提交后,数据库文件大小为2338 ko,我始终在数据库文件目录中保留日志文件(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. 数据库文件大小为2338 ko(无物理更新),然后程序将添加32000条记录。仅当我离开应用程序时,才会修改数据库文件(.db)的修改日期。 !!! the journal file (.db-log) will be deleted at the end of my application 日志文件(.db-log)将在我的应用程序末尾删除

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 预先感谢您的回答最好的问候Romuald

It seems that you are confused on how to use databases in Delphi. 您似乎对如何在Delphi中使用数据库感到困惑。

1) First of all you need to add try/finally in your code in order to catch any exceptions and prevent memory leaks. 1)首先,您需要在代码中添加try / finally,以便捕获任何异常并防止内存泄漏。

2) Use connection.StartTransaction - connection.Commit paired. 2)使用connection.StartTransaction-connection.Commit配对。

3) Commit must be used at the end of your loop. 3)必须在循环结束时使用commit。 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM