HRESULT _hr = get_adoEOF(&_result);
IsEOF()函数如下:其中ADOCG::_RecordsetPtr m_pRecordset;
BOOL IsEOF() {return m_pRecordset->adoEOF == VARIANT_TRUE;};
m_pRecordset->adoEOF 将执行下面的函数(见msado15。tli)
1 inline VARIANT_BOOL Recordset15::GetadoEOF ( ) {
2 VARIANT_BOOL _result = 0;
3 HRESULT _hr = get_adoEOF(&_result);
4 if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
5 return _result;
6 }
程序将在上述第三行代码处抛出异常。
经过查询网上的资料以及和同事一起研究发现。在存储过程中没有返回记录集的路径中增加一个SELECT TOP 0 0 创造一个空记录集返回也可避免该异常的发生。所以,存储过程中没有返回记录集是导致该问题的根本原因。
还有一种避免(仅仅是避免)该异常的方法是在执行完存储过程后,先使用如下代码来判断记录集是否已经打开
if (m_pRecordset->GetState() == ADOCG::adStateClosed)
return FALSE;
else
return TRUE;
如果记录集未打开,则直接通知上传调用模块不要再做记录集操作。
最后小结下该问题的处理方法。
1.程序调用存储过程时,是否返回记录集时由存储过程本身决定的。一般的我们首先使用SET NOCOUNT ON 来关闭计数,防止干扰我们通过SELECT语句返回我们期望的记录集。
2.从存储过程本身下手。保证设计为返回记录集的存储过程,必须在任何时候都有查询语句返回记录集。即使查询条件不符合也要返回一个空记录集。以保证存储过程的健壮性。
3.修改ADO封装类的函数:BOOL CADORecordset::Open(LPCTSTR lpstrExec)
在执行存储过程并返回记录集后,先检查记录集是否打开。如果未打开,则返回FALSE,通知上层程序,打开记录集出错。 应该进行相应的错误处理而不是继续操作记录集。
存储过程不返回记录集导致ADO程序出错的分析 - nscboy的专栏 - CSDN博客 http://blog.csdn.net/nscboy/article/details/4168777