t来判断记录集是否支持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对象时记录集也随之关闭。
10.5.5 滚动记录
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不行).
10.5.6 修改、添加和删除记录
要修改当前记录,应该按下列步骤进行:
调用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( CDBExc