sqlite - delphi fireac sqlite 提交
问题描述
当我提交时,我天真地认为数据库的物理文件会被更新(更改修改日期),但显然它不是那样工作的。关闭数据库时修改了数据库的物理文件!!!
我用 (delphi 10.2.3) * FDConnection1: TFDConnection; 写了一个小测试应用程序。(所有默认设置) (cachedupdate 为 false) * FDQuery1: TFDQuery; (所有默认设置)
我的 SQLite 数据库只有一个表 CREATE TABLE t_stritems
( IdItels
INTEGER, St01
VARCHAR (200), St02
VARCHAR (200), St03
VARCHAR (200), PRIMARY KEY( 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-杂志)。第一次提交后数据库文件大小为 2338 ko,我的数据库文件目录中始终有日志文件(xxxx.db-journal)。数据库文件大小为 2338 ko(无物理更新) 然后程序添加 32000 条记录 数据库文件(.db)的修改日期只有在我离开我的应用程序时才会被修改。!!!日志文件(.db-log)将在我的应用程序结束时被删除
问题:如何让commit将数据保存到数据库?这是正常的吗?数据库的物理文件仅在应用程序关闭时(以及连接的同时)被修改?
提前感谢您的回答最好的问候Romuald
解决方案
您似乎对如何在 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;
推荐阅读
- iptables - 如何通过 iptables 阻止 FIN-WAIT-2?
- javascript - 在聊天应用程序中获取最新消息 - Django
- nginx - Nginx 反向代理到两个服务
- java - 尝试使用 apache POI 从 excel 表中检索数据
- php - (PHP) 试图控制包含函数
- r - R ggplot2 geom_bar barplot:在不修改数据框的情况下按计数对条形图进行排序,并且因子标签具有含义
- python-datetime - 通过排除 pandas 数据框中的非营业时间来计算两个日期之间的营业时间
- azure - 通过 API 检索 Azure AppInsights 实时指标
- vue.js - Vue没有看到从单独组件传递的函数
- javascript - 如何在 Web Worker 中使用 Azure App Insights?