Cơ sở dữ liệu là một tập hợp thông tin được tổ chức sao cho có thể dễ dàng truy cập, quản lý và cập nhật. Các lớp cơ sở dữ liệu MFC dựa trên ODBC được thiết kế để cung cấp quyền truy cập vào bất kỳ cơ sở dữ liệu nào có sẵn trình điều khiển ODBC. Bởi vì các lớp sử dụng ODBC, ứng dụng của bạn có thể truy cập dữ liệu ở nhiều định dạng dữ liệu khác nhau và các cấu hình cục bộ/từ xa khác nhau.
Bạn không phải viết mã trường hợp đặc biệt để xử lý các hệ thống quản lý cơ sở dữ liệu (DBMS) khác nhau. Miễn là người dùng của bạn có trình điều khiển ODBC thích hợp cho dữ liệu họ muốn truy cập, họ có thể sử dụng chương trình của bạn để thao tác dữ liệu trong các bảng được lưu trữ ở đó. Nguồn dữ liệu là một phiên bản cụ thể của dữ liệu được lưu trữ bởi một số hệ thống quản lý cơ sở dữ liệu (DBMS). Ví dụ bao gồm Microsoft SQL Server, Microsoft Access, v.v.
CDatabase
MFC cung cấp một lớp CDatabase đại diện cho một kết nối tới nguồn dữ liệu, thông qua đó bạn có thể thao tác trên nguồn dữ liệu. Bạn có thể có một hoặc nhiều đối tượng CDatabase hoạt động tại một thời điểm trong ứng dụng của mình.
Đây là danh sách các phương thức trong lớp CDatabase.
Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một ứng dụng dựa trên hộp thoại MFC mới.
Bước 1 – Thay đổi chú thích của dòng TODO thành Truy xuất dữ liệu từ cơ sở dữ liệu và kéo một nút và một điều khiển Danh sách như được hiển thị trong ảnh chụp nhanh sau đây.
Bước 2 – Thêm trình xử lý sự kiện nhấp chuột cho nút và biến điều khiển m_ListControl cho Kiểm soát danh sách.
Bước 3 – Chúng tôi có cơ sở dữ liệu đơn giản chứa một bảng Nhân viên với một số bản ghi như trong ảnh chụp nhanh sau đây.
Bước 4 – Chúng tôi cần bao gồm tệp tiêu đề sau để có thể sử dụng lớp CDatabase.
#include "odbcinst.h"
#include "afxdb.h"
Chèn truy vấn
Câu lệnh INSERT INTO trong SQL được sử dụng để thêm các hàng dữ liệu mới vào một bảng trong cơ sở dữ liệu.
Bước 1 – Để thêm các bản ghi mới, chúng ta sẽ sử dụng hàm ExecuteSQL() của lớp CDatabase như trong đoạn mã sau.
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;
Bước 2 – Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy một bản ghi mới được thêm vào cơ sở dữ liệu của mình.
Truy xuất bản ghi
Để truy xuất bảng trên trong ứng dụng MFC, chúng tôi thực hiện các hoạt động liên quan đến cơ sở dữ liệu trong trình xử lý sự kiện nút như trong các bước sau.
Bước 1 – Để sử dụng CDatabase, hãy xây dựng một đối tượng CDatabase và gọi hàm Open() của nó. Điều này sẽ mở kết nối.
Bước 2 – Xây dựng các đối tượng CRecordset để hoạt động trên nguồn dữ liệu được kết nối, chuyển hàm tạo tập bản ghi một con trỏ tới đối tượng CDatabase của bạn.Bước 3 – Sau khi sử dụng kết nối, hãy gọi hàm Đóng và hủy đối tượng 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);
}
}
Bước 4 – Đây là tệp tiêu đề.
// 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();
};
Bước 5 – Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy đầu ra sau.
Bước 6 – Nhấn nút Đọc để thực hiện các hoạt động cơ sở dữ liệu. Nó sẽ truy xuất bảng Nhân viên.
Cập nhật bản ghi
Truy vấn CẬP NHẬT SQL được sử dụng để sửa đổi các bản ghi hiện có trong một bảng. Bạn có thể sử dụng mệnh đề WHERE với truy vấn CẬP NHẬT để cập nhật các hàng đã chọn nếu không tất cả các hàng sẽ bị ảnh hưởng.
Bước 1 – Chúng ta hãy xem xét một ví dụ đơn giản bằng cách cập nhật Tuổi trong đó ID bằng 5.
SqlString = L"UPDATE Employees SET Age = 59 WHERE ID = 5;";
database.ExecuteSQL(SqlString);
Bước 2 – Đây là mã hoàn chỉnh của sự kiện nhấp vào nút.
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;
}
Bước 3 – Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy đầu ra sau.
Bước 4 – Nhấn nút Đọc để thực hiện các hoạt động cơ sở dữ liệu. Nó sẽ lấy bảng Nhân viên sau.
Bước 5 – Bây giờ bạn có thể thấy độ tuổi được cập nhật từ 69 thành 59.
Xóa hồ sơ
Truy vấn SQL DELETE được sử dụng để xóa các bản ghi hiện có khỏi một bảng. Bạn có thể sử dụng mệnh đề WHERE với truy vấn DELETE để xóa các hàng đã chọn, nếu không thì tất cả các bản ghi sẽ bị xóa.
Bước 1 – Chúng ta hãy xem xét một ví dụ đơn giản bằng cách xóa bản ghi có ID bằng 3.
SqlString = L"DELETE FROM Employees WHERE ID = 3;";
database.ExecuteSQL(SqlString);
Bước 2 – Đây là mã hoàn chỉnh của sự kiện nhấp vào nút.
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;
}
Bước 3 – Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy đầu ra sau.
Bước 4 – Nhấn nút Đọc để thực hiện các hoạt động cơ sở dữ liệu. Nó sẽ truy xuất bảng Nhân viên.