MFC - klasy baz danych
ZA databaseto zbiór informacji zorganizowanych w taki sposób, aby można było łatwo uzyskać do nich dostęp, zarządzać nimi i aktualizować. Klasy baz danych MFC oparte na ODBC zostały zaprojektowane w celu zapewnienia dostępu do dowolnej bazy danych, dla której dostępny jest sterownik ODBC. Ponieważ klasy używają ODBC, aplikacja może uzyskiwać dostęp do danych w wielu różnych formatach danych i różnych konfiguracjach lokalnych / zdalnych.
Nie musisz pisać specjalnego kodu do obsługi różnych systemów zarządzania bazami danych (DBMS). Dopóki użytkownicy mają odpowiedni sterownik ODBC dla danych, do których chcą uzyskać dostęp, mogą używać programu do manipulowania danymi w przechowywanych tam tabelach. Źródło danych to konkretna instancja danych obsługiwana przez jakiś system zarządzania bazą danych (DBMS). Przykłady obejmują Microsoft SQL Server, Microsoft Access itp.
CDatabase
MFC udostępnia klasę CDatabasektóry reprezentuje połączenie ze źródłem danych, dzięki któremu można operować na źródle danych. W aplikacji może być jednocześnie aktywny jeden lub więcej obiektów bazy danych CD.
Sr.No. | Nazwa i opis |
---|---|
1 | BeginTrans Rozpoczyna „transakcję” - serię odwracalnych wywołań funkcji AddNew, Edit, Delete i Update klasy CRecordset- w podłączonym źródle danych. Źródło danych musi obsługiwać transakcje dlaBeginTrans mieć jakikolwiek efekt. |
2 | BindParameters Umożliwia powiązanie parametrów przed wywołaniem ExecuteSQL. |
3 | Cancel Anuluje operację asynchroniczną lub proces z drugiego wątku. |
4 | CanTransact Zwraca wartość różną od zera, jeśli źródło danych obsługuje transakcje. |
5 | CanUpdate Zwraca wartość różną od zera, jeśli CDatabase obiekt jest aktualizowalny (nie tylko do odczytu). |
6 | Close Zamyka połączenie ze źródłem danych. |
7 | CommitTrans Kończy transakcję rozpoczętą przez BeginTrans. Wykonywane są polecenia w transakcji, które zmieniają źródło danych. |
8 | ExecuteSQL Wykonuje instrukcję SQL. Żadne rekordy danych nie są zwracane. |
9 | GetBookmarkPersistence Identyfikuje operacje, dzięki którym zakładki pozostają na obiektach zestawu rekordów. |
10 | GetConnect Zwraca parametry połączenia ODBC używane do łączenia obiektu CDatabase ze źródłem danych. |
11 | GetCursorCommitBehavior Identyfikuje wpływ zatwierdzenia transakcji na otwarty obiekt zestawu rekordów. |
12 | GetCursorRollbackBehavior Identyfikuje wpływ wycofania transakcji na otwarty obiekt zestawu rekordów. |
13 | GetDatabaseName Zwraca nazwę aktualnie używanej bazy danych. |
14 | IsOpen Zwraca wartość różną od zera, jeśli CDatabase obiekt jest obecnie połączony ze źródłem danych. |
15 | OnSetOptions Wywoływane przez platformę w celu ustawienia standardowych opcji połączeń. Domyślna implementacja ustawia wartość limitu czasu zapytania. Możesz ustalić te opcje z wyprzedzeniem, dzwoniącSetQueryTimeout. |
16 | Open Ustanawia połączenie ze źródłem danych (przez sterownik ODBC). |
17 | OpenEx Ustanawia połączenie ze źródłem danych (przez sterownik ODBC). |
18 | Rollback Cofa zmiany wprowadzone podczas bieżącej transakcji. Źródło danych powraca do swojego poprzedniego stanu, zgodnie z definicją w wywołaniu BeginTrans, niezmienionego. |
19 | SetLoginTimeout Ustawia liczbę sekund, po upływie których próba połączenia ze źródłem danych zostanie przekroczona. |
20 | SetQueryTimeout Ustawia liczbę sekund, po których upłynie limit czasu operacji zapytań bazy danych. Wpływa na wszystkie kolejne wywołania zestawu rekordów Open, AddNew, Edit i Delete. |
Spójrzmy na prosty przykład, tworząc nową aplikację opartą na dialogu MFC.
Step 1 - Zmień podpis wiersza TODO na Retrieve Data from Database i przeciągnij jeden przycisk i jedną kontrolkę List, jak pokazano na poniższej migawce.
Step 2 - Dodaj procedurę obsługi zdarzenia kliknięcia dla przycisku i zmienną kontrolną m_ListControl dla kontroli listy.
Step 3 - Mamy prostą bazę danych, która zawiera jedną tabelę pracowników z kilkoma rekordami, jak pokazano na poniższej migawce.
Step 4 - Musimy dołączyć następujący plik nagłówkowy, abyśmy mogli użyć klasy CDatabase.
#include "odbcinst.h"
#include "afxdb.h"
Wstaw zapytanie
Instrukcja SQL INSERT INTO służy do dodawania nowych wierszy danych do tabeli w bazie danych.
Step 1 - Aby dodać nowe rekordy, użyjemy funkcji ExecuteSQL () klasy CDatabase, jak pokazano w poniższym kodzie.
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 - Kiedy powyższy kod zostanie skompilowany i wykonany, zobaczysz, że do Twojej bazy danych został dodany nowy rekord.
Odzyskaj rekord
Aby pobrać powyższą tabelę w aplikacji MFC, zaimplementujemy operacje związane z bazą danych w programie obsługi zdarzeń przycisku, jak pokazano w poniższych krokach.
Step 1- Aby użyć CDatabase, utwórz obiekt CDatabase i wywołaj jego funkcję Open (). Spowoduje to otwarcie połączenia.
Step 2 - Skonstruuj obiekty CRecordset do działania na podłączonym źródle danych, przekaż konstruktorowi zestawu rekordów wskaźnik do obiektu CDatabase.
Step 3 - Po użyciu połączenia wywołaj funkcję Close i zniszcz obiekt 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);
}
}
Step 4 - Oto plik nagłówkowy.
// 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 - Gdy powyższy kod zostanie skompilowany i wykonany, zobaczysz następujące dane wyjściowe.
Step 6- Naciśnij przycisk Read, aby wykonać operacje na bazie danych. Spowoduje to pobranie tabeli Employees.
Zaktualizuj rekord
Zapytanie SQL UPDATE służy do modyfikowania istniejących rekordów w tabeli. Możesz użyć klauzuli WHERE z zapytaniem UPDATE, aby zaktualizować wybrane wiersze, w przeciwnym razie wpłynie to na wszystkie wiersze.
Step 1 - Spójrzmy na prosty przykład, aktualizując wiek, w którym ID jest równe 5.
SqlString = L"UPDATE Employees SET Age = 59 WHERE ID = 5;";
database.ExecuteSQL(SqlString);
Step 2 - Oto pełny kod zdarzenia kliknięcia przycisku.
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 - Gdy powyższy kod zostanie skompilowany i wykonany, zobaczysz następujące dane wyjściowe.
Step 4- Naciśnij przycisk Read, aby wykonać operacje na bazie danych. Spowoduje to pobranie następującej tabeli Employees.
Step 5 - Możesz teraz zobaczyć, że wiek został zaktualizowany z 69 do 59 lat.
Usuń rekord
Zapytanie SQL DELETE służy do usuwania istniejących rekordów z tabeli. Możesz użyć klauzuli WHERE z zapytaniem DELETE, aby usunąć wybrane wiersze, w przeciwnym razie wszystkie rekordy zostaną usunięte.
Step 1 - Przyjrzyjmy się prostemu przykładowi, usuwając rekord, w którym identyfikator jest równy 3.
SqlString = L"DELETE FROM Employees WHERE ID = 3;";
database.ExecuteSQL(SqlString);
Step 2 - Oto pełny kod zdarzenia kliknięcia przycisku.
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 - Gdy powyższy kod zostanie skompilowany i wykonany, zobaczysz następujące dane wyjściowe.
Step 4- Naciśnij przycisk Read, aby wykonać operacje na bazie danych. Spowoduje to pobranie tabeli Employees.