DELPHI中FDQuery批量插入数据接口关联进度条实现问题
进度条逻辑实现方案
你当前使用的单条INSERT ... SELECT语句属于数据库端一次性执行的原子操作,FireDac无法直接获取这条语句的内部执行进度,你可以根据需求选择以下两种方案实现进度条:
方案1:显示真实迁移进度(推荐)
需要将一次性批量执行改为分批分页迁移,代码调整逻辑如下:
- 先统计需要迁移的总记录数,初始化进度条参数:
DataModule2.FDQueryTemp.Close; DataModule2.FDQueryTemp.Sql.Clear; DataModule2.FDQueryTemp.Sql.Add('SELECT COUNT(*) AS migrate_total FROM tbllogs WHERE Datetimelog < date_sub(NOW(), INTERVAL 1 month);'); DataModule2.FDQueryTemp.Open; var total := DataModule2.FDQueryTemp.FieldByName('migrate_total').AsInteger; ProgressBar1.Max := total; ProgressBar1.Position := 0;
- 按固定批次大小分批迁移,每完成一批更新一次进度条:
var offset := 0; // 批次大小可根据服务器性能调整,建议设置为500-2000 const BATCH_SIZE = 1000; while offset < total do begin DataModule2.FDQueryInsertExceed.Close; DataModule2.FDQueryInsertExceed.Sql.Clear; DataModule2.FDQueryInsertExceed.Sql.Add('INSERT IGNORE INTO tblLogs'); DataModule2.FDQueryInsertExceed.Sql.Add(Format('SELECT * FROM tbllogs WHERE Datetimelog < date_sub(NOW(), INTERVAL 1 month) LIMIT %d OFFSET %d;', [BATCH_SIZE, offset])); var affected_rows := DataModule2.FDQueryInsertExceed.ExecSQL; // 更新进度条 ProgressBar1.Position := ProgressBar1.Position + affected_rows; offset := offset + BATCH_SIZE; // 避免界面无响应 Application.ProcessMessages; end;
方案2:无真实进度的等待提示
如果你不想修改原有执行逻辑,可以使用不确定模式的进度条,仅提示用户任务正在运行:
- 在
ExecSQL执行前开启进度条滚动动画 - 执行完成后关闭动画即可
如果要避免界面卡死,可以开启FireDac的异步执行模式:设置FDQueryInsertExceed.ResourceOptions.CmdExecMode := amAsync;,绑定OnEndExec事件处理执行完成后的逻辑。
FireDac官方手册说明
FireDac组件的完整官方手册直接集成在Delphi/C++ Builder的IDE帮助系统中,你可以在IDE中选中FD组件后按F1直接跳转到对应组件的说明文档,也可以直接在IDE帮助中心搜索FireDac关键词检索全量文档,文档覆盖了组件属性、方法说明、最佳实践、性能优化等所有使用场景的内容。
内容的提问来源于stack exchange,提问作者FPSI TS4
相关产品推荐
相关产品推荐

