MFC – 数据库类
数据库是一组信息,这些信息经过整理,可以轻松访问,管理和更新.基于ODBC的MFC数据库类旨在提供对ODBC驱动程序可用的任何数据库的访问.因为类使用ODBC,所以您的应用程序可以访问许多不同数据格式和不同本地/远程配置的数据.
您不必编写特殊情况代码来处理不同的数据库管理系统(数据库管理系统).只要您的用户拥有适合他们想要访问的数据的ODBC驱动程序,他们就可以使用您的程序来处理存储在那里的表中的数据.数据源是由某个数据库管理系统(DBMS)托管的特定数据实例.示例包括Microsoft SQL Server,Microsoft Access等.
CDatabase
MFC提供类 CDatabase ,表示连接到数据源,您可以通过它来操作数据源.您可以在应用程序中一次激活一个或多个CDatabase对象.
| Sr.No. | 姓名&说明 |
|---|---|
| 1 |
BeginTrans 启动"事务" - 对类 CRecordset 的AddNew,编辑,删除和更新成员函数的一系列可逆调用 - 在连接的数据源上.数据源必须支持 BeginTrans 的交易才能生效. |
| 2 |
BindParameters 允许您在调用 ExecuteSQL之前绑定参数. |
| 3 |
Cancel 从第二个线程取消异步操作或进程. |
| 4 |
CanTransact 如果数据源支持事务,则返回非零值. |
| 5 |
CanUpdate 如果 CDatabase 对象是可更新的,则返回非零值(不是只读). |
| 6 |
Close 关闭数据源连接. |
| 7 |
CommitTrans 完成交易由BeginTrans开始.执行更改数据源的事务中的命令. |
| 8 |
ExecuteSQL 执行SQL语句.没有返回数据记录. |
| 9 |
GetBookmarkPersistence 标识书签在记录集对象上保留的操作. |
| 10 |
GetConnect 返回用于将CDatabase对象连接到数据源的ODBC连接字符串. |
| 11 |
GetCursorCommitBehavior 标识在开放时提交交易的效果记录集对象. |
| 12 |
GetCursorRollbackBehavior 标识在开放记录集对象上回滚事务的效果. |
| 13 |
GetDatabaseName 返回当前正在使用的数据库的名称. |
| 14 |
IsOpen 如果 CDatabase ,则返回非零值对象当前连接到数据源. |
| 15 |
OnSetOptions 由框架调用以设置标准连接选项.默认实现设置查询超时值.您可以通过调用 SetQueryTimeout 提前建立这些选项. |
| 16 |
Open 建立与数据源的连接(通过ODBC驱动程序) ). |
| 17 |
OpenEx 建立与数据源的连接(通过ODBC驱动程序). |
| 18 |
Rollback 撤消当前交易期间所做的更改.数据源返回其先前状态,如在BeginTrans调用中定义的那样,未改变. |
| 19 |
SetLoginTimeout 设置数据源连接尝试之前的秒数超时. |
| 20 |
SetQueryTimeout 设置数据库查询操作超时的秒数.影响所有后续记录集Open,AddNew,Edit和Delete调用. |
让我们通过创建一个基于MFC对话框的新应用程序来看一个简单的例子.
第1步 : 将TODO行的标题更改为从数据库中检索数据并拖动一个按钮和一个List控件,如下面的快照所示.

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

第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;
第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();
};
第5步 : 编译并执行上面的代码时,您将看到以下输出.

第6步 : 按Read按钮执行数据库操作.它将检索Employees表.

更新记录
SQL UPDATE查询用于修改表中的现有记录.您可以使用带有UPDATE查询的WHERE子句来更新所选行,否则所有行都会受到影响.
步骤1 : 让我们通过更新ID等于5的Age来看一个简单的例子.
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;
}
第3步 : 编译并执行上面的代码时,您将看到以下输出.

第4步 : 按Read按钮执行数据库操作.它将检索以下Employees表.

第5步 : 您现在可以看到年龄从69更新到59.
删除记录
SQL DELETE查询用于删除现有记录表.您可以将WHERE子句与DELETE查询一起使用以删除所选行,否则将删除所有记录.
步骤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;
}
第3步 : 编译并执行上面的代码时,您将看到以下输出.

第4步 : 按Read按钮执行数据库操作.它将检索Employees表.
