本地数据库用ADO方式来做程序,在缓存更新等一直悬而未决的问题都在大家的帮助下解决
了。原想以后都用ADO方式来开发程序。可没想到路上又跑来LOCATE这个拦路虎,却没仔细
看清书上的解释,所以放弃了ADO。于是鲁鲁莽莽的上来提问题。今天一个项目终于开发结
束。在休息之余,又抱起了李维大师的那本书,仔仔细细的再看了一遍第125页至127页,终
于发现,我看书不认真。现在LOCATE的错误未能捕捉是DELPHI对ADO的一个疏漏,而非它的
BUG。我想这样的问题,可能很多人会遇到,所以就把解决方法告知大家,以供参考:
原本如下:(有这本书的人可以看每125页至127页)
不是臭虫,但是一个疏漏:如果在DELPHI的集成开发环境这外执行这个范例应用程序,那么当搜寻一
个不存在的字段时,应该程序并不会产生错误的信息。这很奇怪,因为在一般 的BDE/IDAPI应用程序
中这样动作应该会产生一个错误信息。而且我们说ADO自己的错误会和开发环境结合在一起,这也
就是说这种错误应该要产生一个错误信息并且让应用程序能够处理。但是,即使把前面“寻找字段数
据”按钮的ONCLICK事件处理程序修改成如下程序代码,使用TRY……EXCEPT程序块也无法拦截到
任何的例外错误:
procedure Tform4.btnSearchFieldClick(Sender:Tobject);
var
bResult: Boolean;
begin
try
bResult:=ADODataSet1.Locate(edtFieldName.Text,edtFieldValue.Text,[loCaseinsensitive,loPartialkey]);
ShowADOErrors;
Except
on E:exception do
showMessage(E.Message);
End;
end;
那么这是不是表示ADO的错误根本没有和DELPHI的例外处理机制结合在一起,因此应用程序无法处理
ADO的错误呢?事实上,这是ADOEXPRESS中的疏漏,在TCustomADODataSet类别的LocateRecord
方法中它吃掉了原应该再传递给外部应用程序的例外对象,因此造成了应用程序无法使用
try……except程序块拦截到任何的例外错误。下面是LocateRecord方法的部分原始程序代码,请观察
LocateRecord也使用了try...except程序块,但是在最后的except部分它只在发生例外时把回传
结果设定为False,却没有再调用Raise把例外对象再传递出去。
function TCustomerADODataSet.LocateRecord(const KeyFields;stinr;
const KeyValues:OleVariant;Options:TLocateOptions;
syncCursor:Boolean):Boolean;
var
Fields:TList;
Buffer
Char;
I,FieldCount:Integer;
Partial:Boolean;
SortList,FieldExpr,LocateFilter:string;
begin
...
try
...
except
result:=False;
end;
end;
因此我们只需要把LocateRecord修改成下面的形式;多加一个Raise指令。让LocateRecord在最
后把例外对象再传递给外部的程序代码,而不要把例外对象吃掉。
function TCustomerADODataSet.LocateRecord(const KeyFields;stinr;
const KeyValues:OleVariant;Options:TLocateOptions;
syncCursor:Boolean):Boolean;
begin
...
try
...
except
result;=False;
Raise; //加上这句
end;
end;
修改之后请重新编译ADODB这个程序单元并且让应用程序和这个新的ADODB连接在一起,再去执行
刚才的范例应用程序并且搜寻一个不存在的字段,那么范例应用程序就可以像BDE/IDAPI的应用程
序一样显示例外错误的信息了。程序员也可使用try...except程序块来处理例外,并且进行客户化。