SQL错误“Query execution was interrupted”后如何重连数据感知组件?
问题复现
当发生Query execution was interruptedSQL错误时,所有数据感知组件(TDBGrid、TDBNavigator)都会断开连接或被禁用,即使在查询操作前后调用数据集的DisableControls()和EnableControls()方法,也无法重新启用这些数据感知组件。
根因说明
- 该SQL错误触发时,数据集的
ControlsDisabled内部计数会出现不匹配:查询前调用DisableControls()会让计数+1,异常中断后EnableControls()没有被正常执行,计数无法归零,数据感知组件会一直处于禁用状态。 - 常用数据集组件(如
TADOQuery、TQuery)在SQL执行中断后,会自动断开与TDataSource的绑定关系,即使后续数据集恢复可用,绑定也不会自动重建。 - 数据感知组件感知到数据集异常后,会被强制置为禁用状态,不会随数据集恢复自动重置。
修复方案
1. 强制复位控件禁用计数
在查询逻辑的try...finally块中,无论是否触发异常,都强制清空ControlsDisabled计数,避免计数不匹配:
try YourDataSet.DisableControls; // 你的SQL查询执行逻辑 YourDataSet.Open; finally // 循环调用直到计数归零,兼容异常中断场景 while YourDataSet.ControlsDisabled do YourDataSet.EnableControls; end;
2. 异常后重建数据源绑定
如果捕获到Query execution was interrupted错误,手动重建数据集与数据源的绑定:
- 先将
TDataSource.DataSet赋值为nil - 关闭异常状态的数据集,清理内部异常标记
- 重新将
TDataSource.DataSet指向目标数据集
3. 手动恢复组件启用状态
绑定完成后,手动重置数据感知组件的启用状态并刷新:
// 重置组件状态 DBGrid.Enabled := True; DBNavigator.Enabled := True; // 刷新数据展示 DBGrid.Refresh;
4. 前置规避方案
如果是查询超时导致的中断,可提前调整查询超时参数;如果中断后数据集残留异常标记难以清理,可直接创建新的数据集实例执行查询,避免异常状态残留。
内容的提问来源于stack exchange,提问作者Allan.A
相关产品推荐
相关产品推荐

