Welcome

首页 / 软件开发 / 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 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.