?? chap10_5.htm
字號:
<tr>
<td width="39%">
<p align="JUSTIFY">CRecordset::readOnly
</td>
<td width="61%">
<p align="JUSTIFY">記錄集是只讀的.
</td>
</tr>
<tr>
<td width="39%">
<p align="JUSTIFY">CRecordset::skipDeletedRecords
</td>
<td width="61%">
<p align="JUSTIFY">有些數據庫(如FoxPro)在刪除記錄時并不真刪除,而是做個刪除標記,在滾動時將跳過這些被刪除的記錄.
</td>
</tr>
</table>
<p> </p>
<p align="JUSTIFY"> </p>
<blockquote>
<blockquote>
<p align="JUSTIFY">virtual CString GetDefaultSQL( );<br>
Open函數在必要時會調用該函數返回缺省的SQL語句或表名以查詢數據源中的記錄.一般需要在CRecordset派生類中覆蓋該函數并在新版的函數中提供SQL語句或表名.下面是一些返回字符串的例子.<br>
“Section” //選擇Section表中的所有記錄到記錄集中<br>
“Section, Course” //合并Section表和Course表的各列到記錄集中</p>
<p align="JUSTIFY">//對Section表中的所有記錄按CourseID的升序進行排序,然后建立記錄集</p>
<p align="JUSTIFY">“SELECT * FROM Section ORDER BY CourseID ASC”</p>
</blockquote>
</blockquote>
<p align="JUSTIFY"> 上面的例子說明,通過合理地安排SQL語句和表名,Open函數可以十分靈活地查詢數據源中的記錄.用戶可以合并多個表的字段,也可以只選擇記錄中的某些字段,還可以對記錄進行過濾和排序.</p>
<p align="JUSTIFY"> 上一小節說過,在建立記錄集時,CRecordset會構造一個SELECT語句來查詢數據源.如果在調用Open時只提供了表名,那么SELECT語句還缺少選擇列參數rfx-field-list(參見10.5.3).框架規定,如果只提供了表名,則選擇列的信息從DoFieldExchange中的RFX語句里提?。纾绻谡{用Open時只提供了"Section"表名,那么將會構造如下一個SELECT語句:</p>
<p align="JUSTIFY">SELECT CourseID,SectionNo,InstructorID,RoomNo, Schedule,Capacity
FROM Section</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY"> 建立記錄集后,用戶可以隨時調用Requery成員函數來重新查詢和建立記錄集.Requery有兩個重要用途:</p>
<ul>
<li>
<p align="JUSTIFY">使記錄集能反映用戶對數據源的改變(參見10.5.1).</p>
</li>
<li>
<p align="JUSTIFY">按照新的過濾或排序方法查詢記錄并重新建立記錄集.</p>
</li>
</ul>
<p> </p>
<p align="JUSTIFY"> 在調用Requery之前,可調用CanRestart來判斷記錄集是否支持Requery操作.要記住Requery只能在成功調用Open后調用,所以程序應調用IsOpen來判斷記錄集是否已建立.函數的聲明為</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">virtual BOOL Requery( );throw( CDBException,
CMemoryException );<br>
返回TRUE表明記錄集建立成功,否則返回FALSE.若函數內部出錯則產生異常.</p>
<p align="JUSTIFY">BOOL CanRestart( ) const; //若支持Requery則返回TRUE</p>
<p align="JUSTIFY">BOOL IsOpen( ) const; //若記錄集已建立則返回TRUE</p>
</blockquote>
</blockquote>
<p align="JUSTIFY"> CRecordset類有兩個公共數據成員m_strFilter和m_strSort用來設置對記錄的過濾和排序.在調用Open或Requery前,如果在這兩個數據成員中指定了過濾或排序,那么Open和Requery將按這兩個數據成員指定的過濾和排序來查詢數據源.</p>
<p align="JUSTIFY">成員m_strFilter用于指定過濾器.m_strFilter實際上包含了SQL的WHERE子句的內容,但它不含WHERE關鍵字.使用m_strFilter的一個例子為:</p>
<p align="JUSTIFY">m_pSet->m_strFilter=“CourseID=‘MATH101’”; //只選擇CourseID為MATH101的記錄</p>
<p align="JUSTIFY">if(m_pSet->Open(CRecordset::snapshot, “Section”))</p>
<p align="JUSTIFY"><b>. . . . . .</b></p>
<p align="JUSTIFY"> 成員m_strSort用于指定排序.m_strSort實際上包含了ORDER BY子句的內容,但它不含ORDER
BY關鍵字.m_strSort的一個例子為</p>
<p align="JUSTIFY">m_pSet->m_strSort=“CourseID DESC”; //按CourseID的降序排列記錄</p>
<p align="JUSTIFY">m_pSet->Open();</p>
<p align="JUSTIFY"><b>. . . . . .</b></p>
<p align="JUSTIFY"> 事實上,Open函數在構造SELECT語句時,會把m_strFilter和m_strSort的內容放入SELECT語句的WHERE和ORDER
BY子句中.如果在Open的lpszSQL參數中已包括了WHERE和ORDER BY子句,那么m_strFilter和m_strSort必需為空.</p>
<p align="JUSTIFY"> 調用無參數成員函數Close可以關閉記錄集.在調用了Close函數后,程序可以再次調用Open建立新的記錄集.CRecordset的析構函數會調用Close函數,所以當刪除CRecordset對象時記錄集也隨之關閉。</p>
<p><font color="#3973DE" face="Times New Roman" size="3">10.5.5 </font><font size="3" color="#3973DE">滾動記錄</font></p>
<p align="JUSTIFY"> CRecordset提供了幾個成員函數用來在記錄集中滾動,如下所示.當用這些函數滾動到一個新記錄時,框架會自動地把新記錄的內容拷貝到域數據成員中.</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">void MoveNext( ); //前進一個記錄</p>
<p align="JUSTIFY">void MovePrev( ); //后退一個記錄</p>
<p align="JUSTIFY">void MoveFirst( ); //滾動到記錄集中的第一個記錄</p>
<p align="JUSTIFY">void MoveLast( ); //滾動到記錄集中的最后一個記錄</p>
<p align="JUSTIFY">void SetAbsolutePosition( long nRows ); <br>
該函數用于滾動到由參數nRows指定的絕對位置處.若nRows為負數,則從后往前滾動.例如,當nRows為-1時,函數就滾動到記錄集的末尾.注意,該函數不會跳過被刪除的記錄.</p>
<p align="JUSTIFY">virtual void Move( long nRows, WORD wFetchType
= SQL_FETCH_RELATIVE );<br>
該函數功能強大.通過將wFetchType參數指定為SQL_FETCH_NEXT、SQL_FETCH_PRIOR、SQL_FETCH_FIRST、SQL_FETCH_LAST和SQL_FETCH_ABSOLUTE,可以完成上面五個函數的功能.若wFetchType為SQL_FETCH_RELATIVE,那么將相對當前記錄移動,若nRows為正數,則向前移動,若nRows為負數,則向后移動.</p>
</blockquote>
</blockquote>
<p> </p>
<p align="JUSTIFY"> 如果在建立記錄集時選擇了CRecordset::skipDeletedRecords選項,那么除了SetAbsolutePosition外,在滾動記錄時將跳過被刪除的記錄,這一點對象FoxPro這樣的數據庫十分重要.</p>
<p align="JUSTIFY"> 如果記錄集是空的,那么調用上述函數將產生異常.另外,必須保證滾動沒有超出記錄集的邊界.調用IsEOF和IsBOF可以進行這方面的檢測.</p>
<p align="JUSTIFY"> </p>
<blockquote>
<blockquote>
<p align="JUSTIFY">BOOL IsEOF( ) const;<br>
如果記錄集為空或滾動過了最后一個記錄,那么函數返回TRUE,否則返回FALSE.</p>
<p align="JUSTIFY">BOOL IsBOF( ) const;<br>
如果記錄集為空或滾動過了第一個記錄,那么函數返回TRUE,否則返回FALSE.</p>
</blockquote>
</blockquote>
<p> </p>
<p align="JUSTIFY">下面是一個使用IsEOF的例子:</p>
<p align="JUSTIFY">while(!m_pSet->IsEOF( ))</p>
<p align="JUSTIFY">m_pSet->MoveNext( );</p>
<p align="JUSTIFY">調用GetRecordCound可獲得記錄集中的記錄總數,該函數的聲明為</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">long GetRecordCount( ) const;<br>
要注意這個函數返回的實際上是用戶在記錄集中滾動的最遠距離.要想真正返回記錄總數,只有調用MoveNext移動到記錄集的末尾(MoveLast不行).</p>
</blockquote>
</blockquote>
<p><b> </b></p>
<p align="JUSTIFY"> <b></b><font color="#3973DE" face="Times New Roman" size="3">10.5.6
</font><font size="3" color="#3973DE">修改、添加和刪除記錄</font></p>
<p align="JUSTIFY">要修改當前記錄,應該按下列步驟進行:</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">調用Edit成員函數.調用該函數后就進入了編輯模式,程序可以修改域數據成員.注意不要在一個空的記錄集中調用Edit,否則會產生異常.Edit函數會把當前域數據成員的內容保存在一個緩沖區中,這樣做有兩個目的,一是可以與域數據成員作比較以判斷哪些字段被改變了,二是在必要的時侯可以恢復域數據成員原來的值.若再次調用Edit,則將從緩沖區中恢復域數據成員,調用后程序仍處于編輯模式.調用Move(AFX_MOVE_REFRESH)或Move(0)可退出編輯模式(AFX_MOVE_REFRESH的值為0),同時該函數會從緩沖區中恢復域數據成員.</p>
<p align="JUSTIFY">設置域數據成員的新值.</p>
<p align="JUSTIFY">調用Update完成編輯.Update把變化后的記錄寫入數據源并結束編輯模式.</p>
</blockquote>
</blockquote>
<p> </p>
<p align="JUSTIFY">要向記錄集中添加新的記錄,應該按下列步驟進行:</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">調用AddNew成員函數.調用該函數后就進入了添加模式,該函數把所有的域數據成員都設置成NULL(注意,在數據庫術語中,NULL是指沒有值,這與C++的NULL是不同的).與Edit一樣,AddNew會把當前域數據成員的內容保存在一個緩沖區中,在必要的時侯,程序可以再次調用AddNew取消添加操作并恢復域數據成員原來的值,調用后程序仍處于添加模式.調用Move(AFX_MOVE_REFRESH)可退出添加模式,同時該函數會從緩沖區中恢復域數據成員.</p>
<p align="JUSTIFY">設置域數據成員.</p>
<p align="JUSTIFY">調用Update.Update把域數據成員中的內容作為新記錄寫入數據源,從而結束了添加.</p>
</blockquote>
</blockquote>
<p> </p>
<p align="JUSTIFY">如果記錄集是快照,那么在添加一個新的記錄后,需要調用Requery重新查詢,因為快照無法反映添加操作.</p>
<p align="JUSTIFY">要刪除記錄集的當前記錄,應按下面兩步進行:</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">調用Delete成員函數.該函數會同時給記錄集和數據源中當前記錄加上刪除標記.注意不要在一個空記錄集中調用Delete,否則會產生一個異常.</p>
<p align="JUSTIFY">滾動到另一個記錄上以跳過刪除記錄.</p>
</blockquote>
</blockquote>
<p> </p>
<p align="JUSTIFY">上面提到的函數聲明為:</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">virtual void Edit( );throw( CDBException, CMemoryException
);</p>
<p align="JUSTIFY">virtual void AddNew( );throw( CDBException );</p>
<p align="JUSTIFY">virtual void Delete( );throw( CDBException );</p>
<p align="JUSTIFY">virtual BOOL Update( );throw( CDBException );
<br>
若更新失敗則函數返回FALSE,且會產生一個異常.</p>
</blockquote>
</blockquote>
<p> </p>
<p align="JUSTIFY"> 在對記錄集進行更改以前,程序也許要調用下列函數來判斷記錄集是否是可以更改的,因為如果在不能更改的記錄集中進行修改、添加或刪除將導致異常的產生.</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">BOOL CanUpdate( ) const; //返回TRUE表明記錄是可以修改、添加和刪除的.</p>
<p align="JUSTIFY">BOOL CanAppend( ) const; //返回TRUE則表明可以添加記錄.</p>
</blockquote>
</blockquote>
<div align="center">
<center>
<table border="0" cellpadding="0" cellspacing="0" width="615">
<tr>
<td><a href="chap10_4.htm">上一頁</a></td>
<td>
<p align="right"><a href="chap10_6.htm">下一頁</a>
</td>
</tr>
</table>
<p><a href="http://www.cpcw.com">電腦報首頁</a> <a href="../../index.htm">網絡學院首頁</a></p>
</center>
</div>
<font size="5">
<hr noshade color="#3973DE" size="1">
</font>
<p align="center"><font size="5"></font><font size="2" color="#000000">本教程由<a href="http://vcdynasty.yeah.net">Visual
C++王朝(Where programmers come together)</a>協助制作<br>
未經許可,請勿以任何形式復制</font>
</td>
</tr>
</table>
</center>
</div>
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -