【问题标题】:Abort SQL Query with process time limit使用进程时间限制中止 SQL 查询
【发布时间】:2013-02-03 16:12:39
【问题描述】:

我可以使用 DELPHI、dbgo DB 组件和 SQL Server 数据库服务器编写 SQL 查询吗?

喜欢

select * from table where ......  

process_time_limit = 5 sec?

最好在一个时间限制内给我 10% 的行,而不是等待完整的查询数据集

【问题讨论】:

  • 当达到 5 秒时,您希望发生什么?您可以处理的异常还是其他?您使用的是什么版本(也许资源管理器可以在这里提供帮助)。
  • 另见 stackoverflow.com/questions/5077051/… - CommandTimeout 可能会有所帮助,但这可能取决于其他几个因素。
  • 也许您应该避免启动需要数小时才能完成的查询。
  • @TOndrej:有时您只需要这些信息 :-)
  • @TOndrej:是的,我并不是反对你的观点。但是,当您需要遍历 200 甚至 20 GB 的数据来获取所需的信息时,无论您的数据库和/或查询如何优化,都需要时间。也许您可以将查询拆分为较小的查询,但具有临时结果的多个查询可能只是“隐藏”(并增加)获得答案所需的总时间。

标签: sql-server delphi ado


【解决方案1】:

ADO 组件:

我会尝试异步数据获取。当你执行查询时,你会记得你什么时候开始的,每次OnFetchProgress事件触发时,你会检查EventStatus是否仍处于esOK状态并检查从查询执行。如果它过去了,您可以通过在数据集上使用 Cancel 方法来取消数据提取。

我的意思是使用类似以下(未经测试的)伪代码:

var
  FQueryStart: DWORD;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // configure the asynchronous data fetch for dataset
  ADOQuery1.ExecuteOptions := [eoAsyncExecute, eoAsyncFetchNonBlocking];
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // store the query execution starting time and execute a query
  FQueryStart := GetTickCount;
  ADOQuery1.SQL.Text := 'SELECT * FROM Table';
  ADOQuery1.Open;
end;

procedure TForm1.ADOQuery1FetchProgress(DataSet: TCustomADODataSet; Progress,
  MaxProgress: Integer; var EventStatus: TEventStatus);
begin
  // if the fetch progress is in esOK (adStatusOK) status and the time since
  // the query has been executed (5000 ms) elapsed, cancel the query
  if (EventStatus = esOK) and (GetTickCount - FQueryStart >= 5000) then
    DataSet.Cancel;
end;

【讨论】:

  • 嗯,Cancel 的文档说:“如果这些更改尚未发布,则取消对活动记录的修改。”您确定它可以用于此处的预期目的 - 取消下一次提取吗?
  • 感谢分享这个想法,我会尝试一下
猜你喜欢
  • 2019-04-23
  • 2011-08-02
  • 2012-03-09
  • 2010-11-13
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多