在某些情况下(在多用户环境中)当我Edit
TADODataSet
和Post
时,我会收到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
?
答案 0 :(得分:2)
我试图利用System.RaiseList
让TRaiseFrame.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;
例外的其他想法感兴趣。