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控件,如下面的快照所示.

从DB中检索数据

步骤2 : 为列表控件添加按钮和控制变量m_ListControl的单击事件处理程序.

步骤3 : 我们有一个简单的数据库,其中包含一个Employees表和一些记录,如下面的快照所示.

Employees Table

第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表.

更新记录