如何在for循环中使用大量UPDATE正确处理EOleException?

时间:2014-03-31 01:02:36

标签: sql sql-server delphi for-loop exception-handling

我的应用程序的每个工作线程都在远程SQL Server数据库上执行大量UPDATE操作。我使用for..do构造迭代记录集,其中包含用于进一步更新的输入数据:

try
   for i := 0 to RS.RecordCount-1 do
   begin
      // omitting the quotes for brevity
      CN.Execute('my_stored_proc ' + RS.Fields['Dummy'].Value);
      RS.MoveNext;
   end;
 except
   on E: Exception do
   begin
     // At the moment here is a simple notice of the exception thrown
     ShowMessage(E.ClassName + ': ' + E.Message);
   end;

我注意到EOleException =“查询超时已到期”时,E.Message经常被引发。这显然意味着线程等待SQL Server响应然后中止当前请求。然后(根据日志),线程提交新的i值,忽略前一个值。因此,如果EOleException抛出i = 613处理程序只是移动到i = 614并继续工作而留下613处女。

我的问题是:
处理此类异常的正确方法是什么,确保所有记录都会被处理,即使它们导致异常几片回来?

我应该选择while..do / repeat..until构造,我只能在处理程序中Dec(i),还是有更多不拘一格的技术?

1 个答案:

答案 0 :(得分:1)

如果Execute()引发异常,您显示的代码将不会处理下一条记录。而是退出整个循环。要做你想要的,你需要处理循环内部的异常,而不是在外面。

您也不应该使用RecordCount属性。请改用Eof属性。

试试这个:

try
  while not RS.Eof do
  begin
    try
      // omitting the quotes for brevity
      CN.Execute('my_stored_proc ' + RS.Fields['Dummy'].Value);
    except
      on E: EOleException do
      begin
        if E.Message = 'Query timeout expired' then
          Continue;
        raise;
      end;
    end;
    RS.MoveNext;
  end;
except
  on E: Exception do
  begin
    // At the moment here is a simple notice of the exception thrown
    ShowMessage(E.ClassName + ': ' + E.Message);
  end;
end;