ODBC中怎么利用CRecordset類對數據庫進行操作,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
創新互聯于2013年開始,先為蘇尼特左等服務建站,蘇尼特左等地企業,進行企業商務咨詢服務。為蘇尼特左企業網站制作PC+手機+微官網三網同步一站式服務解決您的所有建站問題。1.MFC中的ODBC類
主要有CDatabase、CRecordset、CRecordview、CDBException、CFieldExchange。這些類封裝了ODBC
SDK函數,可以很方便的操作支持ODBC的數據庫。
(1)CDatabase類:封裝應用程序與需要訪問的數據庫之間的連接,控制事務的提交和執行SQL語句的方法。
(2)CRecordset類:封裝大部分操縱數據庫的方法,包括瀏覽、修改記錄、控制游標移動,排序等操作。CRecordset類是MFC的ODBC類中最重要、功能最強大的一個類。CRecordset類對象提供了從數據源中提取出的記錄集。在多任務操作系統或網絡環境中,多個用戶可以共享同一個數據源。共享數據的一個主要問題是如何協調各個用戶對數據源的修改。CRecordset提供了幾種不同的方法來處理這個問題,這將由程序采用哪種類型的記錄集來決定。
CRecordset對象通常用于兩種形式:動態行集(dynasets)和快照集(snapshots)。動態行集能與其他用戶所做的更改保持同步,快照集則是數據的一個靜態視圖,當別的用戶改變了記錄時(包括修改、添加和刪除),快照中的記錄不受影響,也就是說,快照不反映別的用戶對數據源記錄的改變.直到調用了CRecordset::Requery重新查詢后,快照才會反映變化。每一種形式在記錄集被打開時都提供一組記錄,所不同的是,當在一個動態行集里滾動到一條記錄時,由其他用戶或是應用程序中其他記錄集對該記錄所做的更改會相應地顯示出來,例如在火車聯網銷售系統中,應該實時的顯示共享數據的變化。
(3)CRecordView類:提供與CRecordset對象相連接的視圖,可以建立視圖中的控件與數據庫數據的對應,同時支持游標,修改記錄等操作。
(4)CDBException類:提供對數據庫操作的異常處理。
(5)CFieldExchange類:提供用戶變量與數據庫字段之間的數據交換。
2.域數據成員與數據交換
CRecordset類代表一個記錄集。用戶一般用ClassWizard創建一個CRecordset的派生類。ClassWizard可以為派生的記錄集類創建一批數據成員,這些數據成員與記錄的各字段相對應,被稱為字段數據成員或域數據成員。域數據成員與表中的字段名字類似,且類型匹配。
例如:這是一個CRecordset類的派生類的定義
class CSetdata : public CRecordset
{
public:
CSetdata(CDatabase* pDatabase = NULL);
DECLARE_DYNAMIC(CSetdata)
// Field/Param Data
//{{AFX_FIELD(CSetdata, CRecordset)
//定義域數據成員變量,域數據成員用來與記錄集對應字段進行數據交換,起到一個緩沖區或中間橋梁的作用。也就是說,我們在處理記錄集時,實際上是對域數據成員進行操作,而不是直接對數據庫中的數據操作。
CString m_number;
CString m_name;
CString m_sex;
long m_age;
//}}AFX_FIELD
CString number;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSetdata)
public:
virtual CString GetDefaultConnect(); // Default connection string
virtual CString GetDefaultSQL(); // Default SQL for Recordset
virtual void DoFieldExchange(CFieldExchange* pFX); // RFX support
//}}AFX_VIRTUAL
// Implementation
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
};
#endif
域數據成員用來保存某條記錄的各個字段,它們是程序與記錄之間的緩沖區。域數據成員代表當前記錄,當在記錄集中滾動到某一記錄時,框架自動地把記錄的各個字段拷貝到記錄集對象的域數據成員中。當用戶要修改當前記錄或增加新記錄時,程序先將各字段的新值放入域數據成員中,然后調用相應的CRecordset成員函數把域數據成員設置到數據源中。
不難看出,在記錄集與數據源之間有一個數據交換問題.CRecordset類使用"記錄域交換"(Record Field Exchange,縮寫為RFX)機制自動地在域數據成員和數據源之間交換數據。RFX機制與對話數據交換(DDX)類似。CRecordset的成員函數DoFieldExchange負責數據交換任務,在該函數中調用了一系列RFX函數。當用戶用ClassWizard加入域數據成員時,ClassWizard會自動在DoFieldExchange中建立RFX。
典型的DoFieldExchange函數
void CSetdata::DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CSetdata)
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[number]"), m_number); //實現了域數據成員和數據源之間的數據交換
RFX_Text(pFX, _T("[name]"), m_name);
RFX_Text(pFX, _T("[sex]"), m_sex);
RFX_Long(pFX, _T("[age]"), m_age);
//}}AFX_FIELD_MAP
pFX->SetFieldType(CFieldExchange::param);
RFX_Text(pFX,_T("[]"),number);
}
3.記錄集的建立和關閉
使用MFC的ODBC類操作數據庫首先要建立一個CRecordset的派生類來關聯對應的數據表,然后調用Open()函數來查詢數據源中的數據并建立記錄集。此外,在Open函數中,可能還會調用GetDefaultConnect和GetDefaultSQL函數。
(1)首先在派生類的構造函數中會有一個參數指向一個CDatabase對象,用來獲取數據源。函數如下:
CRecordset(CDatabase* pDatabase = NULL);
如果pDatabase為NULL,則會在Open函數中自動構建一個CDatabase對象。如果CDatabase對象還未與數據源連接,那么在Open函數中會建立連接,連接字符串由成員函數GetDefaultConnect提供。
(2)virtual CString GetDefaultConnect();
該函數返回缺省的連接字符串。Open函數在必要的時侯會調用該函數獲取連接字符串以建立與數據源的連接。一般需要在CRecordset派生類中覆蓋該函數并在新版的函數中提供連接字符串。
例如:CSetdata為CRecordset類的派生類
CString CSetdata::GetDefaultConnect()
{
return _T("ODBC;DSN=my data");
}
這個函數獲取了數據庫連接字符串,包括連接方式以及數據源的名稱。
(3)virtual CString GetDefaultSQL();
Open函數在必要時會調用該函數返回缺省的SQL語句或表名以查詢數據源中的記錄。一般需要在CRecordset派生類中覆蓋該函數并在新版的函數中提供SQL語句或表名。
例如:
CString CSetdata::GetDefaultSQL()
{
return _T("[bingli]");
}
這個類返回的是數據源中數據表bingli的名稱。
(4)virtual BOOL Open( UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE, LPCTSTR lpszSQL = NULL, DWORD dwOptions = none );
throw( CDBException, CMemoryException );
該函數使用指定的SQL語句查詢數據源中的記錄并按指定的類型和選項建立記錄集。參數nOpenType說明了記錄集的類型,如下表所示。如果要求的類型驅動程序不支持,則函數將產生一個異常。參數lpszSQL是一個SQL的SELECT語句,或是一個表名。函數用lpszSQL來進行查詢,如果該參數為NULL,則函數會調用GetDefaultSQL獲取缺省的SQL語句。參數dwOptions可以是一些選項的組合,常用的選項在下表中列出。若創建成功則函數返回TRUE,若函數調用了CDatabase::Open且返回FALSE,則函數返回FALSE.
記錄集的類型
類型
含義
AFX_DB_USE_DEFAULT_TYPE 使用缺省值.
CRecordset::dynaset 可雙向滾動的動態集.
CRecordset::snapshot 可雙向滾動的快照.
CRecordset::dynamic 提供比動態集更好的動態特性,大部分ODBC驅動程序不支持這種記錄集.
CRecordset::forwardOnly 只能前向滾動的只讀記錄集.
創建記錄集時的常用選項
選項
含義
CRecordset::none 無選項(缺省).
CRecordset::appendOnly 不允許修改和刪除記錄,但可以添加記錄.
CRecordset::readOnly 記錄集是只讀的.
CRecordset::skipDeletedRecords 有些數據庫(如FoxPro)在刪除記錄時并不真刪除,而是做個刪除標記,在滾動時將跳過這些被刪除的記錄。
如果所有的參數都為空,例如:
CSetdata *pset = new CSetdata();
pset->Open();
那么Open()函數將會調用GetDefaultSQL()函數獲取指定數據表的數據并建立數據集。實際上,如果只提供表名,CRecordset類會構造一個SELECT語句來查詢數據源。例如:SELECT
(能提供的字段名) FROM bingli(即GetDefaultSQL()函數返回的表名)。
(5) 建立記錄集后,用戶可以隨時調用Requery成員函數來重新查詢和建立記錄集。Requery有兩個重要用途:
使記錄集能反映用戶對數據源的改變
按照新的過濾或排序方法查詢記錄并重新建立記錄集.
在調用Requery之前,可調用CanRestart來判斷記錄集是否支持Requery操作。要記住Requery只能在成功調用Open后調用,所以程序應調用IsOpen來判斷記錄集是否已建立.函數的聲明為
virtual BOOL Requery( );
throw( CDBException, CMemoryException );
返回TRUE表明記錄集建立成功,否則返回FALSE。若函數內部出錯則產生異常.
BOOL CanRestart( ) const; //若支持Requery則返回TRUE
BOOL IsOpen( ) const; //若記錄集已建立則返回TRUE
CRecordset類有兩個公共數據成員m_strFilter和m_strSort用來設置對記錄的過濾和排序。在調用Open或Requery前,如果在這兩個數據成員中指定了過濾或排序,那么Open和Requery將按這兩個數據成員指定的過濾和排序來查詢數據源。
成員m_strFilter用于指定過濾器。m_strFilter實際上包含了SQL的WHERE子句的內容,但它不含WHERE關鍵字。使用m_strFilter的一個例子為:
m_pSet->m_strFilter=“CourseID=‘MATH101’”; //只選擇CourseID為MATH101的記錄
if(m_pSet->Open(CRecordset::snapshot, “Section”))
. . . . . .
成員m_strSort用于指定排序.m_strSort實際上包含了ORDER BY子句的內容,但它不含ORDER BY關鍵字.m_strSort的一個例子為
m_pSet->m_strSort=“CourseID DESC”; //按CourseID的降序排列記錄
m_pSet->Open();
. . . . . .
事實上,Open函數在構造SELECT語句時,會把m_strFilter和m_strSort的內容放入SELECT語句的WHERE和ORDER
BY子句中.如果在Open的lpszSQL參數中已包括了WHERE和ORDER BY子句,那么m_strFilter和m_strSort必需為空.
調用無參數成員函數Close可以關閉記錄集.在調用了Close函數后,程序可以再次調用Open建立新的記錄集.CRecordset的析構函數會調用Close函數,所以當刪除CRecordset對象時記錄集也隨之關閉。
4.滾動記錄
CRecordset提供了幾個成員函數用來在記錄集中滾動,如下所示.當用這些函數滾動到一個新記錄時,框架會自動地把新記錄的內容拷貝到域數據成員中。
void MoveNext(); //前進一個記錄
void MovePrev(); //后退一個記錄
void MoveFirst(); //滾動到記錄集中的第一個記錄
void MoveLast(); //滾動到記錄集中的最后一個記錄
void SetAbsolutePosition( long nRows );
該函數用于滾動到由參數nRows指定的絕對位置處.若nRows為負數,則從后往前滾動.例如,當nRows為-1時,函數就滾動到記錄集的末尾。注意,該函數不會跳過被刪除的記錄。
virtual void Move( long nRows, WORD wFetchType = SQL_FETCH_RELATIVE );
該函數功能強大.通過將wFetchType參數指定為SQL_FETCH_NEXT、SQL_FETCH_PRIOR、SQL_FETCH_FIRST、SQL_FETCH_LAST和SQL_FETCH_ABSOLUTE,可以完成上面五個函數的功能.若wFetchType為SQL_FETCH_RELATIVE,那么將相對當前記錄移動,若nRows為正數,則向前移動,若nRows為負數,則向后移動。
如果在建立記錄集時選擇了CRecordset::skipDeletedRecords選項,那么除了SetAbsolutePosition外,在滾動記錄時將跳過被刪除的記錄,這一點對象FoxPro這樣的數據庫十分重要。
如果記錄集是空的,那么調用上述函數將產生異常。另外,必須保證滾動沒有超出記錄集的邊界。調用IsEOF和IsBOF可以進行這方面的檢測。
BOOL IsEOF( ) const; //如果記錄集為空或滾動過了最后一個記錄,那么函數返回TRUE,否則返回FALSE。
BOOL IsBOF( ) const; //如果記錄集為空或滾動過了第一個記錄,那么函數返回TRUE,否則返回FALSE。
下面是一個使用IsEOF的例子:
while(!m_pSet->IsEOF( ))
m_pSet->MoveNext( );
調用GetRecordCound可獲得記錄集中的記錄總數,該函數的聲明為:
long GetRecordCount( ) const;
要注意這個函數返回的實際上是用戶在記錄集中滾動的最遠距離.要想真正返回記錄總數,只有調用MoveNext移動到記錄集的末尾(MoveLast不行)。
5.修改、添加和刪除記錄
要修改當前記錄,應該按下列步驟進行:
調用Edit成員函數.調用該函數后就進入了編輯模式,程序可以修改域數據成員.注意不要在一個空的記錄集中調用Edit,否則會產生異常.
Edit函數會把當前域數據成員的內容保存在一個緩沖區中,這樣做有兩個目的,一是可以與域數據成員作比較以判斷哪些字段被改變了,二是在必要的時侯可以恢復域數據成員原來的值.若再次調用Edit,則將從緩沖區中恢復域數據成員,調用后程序仍處于編輯模式.調用Move(AFX_MOVE_REFRESH)或Move(0)可退出編輯模式(AFX_MOVE_REFRESH的值為0),同時該函數會從緩沖區中恢復域數據成員.
設置域數據成員的新值.
調用Update完成編輯.Update把變化后的記錄寫入數據源并結束編輯模式.
要向記錄集中添加新的記錄,應該按下列步驟進行:
調用AddNew成員函數.調用該函數后就進入了添加模式,該函數把所有的域數據成員都設置成NULL(注意,在數據庫術語中,NULL是指沒有值,這與C++的NULL是不同的).與Edit一樣,AddNew會把當前域數據成員的內容保存在一個緩沖區中,在必要的時侯,程序可以再次調用AddNew取消添加操作并恢復域數據成員原來的值,調用后程序仍處于添加模式.調用Move(AFX_MOVE_REFRESH)可退出添加模式,同時該函數會從緩沖區中恢復域數據成員.
設置域數據成員.
調用Update.Update把域數據成員中的內容作為新記錄寫入數據源,從而結束了添加.
如果記錄集是快照,那么在添加一個新的記錄后,需要調用Requery重新查詢,因為快照無法反映添加操作.
要刪除記錄集的當前記錄,應按下面兩步進行:
調用Delete成員函數.該函數會同時給記錄集和數據源中當前記錄加上刪除標記.注意不要在一個空記錄集中調用Delete,否則會產生一個異常.
滾動到另一個記錄上以跳過刪除記錄.
上面提到的函數聲明為:
virtual void Edit( );throw( CDBException, CMemoryException );
virtual void AddNew( );throw( CDBException );
virtual void Delete( );throw( CDBException );
virtual BOOL Update( );throw( CDBException );
若更新失敗則函數返回FALSE,且會產生一個異常.
在對記錄集進行更改以前,程序也許要調用下列函數來判斷記錄集是否是可以更改的,因為如果在不能更改的記錄集中進行修改、添加或刪除將導致異常的產生.
BOOL CanUpdate( ) const; //返回TRUE表明記錄是可以修改、添加和刪除的.
BOOL CanAppend( ) const; //返回TRUE則表明可以添加記錄.
關于ODBC中怎么利用CRecordset類對數據庫進行操作問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注創新互聯行業資訊頻道了解更多相關知識。
文章題目:ODBC中怎么利用CRecordset類對數據庫進行操作-創新互聯
分享網址:http://m.newbst.com/article26/hjdcg.html
成都網站建設公司_創新互聯,為您提供全網營銷推廣、靜態網站、軟件開發、商城網站、網頁設計公司、響應式網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯