14.6.2 实现异常保护的TRY...FINALLY语句 上面的程序存在着潜在的危险,在实际应用过程中,可能因为某些原因使得对数据库表的更新不能进行下去。如当程序试图执行Post方法将修改后的记录写回磁盘时,而又因为某种原因磁盘没有准备好,这时便出现了异常。当出现异常时,应用程序会暂停下来并且会弹出一对话框显示有关的错误信息,在用户单击错误信息对话框之后,程序将继续执行到某一个地方去,而这个地方常常不是用户所能预料到的。在我们的程序中, 在执行Post方法之前,窗体中所有的部件与TTable部件都已失去联系。因此,这种异常将导致窗体中显示的数据和数据库无关。 Object Pascal中的Try...Finally语句为我们解决上述异常问题提供了一个解决方法。在Delphi中仍然采用了这一语句用来处理异常问题。实际上,Try...Finally 语句是把两组语句组合在一起。语句的Try部分包含了可能产生异常的程序代码,Finally部分包含了即使发生了异常也必须执行的一条或多条语句。在本例中, Finally 部分只包含了EnableControls方法调用这一条语句,我们将前面的代码改写并组合进Try...Finally 语句: with Table Do begin DisableControls;{在修改记录的过程中,使其它部件无效} Try; First; {将记录指针指向第一条记录} while not EOF do begin <读取记录的一个字段值到一个变量中> <做适当的修改> Edit; {将TTable部件置成编辑状态} <将修改后的字段值写回到其对应的字段> post; {将修改后的记录写回数据库} next; {修改下一条记录} end; enablecontrols; Finally;{出现异常时,执行下面的程序} enablecontrols; {恢复其它部件的功能} end; {结束Try...Finally语句} end; 在保留字Try和Finally之间的代码跟前面的代码是一样的,它们用于在记录之间移动记录指针并处理对记录的修改,这一段代码可能会出现异常,当异常发生时,我们想保证执行EnableControls,以便窗体中各控件恢复与 TTable 部件的联系, 因此我们必须将EnableControls语句放在Finally和结束语句End之间。 在这里要特别注意,请读者们不要混淆了Try...Finally语句和Try...Except 语句。如果真正想在发生异常时采取相应的处理,就要使用Try...Except语句。Try... Finally语句只是用来处理当异常出现时,使应用程序执行Finally部分的语句,使程序继续执行下去。Try...Except语句是实现异常处理,Try...Finally语句是实现异常保护。 有了上述这些概念,我们便可以提供这个例子的一些程序代码,它涉及了所有这些内容。 程序清单:修改数据库中的记录 unit Unit26; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, DBGrids, ExtCtrls, DB, DBTables, Buttons; type TForm1 = class(TForm) DataSource1: TDataSource; customerTable: TTable; Panel1: TPanel; DBGrid1: TDBGrid; Panel2: TPanel; UpperCaseFirstAddBtn: TButton; UpperCaseSecondAddBtn: TButton; MixedCaseFirstAddBtn: TButton; MixedCaseSecondAddBtn: TButton; BitBtn1: TBitBtn; procedure ForceCase(TargetField:String;ToUpper:Boolean); procedure UpperCaseFirstAddBtnClick(Sender: TObject); procedure MixedCaseFirstAddBtnClick(Sender: TObject); procedure UpperCaseSecondAddBtnClick(Sender: TObject); procedure MixedCaseSecondAddBtnClick(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation const upper=true; Mixed=False; {$R *.DFM} Function IsUpper(ch:char):Boolean; begin If (ch>='A')and(ch<='Z')then IsUpper:=true else IsUpper:=False; end; procedure TForm1.ForceCase(TargetField:String;ToUpper:Boolean); var WorkBuffer:string; i:Integer; begin with customerTable do begin DisableControls; TRY First; {将记录指针移到第一条记录处 } While not EOF do begin WorkBuffer:=FieldByName(TargetField).AsString; If ToUpper then for i:=1 to Length(WorkBuffer)do WorkBuffer[i]:=UpCase(WorkBuffer[i]) else begin for i:=1 to Length(WorkBuffer) do If IsUpper(WorkBuffer[i]) then WorkBuffer[i]:=chr(ord(WorkBuffer[i])+32); WorkBuffer[1]:=UpCase(WorkBuffer[1]) end; Edit; FieldByName(TargetField).AsString:=WorkBuffer; post; Next; end; Finally enableControls; end; end; end; procedure TForm1.UpperCaseFirstAddBtnClick(Sender: TObject); begin ForceCase('Addr1',Upper); end; procedure TForm1.MixedCaseFirstAddBtnClick(Sender: TObject); begin ForceCase('Addr1',Mixed); end; procedure TForm1.UpperCaseSecondAddBtnClick(Sender: TObject); begin ForceCase('Addr2',Upper); end; procedure TForm1.MixedCaseSecondAddBtnClick(Sender: TObject); begin ForceCase('Addr2',Mixed); end; procedure TForm1.FormCreate(Sender: TObject); begin customerTable.open; end; end.  
2/2 首页 上一页 1 2 |