【问题标题】:delphi firedac sqlite commitdelphi fireac sqlite 提交
【发布时间】:2018-09-13 11:52:12
【问题描述】:

当我提交时,我天真地认为数据库的物理文件会被更新(更改修改日期),但显然它不是那样工作的。 关闭数据库时修改数据库的物理文件!!!

我用 (delphi 10.2.3) 编写了一个小测试应用程序 * FDConnection1:TFDConnection; (所有默认设置)(cachedupdate 为 false) * FDQuery1:TFDQuery; (所有默认设置)

我的 SQLite 数据库只有一张表 创建表t_stritemsIdItels整数,St01VARCHAR(200),St02VARCHAR(200),St03VARCHAR(200),主键(IdItels))

我的代码很简单

连接数据库:

  FDConnection1.Connected := false;
  FDConnection1.Params.Clear;
  FDConnection1.Params.Add('DriverID=SQLite');
  FDConnection1.Params.ADD('Database=' + Edit1.text);
  FDConnection1.Connected := true;

向数据库中插入行

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;

测试过程: 连接数据库:(我数据库的t_stritems文件包含32000条记录;数据库文件大小为2338 ko) 删除 sql 后,我的数据库文件目录中有一个日志文件(xxxx.db-journal)。数据库文件大小为 2338 ko 在第一次提交之后,我总是在我的数据库文件的目录中保存日志文件(xxxx.db-journal)。数据库文件大小为 2338 ko(无物理更新) 然后程序添加 32000 条记录 数据库文件(.db)的修改日期只有在我离开我的应用程序时才会被修改。 !!! 日志文件 (.db-log) 将在我的应用程序结束时被删除

问题: 如何使提交将数据保存到数据库? 这是正常的吗? 数据库的物理文件只有在应用程序关闭时(并且在连接的同时)才被修改?

提前感谢您的回答 最好的祝福 罗莫尔德

【问题讨论】:

    标签: sqlite delphi commit firedac


    【解决方案1】:

    您似乎对如何在 Delphi 中使用数据库感到困惑。

    1) 首先,您需要在代码中添加 try/finally 以捕获任何异常并防止内存泄漏。

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

    3) 提交必须在循环结束时使用。当您完成数据更新后,您可以调用 Commit 来执行您对字段所做的所有更新。

    为了实现我上面的建议,我将如何重写您的代码:

      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;
    

    【讨论】:

    • 您好,谢谢您的评论您是对的,try finally 是有用的,但这不是问题(实际上没有创建和查询的连接)在我看来,firedac正在自动创建交易。想象一下,在我的循环中,我做了一个很长的处理,例如,我调用了一个会做很多事情的函数,作为这个函数的回报,我在我的表中插入了结果。并且这两个循环的过程所有的所有数据执行大约需要十个小时。
    • 在这种情况下,我将在循环中提交,而不是在所有处理结束时提交。当然,我确信我的处理方式尊重所有数据的完整性。我的主要问题是,当您提交时,数据库磁盘上的物理大小以及基础的修改日期不会改变。仅当您关闭连接时,这些属性才会更改。如果你修改循环使100000或150000插入,你会看到当你关闭连接时,需要一段时间才能关闭,你会看到指针sql。即使你之前提交过。
    • 顺便说一句,如果你想插入数据,你必须在帖子之前进行追加或插入以避免异常;-)。确实,经过 20 年的 delphi,我还有很多东西要学。
    猜你喜欢
    • 2014-11-23
    • 1970-01-01
    • 2014-05-17
    • 2016-02-12
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2019-06-18
    相关资源
    最近更新 更多