TCustomADODataSet捕获EOleException(不是EDatabaseError)

时间:2014-01-06 11:23:11

标签: delphi ado

在某些情况下(在多用户环境中)当我Edit TADODataSetPost时,我会收到ADO引发的异常:

  

“无法找到行进行更新。某些值可能已更改   因为它是最后一次阅读。“

如果我从IDE运行我的程序,异常将被引发为EOleException,错误号为-2147217864
我希望能够捕获此异常,但是当我在IDE外部运行程序时,异常会引发为EDatabaseError,但我没有需要检查的ErrorCode。这是我的代码的一部分:

procedure TForm1.DataSetCommit(ds: TADODataSet);
begin
  ds.Connection.BeginTrans;
  try    
    try
      ds.Post; // <- Exception is raised here
    except
      on E: EOleException do; // EOleException is NOT fired! (E.ErrorCode = -2147217864) - see "ADODB.TCustomADODataSet.InternalPost"
      on E: EDatabaseError do 
      begin
        // todo: Handle this situation
      end;
    end;
    ds.Connection.CommitTrans;
  except
    ds.Connection.RollbackTrans;
    raise;
  end;
end;

如果你查看ADODB.TCustomADODataSet.InternalPost,你会注意到它被包裹起来:

procedure TCustomADODataSet.InternalPost;
begin
  UpdateCursorPos;
  try
    ... // <- Exception is raised here
  except
    on E: Exception do
      DatabaseError(E.Message);
  end;
  CheckForFlyAway;
end;

在本地过程UpdateData内引发异常:Recordset.Update(EmptyParam, EmptyParam);触发EOleException(我需要的)但包装器引发EDatabaseError! (grrrrrrr)。

我的问题是如何抓住原始EOleException,以便查询EOleException.ErrorCode

1 个答案:

答案 0 :(得分:2)

我试图利用System.RaiseListTRaiseFrame.NextRaise无济于事 - 我没有得到理想的EOleException ...所以我找到了一个相当优雅的解决方案是具体到我的案例(ADO)并且不依赖于RTL - 我正在测试Errors的{​​{1}}对象:

TADODataSet.Connection

这将是我对特定问题的解决方案,但我仍然对如何捕获先前procedure TForm1.DataSetCommit(ds: TADODataSet); begin ds.Connection.BeginTrans; try try ds.Post; except on E: EDatabaseError do begin if Assigned(ds.Connection.Errors) and (ds.Connection.Errors.Count > 0) then with ds.Connection.Errors.Item[0] do // if (Number = -2147217864) then ... ShowMessage(Format('Number:%d; Source:%s; Description:%s; NativeError:%d; SQLState:%s', [Number, Source, Description, NativeError, SQLState])); end; end; ds.Connection.CommitTrans; except ds.Connection.RollbackTrans; raise; end; end; 例外的其他想法感兴趣。