Share via


IMultipleResults::GetResult

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

Syntax

HRESULT GetResult(
   IUnknown     *pUnkOuter,
   DBRESULTFLAG  lResultFlag,
   REFIID        riid,
   DBROWCOUNT   *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.

  • lResultFlag
    [in] This flag is ignored when returning row counts. When returning result objects (for example, rowset or row objects), the values described in the following table apply.

    Enum

    Description

    DBRESULTFLAG_DEFAULT

    The type of the returned object is defined by riid or by properties set on the command object. If this is ambiguous, the provider should return a rowset. Prior to OLE DB 2.6, providers were required to return E_INVALIDARG when lResultFlag was not zero. Consumers should not pass nonzero values unless the provider is a 2.6 or later provider and has added support for lResultFlag.

    DBRESULTFLAG_ROWSET

    The consumer explicitly requests a rowset object.

    DBRESULTFLAG_ROW

    The consumer explicitly requests a row object.

    Providers that support the return of row objects from ICommand::Execute and also support multiple results should support returning row objects from calls to IMultipleResults::GetResult, as described by the flag values in the preceding table.

    As in ICommand::Execute, when returning a row object from IMultipleResults::GetResult, if the statement would have returned multiple rows, the provider is encouraged, but not required, to return DB_S_NOTSINGLETON.

    If lResultFlag is not zero and the riid does not match the requested object type, the provider should return E_NOINTERFACE.

    If lResultFlag is not zero and a command property (for example, DBPROP_IRow or DBPROP_IRowset) conflicts with the requested object type, the provider should return DB_S_ERRORSOCCURRED with a suitable DBPROPSTATUS value, such as DBPROPSTATUS_CONFLICTING if the property is optional, or DB_E_ERRORSOCCURRED if the property is required.

  • 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:

    • An error occurred, returning one or more output parameter values associated with the next result. To determine which output parameters were not returned, the consumer checks the status values. For a list of status values that can be returned by this method, see "Status Values Used When Getting Data" in Status.

    • The rowset was opened, but one or more properties ? for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_OPTIONAL ? were not set. The consumer calls IRowsetInfo::GetProperties to determine which properties were set.

  • DB_S_NOTSINGLETON
    The provider supports returning row objects on IMultipleResults::GetResult, and the consumer requested a row object but the result was not a singleton. A row object of the first row of the rowset is returned if the provider supports returning the row object. Because returning this result may be expensive, providers are not required to do so. If DB_S_ERRORSOCCURRED also applies to the execution of this method, it takes precedence over DB_S_NOTSINGLETON.

  • 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
    The value passed in for lResultFlag was invalid or not supported.

  • 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.

    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 rowset.

  • 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. A result is returned for each separate statement in the command text or from each set of parameters passed to a command. 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:

  • If IMultipleResults::GetResult returns E_INVALIDARG, DB_E_NOAGGREGATION or DB_E_OBJECTOPEN, the current result is still available. Assuming there are no other errors, the next call to IMultipleResults::GetResult returns the current result.

  • If IMultipleResults::GetResult returns any other error, the current result is lost. The next call to IMultipleResults::GetResult returns either the next result or DB_S_NORESULT if the error caused the provider to lose all remaining results. Providers that can recover the current result in this situation must discard it and return the next result.

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

hr = pICommandText->Execute(pUnkOuter, IID_IMultipleResults, pParams,
                        &cRowsAffected,(IUnknown**)&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

Reference

ICommand::Execute