MFC 為 ODBC 程式設計提供五大基礎類別,其中 CFieldExchange 實現的 RFX(Record Field Exchange) 機制,是記錄集與資料源雙向資料交換的核心。本文系統介紹五大類別職責、RFX 函式對照表,並以 AppWizard 逐步建立範例專案,示範 DDX(對話框資料交換)與 RFX 協作的完整流程。
| 類別 | 核心職責 |
|---|---|
CDatabase | 代表資料源連接,封裝 SQLConnect/SQLDriverConnect,管理交易認可/回滾。 |
CRecordset | 封裝結果集,支援游標捲動、篩選、排序、編輯、新增/刪除。 |
CRecordView | 表單視圖直接綁定 CRecordset,提供資料感知控件自動 DDX。 |
CFieldExchange | 實現 RFX,負責記錄集成員變數與資料庫欄位的雙向繫結。 |
CDBException | 封裝 ODBC 錯誤碼與訊息,提供 m_nRetCode、m_strError 等診斷資訊。 |
在 CRecordset::DoFieldExchange() 覆寫中,針對每個成員變數呼叫對應 RFX 函式:
| RFX 函式 | C++ 型別 | SQL 型別範例 |
|---|---|---|
RFX_Bool | BOOL | BIT, SMALLINT |
RFX_Byte | BYTE | TINYINT |
RFX_Int / RFX_Long | int / long | INTEGER, SMALLINT, BIGINT |
RFX_Single / RFX_Double | float / double | REAL, FLOAT, DOUBLE |
RFX_Text | CString | CHAR, VARCHAR, TEXT |
RFX_Binary | CByteArray | BINARY, VARBINARY, IMAGE |
RFX_Date | CTime / COleDateTime | DATE, TIMESTAMP |
RFX_LongBinary | CLongBinary | BLOB, IMAGE (大物件) |
TestODBC。test.dbf,連續點 Next 完成產生。CTestODBCApp // 應用程式類
CTestODBCDoc // 文件類
CTestODBCSet // 記錄集類 (繼承 CRecordset)
CTestODBCView // 視圖類 (繼承 CRecordView)
CMainFrame // 主視窗框架
CAboutDlg // 關於對話框
// CTestODBCSet.h
class CTestODBCSet : public CRecordset
{
public:
// 欄位成員變數(由 AppWizard 依資料表自動產生)
long m_ID;
CString m_Name;
double m_Score;
CTime m_Date;
// 連接字串(DSN-less)
virtual CString GetDefaultConnect() {
return _T("Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=.;Exclusive=No;");
}
virtual CString GetDefaultSQL() { return _T("test"); }
// RFX 綁定
virtual void DoFieldExchange(CFieldExchange* pFX) {
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Long(pFX, _T("[ID]"), m_ID);
RFX_Text(pFX, _T("[Name]"), m_Name);
RFX_Double(pFX, _T("[Score]"), m_Score);
RFX_Date(pFX, _T("[Date]"), m_Date);
}
};
CRecordView 覆寫 DoDataExchange,呼叫 DDX_FieldText 等函式,將記錄集成員直接綁定至對話框控件:
void CTestODBCView::DoDataExchange(CDataExchange* pDX)
{
CRecordView::DoDataExchange(pDX);
DDX_FieldText(pDX, IDC_EDIT_ID, m_pSet->m_ID, m_pSet);
DDX_FieldText(pDX, IDC_EDIT_NAME, m_pSet->m_Name, m_pSet);
DDX_FieldText(pDX, IDC_EDIT_SCORE, m_pSet->m_Score, m_pSet);
// 日期需自行處理格式化
}
sequenceDiagram
participant User
participant View as CRecordView
participant RS as CRecordset
participant RFX as CFieldExchange
participant DB as ODBC Driver
User->>View: 編輯控件內容
View->>View: OnOK() -> UpdateData(TRUE)
View->>RS: DDX_FieldText -> RFX_Text
RFX->>RS: 更新成員變數 m_Name
User->>View: 點擊「下一筆」
View->>RS: MoveNext()
RS->>DB: SQLFetch
DB->>RFX: 傳回欄位資料
RFX->>RS: RFX_Text 讀取至 m_Name
RS->>View: DDX_FieldText 更新控件
View->>User: 顯示新記錄
CTime 範圍限制(1970-2038),跨世紀應用請改用 COleDateTime + RFX_Date。RFX_LongBinary + CLongBinary,並設定 CRecordset::useMultiRowFetch。CRecordset::snapshot + forwardOnly 游標;需更新才用 dynaset。TRY/CATCH(CDBException, e),記錄 e->m_strError。MFC ODBC 架構以 CDatabase 管理連接,CRecordset 封裝結果集,CFieldExchange 實現 RFX 雙向繫結,CRecordView 提供表單級 DDX。掌握 RFX 函式對照表與 DoFieldExchange 覆寫模式,配合 AppWizard 快速產生樣板碼,即可高效開發穩健的資料庫應用。