CRecordset::FlushResultSet 

Retrieves the next result set of a predefined query (stored procedure), if there are multiple result sets.


BOOL FlushResultSet( );

Nonzero if there are more result sets to be retrieved; otherwise 0.

You should call FlushResultSet only when you are completely finished with the cursor on the current result set. Note that when you retrieve the next result set by calling FlushResultSet, your cursor is not valid on that result set; you should call the MoveNext member function after calling FlushResultSet.

If a predefined query uses an output parameter or input/output parameters, you must call FlushResultSet until it returns FALSE (the value 0), in order to obtain these parameter values.

FlushResultSet calls the ODBC API function SQLMoreResults. If SQLMoreResults returns SQL_ERROR or SQL_INVALID_HANDLE, then FlushResultSet will throw an exception. For more information about SQLMoreResults, see the Platform SDK.

In Visual C++ 2005 your stored procedure needs to have bound fields if you want to call FlushResultSet.

This method can throw exceptions of type CDBException*.

The following code assumes that COutParamRecordset is a CRecordset-derived object based on a predefined query with an input parameter and an output parameter, and having multiple result sets. Note the structure of the DoFieldExchange override.

// DoFieldExchange override
//
// Only necessary to handle parameter bindings.
// Don't use CRecordset-derived class with bound
// fields unless all result sets have same schema
// OR there is conditional binding code.

void COutParamRecordset::DoFieldExchange( CFieldExchange* pFX )
{
   pFX->SetFieldType( CFieldExchange::outputParam );
   RFX_Long( pFX, "Param1", m_nOutParamInstructorCount );
         // The "Param1" name here is a dummy name 
         // that is never used

   pFX->SetFieldType( CFieldExchange::inputParam );
   RFX_Text( pFX, "Param2", m_strInParamName );
         // The "Param2" name here is a dummy name 
         // that is never used

}


// Now implement COurParamRecordset.

// Assume db is an already open CDatabase object
COutParamRecordset rs( &db );
rs.m_strInParamName = _T("Some_Input_Param_Value");

// Get the first result set
// NOTE: SQL Server requires forwardOnly cursor 
//       type for multiple rowset returning stored 
//       procedures
rs.Open( CRecordset::forwardOnly, 
         "{? = CALL GetCourses( ? )}", 
         CRecordset::readOnly);

// Loop through all the data in the first result set
while ( !rs.IsEOF( ) )
{
   CString strFieldValue;
   for( int nIndex = 0; 
        nIndex < rs.GetODBCFieldCount( ); 
        nIndex++ )
   {
      rs.GetFieldValue( nIndex, strFieldValue );

      // TO DO: Use field value string.
   }
   rs.MoveNext( );
}

// Retrieve other result sets...
while( rs.FlushResultSet( ) )
{
   // must call MoveNext because cursor is invalid
   rs.MoveNext( );

   while ( !rs.IsEOF( ) )
   {
      CString strFieldValue;
      for( int nIndex = 0; 
           nIndex < rs.GetODBCFieldCount( ); 
           nIndex++ )
      {
         rs.GetFieldValue( nIndex, strFieldValue );

         // TO DO: Use field value string.
      }
      rs.MoveNext( );
   }
}


// All result sets have been flushed. Cannot
// use the cursor, but the output parameter,
// m_nOutParamInstructorCount, has now been written.
// Note that m_nOutParamInstructorCount not valid until
// CRecordset::FlushResultSet has returned FALSE,
// indicating no more result sets will be returned.

// TO DO: Use m_nOutParamInstructorCount

// Cleanup
rs.Close( );
db.Close( );

Community Additions

ADD
Show: