3、CRecordset類數據庫
一、IsBOF與IsEOF網絡
(1)IsBOF函數
若是記錄集沒有記錄,或已經向前遊動到第一個記錄以前,則返回非零;不然返回0。詳細說明以下:性能
1)訪問Open函數以後,若是記錄集沒有任何記錄,IsBOF返回非零。當你打開一個至少包含一個記錄的記錄集,第一個記錄是當前記錄,此時IsBOF返回0。spa
2)若是第一個記錄是當前記錄而且你訪問MovePrev,以後IsBOF會返回非零值。若是IsBOF返回非零值而且訪問MovePrev函數,會報錯。操作系統
3)若是IsBOF返回非零值,說明當前記錄沒有定義,任何請求當前記錄的動做將會致使錯誤。指針
(2)IsEOFcode
若是記錄集沒有記錄,或已經滾動到最後一條紀錄以後,則返回非零。不然,返回0。對象
if (m_test.IsOpen()) m_test.Close(); m_test.Open(); //若是記錄集爲空,返回 if (m_test.IsBOF()) return FALSE; //若是不是最後一個記錄的下一個位置,就向下移動一個記錄 while (!m_test.IsEOF) { m_test.MoveNext(); }
二、快照(Snapshot) 和動態集(Dynaset)blog
在多任務操做系統或網絡環境中,多個用戶能夠共享同一個數據源。共享數據的一個主要問題是如何協調各個用戶對數據源的修改。例如,當某一個應用改變了數據源中的記錄時,別的鏈接至該數據源的應用應該如何處理。對於這個問題,基於MFC的ODBC應用程序能夠採起幾種不一樣的處理辦法,這將由程序採用哪一種記錄集決定。
記錄集主要分爲快照(Snapshot) 和動態集(Dynaset)兩種,CRecordset類對這二者都支持。這兩種記錄集的不一樣表如今它們對別的應用改變數據源記錄採起了不一樣的處理方法。
(1)快照(Snapshot)
快照型記錄集提供了對數據的靜態視。當別的用戶改變了記錄時(包括修改、添加和刪除),快照中的記錄不受影響,也就是說,快照不反映別的用戶對數據源記錄的改變,直到調用了CRecordset::Requery從新查詢後,快照纔會反映變化。須要指出的是,快照的這種靜態特性是相對於別的用戶而言的,它會正確反映由自己用戶對記錄的修改和刪除,但對於新添加的記錄直到調用Requery後才能反映到快照中。
(2)動態集(Dynaset)
動態集提供了數據的動態視。當別的用戶修改或刪除了記錄集中的記錄時,會在動態集中反映出來:當滾動到修改過的記錄時對其所做的修改會當即反映到動態集中,當記錄被刪除時,MFC代碼會跳過記錄集中的刪除部分。對於其它用戶添加的記錄,直到調用Requery時,纔會在動態集中反映出來。自己應用程序對記錄的修改、添加和刪除會反映在動態集中。當數據必須是動態的時侯,使用動態集是最適合的。例如,在一個火車票聯網售票系統中,顯然應該用動態集隨時反映出共享數據的變化。
(3)光標機制
在記錄集中滾動,須要有一個標誌來指明滾動後的位置(當前位置)。ODBC驅動程序會維護一個光標,用來跟蹤記錄集的當前記錄,能夠把光標理解成跟蹤記錄集位置的一種機制。
光標庫(Cursor Library)是處於ODBC驅動程序管理器和驅動程序之間的動態連接庫(ODBCCR32.DLL)。光標庫的主要功能是支持快照以及爲底層驅動程序提供雙向滾動能力,高層次的驅動程序不須要光標庫,由於它們是可滾動的。光標庫管理快照記錄的緩衝區,該緩衝區反映本程序對記錄的修改和刪除,但不反映其它用戶對記錄的改變,因而可知,快照實際上至關於當前的光標庫緩衝區。
快照是一種靜態光標(Static Cursor)。靜態光標直到滾動到某個記錄才能取得該記錄的數據。所以,要保證全部的記錄都被快照,能夠先滾動到記錄集的末尾,而後再滾動到感興趣的第一個記錄上。這樣作的缺點是滾動到末尾須要額外的開銷,會下降性能。
與快照不一樣,動態集不用光標庫維持的緩衝區來存放記錄。實際上,動態集是不使用光標庫的,由於光標庫會屏蔽掉一些支持動態集的底層驅動程序功能。動態集是一種鍵集驅動光標(Keyset-Driven Cursor),當打開一個動態集時,驅動程序保存記錄集中每一個記錄的鍵。只要光標在動態集中滾動,驅動程序就會經過鍵來從數據源中檢取當前記錄,從而保證選取的記錄與數據源同步。
從上面的分析中能夠看出,快照和動態集有一個共同的特色,那就是在創建記錄集後,記錄集中的成員就已經肯定了。這就是爲何兩種記錄集都不能反映別的用戶添加記錄的緣由。
三、Open與Requery
CRecordSet的Open()和Requery()成員函數能夠實現記錄查詢。詳細說明以下:
(1)使用CRecordSet的類對象以前,必須使用CRecordSet的成員函數Open()來得到有效的記錄集。一旦使用過Open()函數,再次查詢時使用Requery()函數就能夠了。
(2)調用Open()函數時,若是已經將一個打開的CDatabase對象指針傳遞給CRecordSet類對象的m_pDatabase成員變量,那麼,CRecordSet類對象將使用該數據庫對象創建ODBC鏈接;不然,若是m_pDatabase爲空指針,對象就須要就新建一個CDatabase類對象並使其與缺省的數據源相連,而後進行CRecordSet類對象的初始化。缺省數據源由GetDefaultConnect()函數得到。
(3)也能夠提供所須要的SQL語句,並以它來調用CRecordSet::Open()函數,例如:
//strSQL爲SQL語句 m_test.Open(AFX_DB_USE_DEFAULT_TYPE, strSQL);
(4)若是Open沒有指定參數,程序使用缺省的SQL語句,即對在GetDefaultSQL()函數中指定的SQL語句進行操做。例如:
CString CHistorySet::GetDefaultSQL() { return _T("[History]"); }
GetDefaultSQL()函數返回的表名,對應的缺省操做是SELECT語句,即:SELECT *FROM History。