MFC – 数据库类
MFC – 数据库类
一个数据库是被组织,以便它可以很容易地访问,管理和更新信息的集合。基于 ODBC 的 MFC 数据库类旨在提供对任何有 ODBC 驱动程序可用的数据库的访问。由于这些类使用 ODBC,您的应用程序可以访问许多不同数据格式和不同本地/远程配置的数据。
您不必编写特殊情况代码来处理不同的数据库管理系统 (DBMS)。只要您的用户有适合他们想要访问的数据的 ODBC 驱动程序,他们就可以使用您的程序来操作存储在那里的表中的数据。数据源是由某个数据库管理系统 (DBMS) 托管的特定数据实例。示例包括 Microsoft SQL Server、Microsoft Access 等。
数据库
MFC 提供了一个CDatabase类,它表示与数据源的连接,通过它您可以对数据源进行操作。您可以在应用程序中一次激活一个或多个 CDatabase 对象。
让我们通过创建一个新的基于 MFC 对话框的应用程序来查看一个简单的示例。
步骤 1 – 将 TODO 行的标题更改为从数据库中检索数据并拖动一个按钮和一个列表控件,如下面的快照所示。

步骤 2 – 为按钮添加单击事件处理程序,并为列表控件添加控件变量 m_ListControl。
步骤 3 – 我们有一个简单的数据库,其中包含一个带有一些记录的员工表,如下面的快照所示。

第 4 步– 我们需要包含以下头文件,以便我们可以使用 CDatabase 类。
#include "odbcinst.h" #include "afxdb.h"
插入查询
SQL INSERT INTO 语句用于向数据库中的表添加新的数据行。
步骤 1 – 要添加新记录,我们将使用 CDatabase 类的 ExecuteSQL() 函数,如下面的代码所示。
CDatabase database;
CString SqlString;
CString strID, strName, strAge;
CString sDriver = L"MICROSOFT ACCESS DRIVER (*.mdb)";
CString sDsn;
CString sFile = L"D:\\Test.mdb";
// You must change above path if it's different
int iRec = 0;
// Build ODBC connection string
sDsn.Format(L"ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);
TRY {
// Open the database
database.Open(NULL,false,false,sDsn);
SqlString = "INSERT INTO Employees (ID,Name,age) VALUES (5,'Sanjay',69)";
database.ExecuteSQL(SqlString);
// Close the database
database.Close();
}CATCH(CDBException, e) {
// If a database exception occured, show error msg
AfxMessageBox(L"Database error: " + e→m_strError);
}
END_CATCH;
Step 2 – 编译并执行上述代码后,您将看到在您的数据库中添加了一条新记录。

检索记录
为了在 MFC 应用程序中检索上表,我们在按钮事件处理程序中实现数据库相关操作,如下所示。
步骤 1 – 要使用 CDatabase,请构造一个 CDatabase 对象并调用其 Open() 函数。这将打开连接。
第 2 步– 构造 CRecordset 对象以对连接的数据源进行操作,将记录集构造函数传递给 CDatabase 对象的指针。
步骤 3 – 使用连接后,调用 Close 函数并销毁 CDatabase 对象。
void CMFCDatabaseDemoDlg::OnBnClickedButtonRead() {
// TODO: Add your control notification handler code here
CDatabase database;
CString SqlString;
CString strID, strName, strAge;
CString sDriver = "MICROSOFT ACCESS DRIVER (*.mdb)";
CString sFile = L"D:\\Test.mdb";
// You must change above path if it's different
int iRec = 0;
// Build ODBC connection string
sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s",sDriver,sFile);
TRY {
// Open the database
database.Open(NULL,false,false,sDsn);
// Allocate the recordset
CRecordset recset( &database );
// Build the SQL statement
SqlString = "SELECT ID, Name, Age " "FROM Employees";
// Execute the query
recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);
// Reset List control if there is any data
ResetListControl();
// populate Grids
ListView_SetExtendedListViewStyle(m_ListControl,LVS_EX_GRIDLINES);
// Column width and heading
m_ListControl.InsertColumn(0,"Emp ID",LVCFMT_LEFT,-1,0);
m_ListControl.InsertColumn(1,"Name",LVCFMT_LEFT,-1,1);
m_ListControl.InsertColumn(2, "Age", LVCFMT_LEFT, -1, 1);
m_ListControl.SetColumnWidth(0, 120);
m_ListControl.SetColumnWidth(1, 200);
m_ListControl.SetColumnWidth(2, 200);
// Loop through each record
while( !recset.IsEOF() ) {
// Copy each column into a variable
recset.GetFieldValue("ID",strID);
recset.GetFieldValue("Name",strName);
recset.GetFieldValue("Age", strAge);
// Insert values into the list control
iRec = m_ListControl.InsertItem(0,strID,0);
m_ListControl.SetItemText(0,1,strName);
m_ListControl.SetItemText(0, 2, strAge);
// goto next record
recset.MoveNext();
}
// Close the database
database.Close();
}CATCH(CDBException, e) {
// If a database exception occured, show error msg
AfxMessageBox("Database error: "+e→m_strError);
}
END_CATCH;
}
// Reset List control
void CMFCDatabaseDemoDlg::ResetListControl() {
m_ListControl.DeleteAllItems();
int iNbrOfColumns;
CHeaderCtrl* pHeader = (CHeaderCtrl*)m_ListControl.GetDlgItem(0);
if (pHeader) {
iNbrOfColumns = pHeader→GetItemCount();
}
for (int i = iNbrOfColumns; i >= 0; i--) {
m_ListControl.DeleteColumn(i);
}
}
第 4 步– 这是头文件。
// MFCDatabaseDemoDlg.h : header file
//
#pragma once
#include "afxcmn.h"
// CMFCDatabaseDemoDlg dialog
class CMFCDatabaseDemoDlg : public CDialogEx {
// Construction
public:
CMFCDatabaseDemoDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MFCDATABASEDEMO_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
void ResetListControl();
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CListCtrl m_ListControl;
afx_msg void OnBnClickedButtonRead();
};
Step 5 – 编译并执行上述代码后,您将看到以下输出。

步骤 6 – 按读取按钮执行数据库操作。它将检索员工表。

更新记录
SQL UPDATE Query 用于修改表中的现有记录。您可以将 WHERE 子句与 UPDATE 查询一起使用来更新选定的行,否则所有行都会受到影响。
第 1 步– 让我们通过更新 ID 等于 5 的年龄来查看一个简单的示例。
SqlString = L"UPDATE Employees SET Age = 59 WHERE ID = 5;"; database.ExecuteSQL(SqlString);
第 2 步– 这是按钮单击事件的完整代码。
void CMFCDatabaseDemoDlg::OnBnClickedButtonRead() {
// TODO: Add your control notification handler code here
CDatabase database;
CString SqlString;
CString strID, strName, strAge;
CString sDriver = L"MICROSOFT ACCESS DRIVER (*.mdb)";
CString sDsn;
CString sFile =
L"C:\\Users\\Muhammad.Waqas\\Downloads\\Compressed\\ReadDB_demo\\Test.mdb";
// You must change above path if it's different
int iRec = 0;
// Build ODBC connection string
sDsn.Format(L"ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);
TRY {
// Open the database
database.Open(NULL,false,false,sDsn);
// Allocate the recordset
CRecordset recset(&database);
SqlString = L"UPDATE Employees SET Age = 59 WHERE ID = 5;";
database.ExecuteSQL(SqlString);
SqlString = "SELECT ID, Name, Age FROM Employees";
// Build the SQL statement
SqlString = "SELECT ID, Name, Age FROM Employees";
// Execute the query
recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);
// Reset List control if there is any data
ResetListControl();
// populate Grids
ListView_SetExtendedListViewStyle(m_listCtrl,LVS_EX_GRIDLINES);
// Column width and heading
m_listCtrl.InsertColumn(0,L"Emp ID",LVCFMT_LEFT,-1,0);
m_listCtrl.InsertColumn(1,L"Name",LVCFMT_LEFT,-1,1);
m_listCtrl.InsertColumn(2, L"Age", LVCFMT_LEFT, -1, 1);
m_listCtrl.SetColumnWidth(0, 120);
m_listCtrl.SetColumnWidth(1, 200);
m_listCtrl.SetColumnWidth(2, 200);
// Loop through each record
while (!recset.IsEOF()) {
// Copy each column into a variable
recset.GetFieldValue(L"ID",strID);
recset.GetFieldValue(L"Name",strName);
recset.GetFieldValue(L"Age", strAge);
// Insert values into the list control
iRec = m_listCtrl.InsertItem(0,strID,0);
m_listCtrl.SetItemText(0,1,strName);
m_listCtrl.SetItemText(0, 2, strAge);
// goto next record
recset.MoveNext();
}
// Close the database
database.Close();
}CATCH(CDBException, e) {
// If a database exception occured, show error msg
AfxMessageBox(L"Database error: " + e→m_strError);
}
END_CATCH;
}
Step 3 – 编译并执行上述代码后,您将看到以下输出。

步骤 4 – 按读取按钮执行数据库操作。它将检索以下员工表。

第 5 步– 您现在可以看到年龄从 69 更新到 59。
删除记录
SQL DELETE 查询用于从表中删除现有记录。您可以使用带有 DELETE 查询的 WHERE 子句删除选定的行,否则所有记录都将被删除。
步骤 1 – 让我们看一个简单的例子,删除 ID 等于 3 的记录。
SqlString = L"DELETE FROM Employees WHERE ID = 3;"; database.ExecuteSQL(SqlString);
第 2 步– 这是按钮单击事件的完整代码。
void CMFCDatabaseDemoDlg::OnBnClickedButtonRead() {
// TODO: Add your control notification handler code here
CDatabase database;
CString SqlString;
CString strID, strName, strAge;
CString sDriver = L"MICROSOFT ACCESS DRIVER (*.mdb)";
CString sDsn;
CString sFile =
L"C:\\Users\\Muhammad.Waqas\\Downloads\\Compressed\\ReadDB_demo\\Test.mdb";
// You must change above path if it's different
int iRec = 0;
// Build ODBC connection string
sDsn.Format(L"ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);
TRY {
// Open the database
database.Open(NULL,false,false,sDsn);
// Allocate the recordset
CRecordset recset(&database);
SqlString = L"DELETE FROM Employees WHERE ID = 3;";
database.ExecuteSQL(SqlString);
SqlString = "SELECT ID, Name, Age FROM Employees";
// Build the SQL statement
SqlString = "SELECT ID, Name, Age FROM Employees";
// Execute the query
recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);
// Reset List control if there is any data
ResetListControl();
// populate Grids
ListView_SetExtendedListViewStyle(m_listCtrl,LVS_EX_GRIDLINES);
// Column width and heading
m_listCtrl.InsertColumn(0,L"Emp ID",LVCFMT_LEFT,-1,0);
m_listCtrl.InsertColumn(1,L"Name",LVCFMT_LEFT,-1,1);
m_listCtrl.InsertColumn(2, L"Age", LVCFMT_LEFT, -1, 1);
m_listCtrl.SetColumnWidth(0, 120);
m_listCtrl.SetColumnWidth(1, 200);
m_listCtrl.SetColumnWidth(2, 200);
// Loop through each record
while (!recset.IsEOF()) {
// Copy each column into a variable
recset.GetFieldValue(L"ID",strID);
recset.GetFieldValue(L"Name",strName);
recset.GetFieldValue(L"Age", strAge);
// Insert values into the list control
iRec = m_listCtrl.InsertItem(0,strID,0);
m_listCtrl.SetItemText(0,1,strName);
m_listCtrl.SetItemText(0, 2, strAge);
// goto next record
recset.MoveNext();
}
// Close the database
database.Close();
}CATCH(CDBException, e) {
// If a database exception occured, show error msg
AfxMessageBox(L"Database error: " + e→m_strError);
}
END_CATCH;
}
Step 3 – 编译并执行上述代码后,您将看到以下输出。

步骤 4 – 按读取按钮执行数据库操作。它将检索员工表。