14.6.2 實現(xiàn)異常保護(hù)的TRY...FINALLY語句
上面的程序存在著潛在的危險,在實際應(yīng)用過程中,可能因為某些原因使得對數(shù)據(jù)庫表的更新不能進(jìn)行下去。如當(dāng)程序試圖執(zhí)行Post方法將修改后的記錄寫回磁盤時,而又因為某種原因磁盤沒有準(zhǔn)備好,這時便出現(xiàn)了異常。當(dāng)出現(xiàn)異常時,應(yīng)用程序會暫停下來并且會彈出一對話框顯示有關(guān)的錯誤信息,在用戶單擊錯誤信息對話框之后,程序?qū)⒗^續(xù)執(zhí)行到某一個地方去,而這個地方常常不是用戶所能預(yù)料到的。在我們的程序中, 在執(zhí)行Post方法之前,窗體中所有的部件與TTable部件都已失去聯(lián)系。因此,這種異常將導(dǎo)致窗體中顯示的數(shù)據(jù)和數(shù)據(jù)庫無關(guān)。
Object Pascal中的Try...Finally語句為我們解決上述異常問題提供了一個解決方法。在Delphi中仍然采用了這一語句用來處理異常問題。實際上,Try...Finally 語句是把兩組語句組合在一起。語句的Try部分包含了可能產(chǎn)生異常的程序代碼,F(xiàn)inally部分包含了即使發(fā)生了異常也必須執(zhí)行的一條或多條語句。在本例中, Finally 部分只包含了EnableControls方法調(diào)用這一條語句,我們將前面的代碼改寫并組合進(jìn)Try...Finally 語句:
with Table Do
begin
DisableControls;{在修改記錄的過程中,使其它部件無效}
Try;
First; {將記錄指針指向第一條記錄}
while not EOF do
begin
<讀取記錄的一個字段值到一個變量中>
<做適當(dāng)?shù)男薷?gt;
Edit; {將TTable部件置成編輯狀態(tài)}
<將修改后的字段值寫回到其對應(yīng)的字段>
post; {將修改后的記錄寫回數(shù)據(jù)庫}
next; {修改下一條記錄}
end;
enablecontrols;
Finally;{出現(xiàn)異常時,執(zhí)行下面的程序}
enablecontrols; {恢復(fù)其它部件的功能}
end; {結(jié)束Try...Finally語句}
end;
在保留字Try和Finally之間的代碼跟前面的代碼是一樣的,它們用于在記錄之間移動記錄指針并處理對記錄的修改,這一段代碼可能會出現(xiàn)異常,當(dāng)異常發(fā)生時,我們想保證執(zhí)行EnableControls,以便窗體中各控件恢復(fù)與 TTable 部件的聯(lián)系, 因此我們必須將EnableControls語句放在Finally和結(jié)束語句End之間。
在這里要特別注意,請讀者們不要混淆了Try...Finally語句和Try...Except 語句。如果真正想在發(fā)生異常時采取相應(yīng)的處理,就要使用Try...Except語句。Try... Finally語句只是用來處理當(dāng)異常出現(xiàn)時,使應(yīng)用程序執(zhí)行Finally部分的語句,使程序繼續(xù)執(zhí)行下去。Try...Except語句是實現(xiàn)異常處理,Try...Finally語句是實現(xiàn)異常保護(hù)。
有了上述這些概念,我們便可以提供這個例子的一些程序代碼,它涉及了所有這些內(nèi)容。
程序清單:修改數(shù)據(jù)庫中的記錄
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.
相關(guān)推薦:2010年9月計算機(jī)等級考試試題及答案解析專題北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |