首页 / 软件开发 / Delphi / 第十四章-简单数据库应用的创建及MASTAPP介绍(三)(2)
第十四章-简单数据库应用的创建及MASTAPP介绍(三)(2)2007-05-0714.6.2 实现异常保护的TRY...FINALLY语句 上面的程序存在着潜在的危险,在实际应用过程中,可能因为某些原因使得对数据库表的更新不能进行下去。如当程序试图执行Post方法将修改后的记录写回磁盘时,而又因为某种原因磁盘没有准备好,这时便出现了异常。当出现异常时,应用程序会暂停下来并且会弹出一对话框显示有关的错误信息,在用户单击错误信息对话框之后,程序将继续执行到某一个地方去,而这个地方常常不是用户所能预料到的。在我们的程序中, 在执行Post方法之前,窗体中所有的部件与TTable部件都已失去联系。因此,这种异常将导致窗体中显示的数据和数据库无关。 Object Pascal中的Try...Finally语句为我们解决上述异常问题提供了一个解决方法。在Delphi中仍然采用了这一语句用来处理异常问题。实际上,Try...Finally 语句是把两组语句组合在一起。语句的Try部分包含了可能产生异常的程序代码,Finally部分包含了即使发生了异常也必须执行的一条或多条语句。在本例中, Finally 部分只包含了EnableControls方法调用这一条语句,我们将前面的代码改写并组合进Try...Finally 语句: with Table DobeginDisableControls;{在修改记录的过程中,使其它部件无效}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 usesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, DBGrids, ExtCtrls, DB, DBTables, Buttons; typeTForm1 = 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; varForm1: TForm1; implementationconstupper=true;Mixed=False; {$R *.DFM}Function IsUpper(ch:char):Boolean;beginIf (ch>="A")and(ch<="Z")thenIsUpper:=trueelseIsUpper:=False;end;procedure TForm1.ForceCase(TargetField:String;ToUpper:Boolean);varWorkBuffer:string;i:Integer;beginwith customerTable dobeginDisableControls;TRYFirst; {将记录指针移到第一条记录处 }While not EOF dobeginWorkBuffer:=FieldByName(TargetField).AsString;If ToUpper thenfor i:=1 to Length(WorkBuffer)doWorkBuffer[i]:=UpCase(WorkBuffer[i])elsebeginfor i:=1 to Length(WorkBuffer) doIf IsUpper(WorkBuffer[i]) thenWorkBuffer[i]:=chr(ord(WorkBuffer[i])+32);WorkBuffer[1]:=UpCase(WorkBuffer[1])end;Edit;FieldByName(TargetField).AsString:=WorkBuffer;post;Next;end;FinallyenableControls;end;end;end; procedure TForm1.UpperCaseFirstAddBtnClick(Sender: TObject);beginForceCase("Addr1",Upper);end; procedure TForm1.MixedCaseFirstAddBtnClick(Sender: TObject);beginForceCase("Addr1",Mixed);end;procedure TForm1.UpperCaseSecondAddBtnClick(Sender: TObject);beginForceCase("Addr2",Upper);end;procedure TForm1.MixedCaseSecondAddBtnClick(Sender: TObject);beginForceCase("Addr2",Mixed);end;procedure TForm1.FormCreate(Sender: TObject);begincustomerTable.open;end; end.