MDAC 2.5 SDK - OLE DB Programmer's Reference
OLE DB Interfaces


 

IMultipleResults::GetResult

Returns the next in a series of multiple results from the provider.

HRESULT GetResult(
   IUnknown *    pUnkOuter,
   LONG          lReserved,
   REFIID        riid,
   LONG *        pcRowsAffected,
   IUnknown **   ppRowset);

Parameters

pUnkOuter

[in]
A pointer to the controlling IUnknown interface if the object is being created as part of an aggregate; otherwise, it is a null pointer.

lReserved

[in]
Reserved. Must be set to zero.

riid

[in]
The requested interface to return in *ppRowset. This interface is conceptually added to the list of required interfaces on the resulting rowset, and the method fails (E_NOINTERFACE) if that interface cannot be supported on the resulting rowset.

If this is IID_NULL, ppRowset is ignored and no rowset is returned, even if one exists.

pcRowsAffected

[out]
A pointer to memory in which to return the count of rows affected by an update, delete, or insert. If the value of cParamSets passed into ICommand::Execute was greater than 1, *pcRowsAffected is the total number of rows affected by all of the sets of parameters represented by the current result. If the count of affected rows is not available, *pcRowsAffected is set to DB_COUNTUNAVAILABLE on output. If the result is not a count of rows affected by an update, delete, or insert, *pcRowsAffected is undefined on output. If an error occurs, *pcRowsAffected is set to DB_COUNTUNAVAILABLE. If pcRowsAffected is a null pointer, no count of affected rows is returned.

Some providers do not support returning individual counts of rows but instead return an overall count of the total rows affected by the call to ICommand::Execute, or they do not return row counts at all. Such providers set *pcRowsAffected to DB_COUNTUNAVAILABLE when the count of affected rows is not available.

ppRowset

[out]
A pointer to memory in which to return the interface for the next result. If the next result is not a rowset (for example, if it is the count of the rows affected by an update, delete, or insert), this is set to a null pointer. If an error occurs, *ppRowset is set to a null pointer.

If ppRowset is a null pointer, no rowset is created.

Return Code

S_OK

The method succeeded.

DB_S_ERRORSOCCURRED

This can be returned for either of the following reasons:

DB_S_NORESULT

There are no more results. *ppRowset is set to a null pointer, and *pcRowsAffected is set to –1.

DB_S_STOPLIMITREACHED

Execution has been stopped because a resource limit has been reached. The results obtained so far have been returned. Calling IMultipleResults::GetResult again returns information for the next result or returns DB_S_NORESULT if no more results can be obtained, either because they do not exist or because the resource limit applies across multiple results.

This return code takes precedence over DB_S_ERRORSOCCURRED. That is, if the conditions described here and those described in DB_S_ERRORSOCCURRED both occur, the provider returns this code. When the consumer receives this return code, it should also check for the conditions described in DB_S_ERRORSOCCURRED.

E_FAIL

A provider-specific error occurred.

E_INVALIDARG

lReserved was not zero.

E_NOINTERFACE

The interface specified in riid was not supported on the rowset.

E_OUTOFMEMORY

The provider was unable to allocate sufficient memory in which to create the rowset.

E_UNEXPECTED

ITransaction::Commit or ITransaction::Abort was called, and the object is in a zombie state.

DB_E_ABORTLIMITREACHED

Execution has been aborted because a resource limit has been reached. No results have been returned. Calling IMultipleResults::GetResult again returns information for the next result or returns DB_S_NORESULT if no more results can be obtained, either because they do not exist or because the resource limit applies across multiple results.

DB_E_CANTCONVERTVALUE

A literal value in the command text associated with the next result could not be converted to the type of the associated column for reasons other than data overflow.

DB_E_DATAOVERFLOW

A literal value in the command text associated with the next result overflowed the type specified by the associated column.

DB_E_ERRORSINCOMMAND

The command text associated with the next result contained one or more errors. Providers should use OLE DB error objects to return details about the errors.

DB_E_ERRORSOCCURRED

The method failed due to one or more invalid input parameter values associated with the next result. To determine which input parameter values were invalid, the consumer checks the status values. For a list of status values that can be returned by this method, see "Status Values Used When Setting Data" in "Status" in Chapter 6, "Getting and Setting Data."

The rowset was not returned because one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_REQUIRED or an invalid value—could not be satisfied.

DB_E_INTEGRITYVIOLATION

A literal value in the command text associated with the next result violated the integrity constraints for the column.

DB_E_NOAGGREGATION

pUnkOuter was not a null pointer, and the provider is an OLE DB 1.0 or 1.1 provider that does not support aggregation of the object being created.

pUnkOuter was not a null pointer, and riid was not IID_IUnknown.

DB_E_NOTFOUND

The provider supports the return of singleton row objects on a method that typically returns a rowset, a row was requested via riid or DBPROP_IRow, and no rows existed in the table.

DB_E_OBJECTOPEN

The previous rowset is still open, and the provider does not support multiple open results simultaneously. (DBPROP_MULTIPLERESULTS is DBPROPVAL_MR_SUPPORTED.)

DB_SEC_E_PERMISSIONDENIED

The consumer did not have sufficient permission to get the next result.

Comments

IMultipleResults::GetResult returns the next in a series of multiple results from the provider. If the next result is the result of a row-returning command or operation, such as an SQL SELECT statement, the result of this method is a rowset over the result rows. If no rows match the command, the rowset is still created. The resulting rowset is fully functional and can be used, for example, to insert new rows or determine column metadata. If the next result is the result of a non-row-returning command, such as an SQL INSERT statement, *ppRowset is set to NULL and *pcRowsAffected is set to the count of rows affected, if applicable.

Rowsets returned by IMultipleResults::GetResult have the properties set as defined by the command that created the multiple results object. These properties are identical for each result set. There is no way to set different properties for results of a multiple result.

Providers will generally be able to process only one result at a time. For maximum interoperability, consumers should free any rowset obtained by a previous call to IMultipleResults::GetResult before requesting the next result.

If ICommand::Execute is called multiple times for a single command, with or without changes to the command text, the outcome may reflect changes in the underlying stored data, depending on the isolation level specified for the surrounding transaction.

When executing a command whose command text is a sequence of subcommands and also requesting a multiple results object, the provider must ensure that subcommands are executed in the order they appear in the command text and that any command whose results have been retrieved via IMultipleResults::GetResult has been executed.

It is provider-specific whether each of the subcommands is executed at ICommand::Execute or just-in-time for IMultipleResults::GetResult, and it is also provider-specific whether subcommands whose results have not been obtained have been executed.

Providers may check the entire command text for errors at execute time or may check the command text associated with each result when that result is retrieved. Therefore, the syntax errors returned by ICommand::Execute can also be returned by IMultipleResults::GetResult. In this case, the next call to IMultipleResults::GetResult moves on to the next result or returns DB_S_NORESULT if no more results are available.

When IMultipleResults::GetResult returns an error, its behavior depends on the error that occurred, as in the following scenarios:

The following example shows how a consumer might process multiple results:

hr = pICommandText->Execute(pUnkOuter, IID_IMultipleResults, pParams, 
                            &cRowsAffected,  &pIMultipleResults);
if (pIMultipleResults) {
   while(hr != DB_S_NORESULT) {
      if(SUCCEEDED(hr = pIMultipleResults->GetResult(pUnkOuter, 0, 
         IID_IRowset,  &cRowsAffected, &pIRowset))) {
         if(pIRowset) {
            // The next result is a rowset. Process the rowset.
            pIRowset->Release();
         } else {
            // The next result is not a rowset. Process the 
            // nonrowset result.
      }
      } else {
         // Process error from GetResult.
         break;
      }
   }
   pIMultipleResults->Release();
}

See Also

ICommand::Execute