C++Builder 5 引入 ADOExpress (dbGo) 元件套件,將 Microsoft ADO (ActiveX Data Objects) 封裝為 VCL 元件,提供與 BDE/IBX 相似的設計時體驗,但底層直通 OLE DB Provider,支援 無 DSN 連線、斷開式記錄集、XML 持久化、ASP/COM+ 整合 等現代特性。遷移既有 BDE 專案只需替換資料存取元件,資料感知控制項 (TDBGrid, TDBEdit 等) 完全相容。
| 元件 | 用途 | 對應傳統元件 |
|---|---|---|
TADOConnection | 資料庫連線管理、交易控制 | TDatabase |
TADOTable | 單一資料表操作 (索引、篩選、編輯) | TTable |
TADOQuery | SQL 查詢、更新、預存程序 | TQuery |
TADODataSet | 通用資料集 (支援 Shape、命令文字、存取程序) | TQuery/TTable 合體 |
TADOCommand | 執行不傳回資料集的命令 (DDL、DML、Action Query) | TQuery (ExecSQL) |
TADOStoredProc | 預存程序執行 | TStoredProc |
TDataSource | 資料集與資料感知控制項橋樑 | TDataSource (同樣) |
雙擊 TADOConnection → ConnectionString 屬性省略號 → 建立:
Jet OLEDB:Database Password=xxx)。程式碼設定:
ADOConnection1->ConnectionString =
"Provider=Microsoft.Jet.OLEDB.4.0;"
"Data Source=C:\\Data\\Northwind.mdb;"
"Jet OLEDB:Database Password=secret;"
"Persist Security Info=False;";
ADOConnection1->Connected = true;
ADO 支援 Shape 指令 定義階層式資料集,無需撰寫嵌套查詢程式碼即可實現主/從表關聯。
// 設計時設定元件
// ADOConnection1: 已設定 ConnectionString, Connected=true
// ADODataSet1 (Master): Connection=ADOConnection1
// ADODataSet2 (Detail): 稍後設定 DataSetField
// DataSource1 -> ADODataSet1 -> DBGrid1
// DataSource2 -> ADODataSet2 -> DBGrid2
// ADODataSet1 CommandText (Shape 指令)
SHAPE {SELECT * FROM Orders}
APPEND ({SELECT * FROM [Order Details]} AS Details
RELATE OrderID TO OrderID)
// 執行後,ADODataSet1 會包含一個名為 "Details" 的欄位,型別為 TDataSetField
// 步驟 1: 開啟 ADODataSet1
ADODataSet1->Open();
// 步驟 2: 開啟 Fields Editor (右鍵 ADODataSet1 -> Fields Editor -> 右鍵 -> Add all fields)
// 確認 "Details" 欄位存在 (型別 TDataSetField)
// 步驟 3: 設定 ADODataSet2
ADODataSet2->DataSetField = ADODataSet1->FieldByName("Details"); // 或物件檢查器下拉選擇
// 步驟 4: 開啟 ADODataSet2 (會自動隨 Master 游標移動而同步)
ADODataSet2->Open();
// 步驟 5: (選擇性) 隱藏 DBGrid1 中的 Details 欄位
// DBGrid1 -> Columns 編輯器 -> Add all fields -> 選取 Details -> Delete
SHAPE {parent-command}
APPEND ({child-command} AS alias RELATE parent-field TO child-field)
[APPEND ...] // 可多層巢狀
parent-command、child-command 為標準 SQL SELECT。AS alias 為子資料集在父資料集中的欄位名稱。RELATE 指定關聯欄位 (需同名或同型別)。嚴禁字串拼接 SQL (防 SQL Injection),一律使用參數:
ADOQuery1->SQL->Text = "SELECT * FROM Customers WHERE Country = :Country AND City = :City";
ADOQuery1->Parameters->ParamByName("Country")->Value = "Germany";
ADOQuery1->Parameters->ParamByName("City")->Value = "Berlin";
ADOQuery1->Open();
ADORecordset 支援 CursorLocation = clUseClient 時將資料快取在用戶端,斷開連線後仍可瀏覽、編輯、排序、篩選,重新連線時批次更新:
ADODataSet1->CursorLocation = clUseClient;
ADODataSet1->LockType = ltBatchOptimistic;
ADODataSet1->Open();
// ... 離線操作 ...
ADODataSet1->UpdateBatch(); // 批次寫回
| 問題 | 原因 | 解決 |
|---|---|---|
| 欄位型別不符 | OLE DB Provider 對應型別與 BDE 不同 | Fields Editor 重新建立欄位,檢查 DataType |
| AutoInc 欄位取值 | Access Jet 4.0 需在 Append 後重新查詢 | 使用 SELECT @@IDENTITY 或 SCOPE_IDENTITY() (SQL Server) |
| 大量資料效能 | 預設游標類型可能為伺服器端 | 設定 CursorLocation=clUseClient, CacheSize 適當值 |
| 中文亂碼 | 字碼頁不匹配 | 連線字串加 CharacterSet=Unicode 或確認資料庫/Provider 字碼頁 |
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TADOConnection* conn = new TADOConnection(this);
conn->ConnectionString = "Provider=SQLOLEDB.1;Data Source=.;Initial Catalog=TestDB;Integrated Security=SSPI;";
conn->Connected = true;
TADOQuery* qry = new TADOQuery(this);
qry->Connection = conn;
qry->SQL->Text = "SELECT GETDATE() AS ServerTime";
qry->Open();
ShowMessage("伺服器時間: " + qry->FieldByName("ServerTime")->AsString);
qry->Close();
conn->Connected = false;
// 元件擁有者為 Form,Form 銷毀時自動釋放
}
ADOExpress 讓 BCB 5 具備現代化資料存取能力,Shape 指令簡化 Master/Detail 實作,斷開式記錄集支援離線應用。新專案建議直接使用 TADOConnection + TADOQuery/TADODataSet,避免 TADOTable 的限制。配合參數化查詢、適當游標選項,可構建高效能、安全的資料庫應用程式。