E N D
第二十一章 ActiveX Data Objects • 前面第17 章, 筆者已講述Borland Database Engine (簡稱BDE) 模式的資料庫操作, 本章的ActiveX Data Objects(以下簡稱ADO)則是微軟所大力推廣的資料庫存取模式。而Borland 公司的Delphi 及C++Builder 亦支援此模式, 故可以使用ADO 封裝的元件撰寫資料庫程式。ADO 的資料來源元件, 如下圖所示, 其中ADOTable 及ADOQuery 的功能與BDE 的Table 及Query 的用法相近。 • ADO與資料聯繫物件 • 資料庫編輯的方式 • 主副明細 • 報表的製作
ADO 與BDE 的關係 • 前面第16 章, 我們已說明BCB 的資料存取模式共有4 種, 分別是BDE 、ADO 、dbExpress 及InterBase, 其存取模式如下圖所示, 其中BDE 、ADO、dbExpress 及InterBase 稱為資料源元件。 • 於BDE 模式中, 我們已介紹使用Table 、Query 及QuickRep 等元件展示、查詢、新增、修改、刪除及列印資料庫的內容。本單元則要使用ADO模式, 重複完成以上資料庫的基本操作工作。其次, 由上圖中, 讀者將不難發現, 要使用ADO 模式完成以上資料庫基本操作, 只要將BDE 標籤的元件以ADO 標籤的元件代替即可, 請看以下各節介紹。
2 1 -1 ADO 與資料連繫物件 • 前面第17-1 節, 我們已使用BDE 模式展示資料庫的內容, 若使用ADO模式, 則只要將BDE 模式的Table 元件以ADO 模式的ADOTable 元件取代即可, 請看以下範例說明。
範例21-1a • 請以ADOTable 元件配合資料庫連繫元件, 展示school.mdb 的stugrade 資料表。
2 1 - 2 資料庫編輯的方式 • 於BDE 模式中, 資料的編輯是使用Table 與Query 元件, 於ADO 模式, 則有ADOTable 與ADOQuery 與之對應。
ADOTable ADOTable 與Table 都是一種逐一瀏覽的方式編輯資料庫, 此種資料編輯方式, 本書歸納以下幾個單元, 分別是資料項的表示、記錄指標的移動、記錄的新增、記錄的刪除、記錄的更正、記錄的搜尋及記錄的排序。 • 資料項 ADOTable 元件的資料項表示法如下,其中FieldByName 與Fields[欄位索引]應加上型別轉換函式。 ADOTable1->FieldValues[" 欄位名稱"] ; ADOTable1->FieldByName(" 欄位名稱")->型別轉換函數; ADOTable1->Fields->Fields[欄位索引]->型別轉換函數;
在以上敘述中,型別轉換函式可為AsVariant 、AsString 、AsInteger 、AsFloat 、AsCurrency 、AsDateTime 及AsBoolean 等。如果要將資料項放入Text1 物件,則應加上AsString ,將型別轉換為String 型別。例如,以下敘述可將欄位順序為0 的Name 欄位放入Edit1 物件。 Edit1->Text = ADOTable1->FieldValues["Name"] ; Edit1->Text = ADOTable1->FieldByName("Name")->AsString ; Edit1->Text = ADOTable1->Fields->Fields[0]->AsString ; • 若已將欄位物件加入欄位編輯器,則亦可使用欄位物件名稱代表某一資料項。例如,以下敘述可存取Name 資料項的內容。 ADOTable1Name->Value ; // 要注意大小寫 ADOTable1Name->AsString ;
記錄指標 當我們使用ADOTable 物件開啟資料表時, 不管記錄的多寡, 均存在一個稱為記錄指標的東西, 指向資料表的第一筆記錄, 我們稱此記錄為作用中的記錄, 此時若進行資料項的編輯, 則其操作對象即為此記錄指標所指的記錄, 如下圖所示。
範例21-2a • 示範各種資料項的用法與記錄指標的移動。
欄位編輯視窗 • 於表單的資料源元件圖項按二下, 即可出現欄位編輯視窗, 使用者可於欄位編輯視窗新增一些欄位物件。下圖右的ADOTable1name 、ADOTable1chi 及ADOTable1eng 即為新增的欄位物件, 此時即可於程式中使用欄位物件存取資料項, 以下敘述可將ADOTable1name 的內容指定由Edit1顯示。 Edit1->Text=ADOTable1name->AsString ;
範例21-2b • 請以欄位物件重做以上範例。
記錄的新增 • 於資料表中欲新增一筆記錄, 其方法為使用Insert 及Post 方法, 其中Insert 是告訴資料庫即將新增記錄、Post 是將位於記憶體緩衝區的資料回存至資料庫。其中資料項的表示, 本例示範FieldByName (" 欄位名稱") 的使用方式, 讀者可自行使用上一單元所介紹的其它資料項表示法。例如, 以下敘述可分別插入一個字串與一個數值型別的記錄。
// 以下敘述使用了型別轉換函數AsStr ing 及AsInteger ADOTable1->Insert() ; // 欄位1 的型別為String ADOTable1->FieldByName(" 欄位名稱1")->AsString = Edit1->Text ; // 欄位2 的型別為Integer ADOTable1->FieldByName(" 欄位名稱2")->AsInteger = StrToInt(Edit2->Text) ; ADOTable1->Post() ; • 以下程式片段, 可於Test1.mdb 的grade 資料表新增一筆記錄。 // 以下敘述使用了型別轉換函數AsStr ing 及AsInteger ADOTable1->Insert() ; ADOTable1->FieldByName("Name")->AsString = "謝承佑" ; ADOTable1->FieldByName("Chi")->AsInteger = 92 ; ADOTable1->FieldByName("Eng")->AsInteger = 88 ; ADOTable1->Post() ;
範例21-2c • 示範記錄的新增(本例使用test1.mdb 的grade 資料表)。
記錄的刪除 • 刪除記錄的方法是Delete 。其語法如下: ADOTab le 1.De le te ; 那到底是刪除那一筆記錄呢?答案是刪除記錄指標所指的記錄, 請看以下範例。
範例21-2d • 示範記錄的刪除(資料表、表單均同上範例)
記錄的更正 • 記錄的更正是使用Edit 及Post 的方法, 其語法如下: ADOTable1->Edit() ; ADOTable1->FieldByName(" 欄位名稱1")->AsString = Edit1->Text ; ADOTable1->FieldByName(" 欄位名稱2")->AsInteger = StrToInt(Edit2->Text) ; / / 注意型別轉換 ADOTable1->Post() ; • 但是如果我們在表單中使用了資料感知元件(例如, DBEdi t),則您只要更改了資料感知元件中的內容,使用以下敘述即可將更改後的內容寫入資料庫中。 ADOTable1->Post() ; • 以下程式片段可更正grade 資料表的記錄指標所在記錄。 ADOTable1->Edit() ; ADOTable1->FieldByName("Name")->AsString = "孫大明" ; ADOTable1->FieldByName("Chi")->AsInteger = 22 ; ADOTable1->FieldByName("Eng")->AsInteger = 33 ; ADOTable1->Post() ;
範例21-2e 示範記錄的更正(資料表同上範例)。 1. 下圖是程式執行結果的初始畫面, 筆者已將記錄指標移至" 朱安琪" 這筆記錄, 右邊的三個DBEdit 元件因是連繫元件的關係, 亦同時顯示" 朱安琪" 的資料。
2. 下圖是按一下" 更正記錄指標的內容", 此按鈕執行以下程式片段, 所 以執行結果, 如下圖所示。 / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - / / 更正一筆記錄 void _ _fastcall TForm1::btnEdit1Click(TObject *Sender) { ADOTable1->Edit() ; ADOTable1->FieldByName("Name")->AsString = "謝承佑" ; ADOTable1->FieldByName("Chi")->AsInteger = 92 ; ADOTable1->FieldByName("Eng")->AsInteger = 88 ; ADOTable1->Post() ; } / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3. 下圖左是按一下" 更正以上記錄" 的結果, 此按鈕執行以下程式片段,其功能是將連繫物件DBText 的內容回存資料庫。 / / 將連繫元件的結果回存資料庫 void _ _fastcall TForm1::btnEdit2Click(TObject *Sender) { ADOTable1->Post() ; }
4. 下圖右是按一下" 將國文分數加百分之十" 的結果, 此按鈕的程式片段如下: void _ _fastcall TForm1::btnEdit3Click(TObject *Sender) { ADOTable1->First() ; while (! ADOTable1->Eof) { ADOTable1->Edit() ; ADOTable1->FieldByName("Chi")->AsInteger = ADOTable1->FieldByName("Chi")->AsInteger * 1.1 ; ADOTable1->Post() ; ADOTable1->Next() ; } }
記錄的搜尋 ADO 模式中記錄的搜尋, 其方法有Locate 及Filter, 分別說明如下: • Locate Locate 的語法如下: virtual bool _ _fastcall Locate(const AnsiString KeyFields, const System::Variant &KeyValues, TLocateOptions Options); • 以上語法說明如下: • KeyFields: 欲搜尋的欄位名稱。 • KeyValues: 欲搜尋的欄位值。 • Options: 搜尋方式。其型別是TlocateOptions 的集合型別, 如下所示, 其中loCaseInsensitive 是表示搜尋時大小寫不分, loPartialKey 是部份字元符合即可, 例如輸入" 學樂", 若有" 學樂出版社" 或" 學樂出版有限公司", 均符合搜尋條件。 enum TLocateOption {loCaseInsensitive, loPartialKey}; • 當搜尋成功時, Locate 函數傳回true, 並將記錄指標移到合乎條件的第一筆記錄; 若傳回false, 則記錄指標並不移動。
範例21-2f • 示範記錄的搜尋。
Filter • 上一單元的Locate 較適合做字串的搜尋, 若是數值的搜尋, 例如"chi>60" 或"chi<80" 時, 則無法使用Locate, 像這種搜尋某一範圍的動作, 則較適合使用Filter。Filter 的語法如下: ADOTable1->Filter= " 數值欄位名稱關係運算子條件值" ; ADOTable1->Filtered=true ;
範例21-2g • 示範Filter 屬性的用法。
排序 • ADOTable 元件使用Sort 屬性進行排序, Sort 屬性語法如下, 預設值是升冪ASC, 值得注意的是, ASC 與DESC 一律都必須大寫才行。 ADOTable1->Sort = " 欄位名稱<ASC/DESC>";
範例21-2h • 示範Sort 屬性的用法。
ADOQuery • 於BDE 模式中, 是使用Query 元件執行SQL 字串, 但是ADO 模式中則使用ADOQuery 。關於SQL 的用法, 本書已分別於17-4 節及19 章介紹, 本單元的ADOQuery 的用法則與Query 相近, 以下範例示範如何使用ADOQuery 展示test1.mdb 的grade 資料表。
範例21-2i • 示範ADOQuery 的用法(本例欲以DBGrid 展示test1.mdb 的grade 資料表。
ADOConnection • 前面的ADOTable 及ADOQuery 均較適合一次開啟一個資料表, 但是有些時候您必須同時開啟兩個資料表, 此時若還是使用ADOTable 或ADOQuery開啟資料庫, 則因要設兩次ConnectionString, 所以您的資料庫將被兩個程式所連接而影響執行速度, 所以若要同時開啟兩個資料表, 則應使用ADOConnection 元件。 • 以下範例則示範如何使用ADOConnection 元件連結兩個資料表, 以進行主副明細查詢。
範例21-3a • 示範主副明細查詢, 主要資料表是test1.mdb 的stuname, 次要資料表是stugrd 。
21 - 4 報表的製作 • ADO 報表的製作與BDE 模式的報表製作完全相同, 只要將資料源物件以ADO 標籤的元件替換即可。以下僅以列印test1.mdb 的grade 資料表示範ADO 報表製作, 其餘請自行參考第18 章。
範例21-4a • 示範報表的製作。(本例欲列印test1.mdb 的grade 的資料表)