TCustomADODataSet捕获EOleException(不是EDatabaseError)

kob*_*bik 5 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;
Run Code Online (Sandbox Code Playgroud)

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

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

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

我的问题是我如何获得原件EOleException以便我可以查询EOleException.ErrorCode

kob*_*bik 2

我试图利用 来System.RaiseList获得TRaiseFrame.NextRaise无济于事 - 我没有得到想要的EOleException......所以我找到了一个相当优雅的解决方案,它特定于我的情况(ADO)并且不依赖于 RTL - 我' m 测试Errors的对象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;
Run Code Online (Sandbox Code Playgroud)

这将是我对特定问题的解决方案,但我仍然对如何捕获先前的异常的其他想法感兴趣EOleException