Executes the command.
HRESULT Execute ( IUnknown *pUnkOuter, REFIID riid, DBPARAMS *pParams, DBROWCOUNT *pcRowsAffected, IUnknown **ppRowset);
Parameters
If this is IID_NULL, ppRowset is ignored and no rowset is returned, even if the command would otherwise generate a rowset. Specifying IID_NULL is useful in the case of text commands that do not generate rowsets, such as data definition commands, as a hint to the provider that no rowset properties need to be verified.
If riid is IID_IMultipleResults, the provider creates a multiple results object and returns a pointer to it in *ppRowset; it does this even if the command generates a single result. If the provider supports multiple results and the command generates multiple results but riid is not IID_IMultipleResults, the provider returns the first result and discards any remaining results. If riid is IID_IMultipleResults and the provider does not support multiple results, ICommand::Execute returns E_NOINTERFACE.
struct DBPARAMS { void *pData; DB_UPARAMS cParamSets; HACCESSOR hAccessor; };
The elements of this structure are used as described in the following table.
Element | Description |
---|---|
pData | Pointer to a buffer from which the provider retrieves input parameter data and to which the provider returns output parameter data, according to the bindings specified by hAccessor. This pointer must be a valid pointer to a contiguous block of consumer-owned memory for the input and output parameter values. For more information, see "Getting Data" and "Setting Data" in Chapter 6: Getting and Setting Data.
When output parameter data is available to the consumer depends on the DBPROP_OUTPUTPARAMETERAVAILABILITY property. |
cParamSets | The number of sets of parameters in *pData. If cParamSets is greater than one, the bindings described by hAccessor define the offsets within *pData for each set of parameters and cbRowSize (as specified in IAccessor::CreateAccessor) defines a single fixed offset between each of those values and the corresponding values for the next set of parameters. Sets of multiple parameters (cParamSets is greater than one) can be specified only if DBPROP_MULTIPLEPARAMSETS is VARIANT_TRUE and the command does not return any rowsets. |
hAccessor | Handle of the accessor to use. If hAccessor is the handle of a null accessor (cBindings in IAccessor::CreateAccessor was 0), ICommand::Execute does not retrieve or return any parameter values. |
If the provider is able to determine the number of parameters in the command and the command text does not include parameters, the provider ignores this argument.
pcRowsAffected is undefined if ICommand::Execute returns DB_S_ASYNCHRONOUS. For asynchronously executed commands, the consumer should call IDBAsynchStatus::GetStatus to obtain the number of rows affected in pulProgress.
If ppRowset is not a null pointer and an interface on a stream object was requested, the provider returns to *ppRowset the interface pointer set in the DBPROP_OUTPUTSTREAM property. The consumer must release the interface pointer in *ppRowset when it is no longer needed.
If *ppRowset is a null pointer, the provider did not write any results to the stream specified in DBPROP_OUTPUTSTREAM.
Return Code
DB_S_ASYNCHRONOUS should be returned before DB_S_ERRORSOCCURRED. Once rowset population is complete, the consumer can see DB_S_ERRORSOCCURRED either by calling IDBAsynchStatus::GetStatus or by receiving IDBAsynchNotify::OnStop.
DB_S_ERRORSOCCURRED should be returned before DB_S_NOTSINGLETON because the status values can be checked, and providers are not required to return DB_S_NOTSINGLETON.
Multiple sets of parameters were specified, and one or more (but not all) of the parameters have been processed prior to the command being canceled by ICommand::Cancel or IDBAsynchStatus::Abort.
This return code takes precedence over DB_S_ERRORSOCCURRED. That is, if the conditions described here and in 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.
The parameter information was invalid. Parameter information may be invalid for any of the following reasons. In all cases, any streams used to pass input parameters are not released.
riid was IID_IMultipleResults, and the provider did not support multiple results objects.
The command was not executed, and no rowset was returned because one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_REQUIRED—were not set.
Multiple parameter sets were passed with a command that returns a rowset. (Some providers might not return this error.)
pUnkOuter was not a null pointer, and riid was not IID_IUnknown. Any streams used to pass input parameters are not released.
The command text used parameters and pParams was a null pointer.
If a session is enlisted in a global transaction and a command requires the creation of an additional connection, the provider should return DB_E_OBJECTOPEN. Providers written prior to OLE DB 2.6 may return E_FAIL.
Comments
If this method performs deferred accessor validation and that validation takes place before any data is transferred, it can also return any of the following HRESULTs for the reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor. In all cases, any streams used to pass input parameters are not released.
E_NOINTERFACE
DB_E_BADBINDINFO
DB_E_BADORDINAL
DB_E_BADSTORAGEFLAGS
DB_E_UNSUPPORTEDCONVERSION
If the command is a row-returning command, 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 command is a non-row-returning command, such as an SQL INSERT statement, *ppRowset is set to NULL and no rowset is returned.
If the command returns multiple results (row counts, rowset objects, or row objects), the consumer requests a multiple-results object by setting riid to IID_IMultipleResults. ICommand::Execute creates the multiple results object and returns an IMultipleResults interface pointer to it in *ppRowset. The consumer repeatedly calls IMultipleResults::GetResult to retrieve the results in order. For more information, see "Multiple Results" in Chapter 3: Commands.
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.
If any or all parameters fail and the provider does not support errors within an array of parameters (that is, the command fails if any or all of the parameters fail), the provider returns DB_E_ERRORSOCCURRED and returns any error information for the failed parameters in their status bindings.
If any or all parameters fail and the provider supports errors within an array of parameters, the provider returns DB_S_ERRORSOCCURRED, sets pcRowsAffected to the number of successful parameters, and returns any error information for the failed parameters in their status bindings.
When populating output parameters and the command produces a nonsingleton result, the provider returns S_OK and populates the output parameters with values from the first row of the result. If the underlying command processor does not support nonsingleton results with output parameters, the provider returns a provider-specific error.
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.
ICommand::Execute can be called when a rowset is already open on the command if the only change between the calls is a change in the value of existing parameters. (Calls to ICommandWithParameters::SetParameterInfo will fail.) Methods that modify the command (ICommandPrepare::Prepare, ICommandPrepare::Unprepare, ICommandProperties::SetProperties, and ICommandText::SetCommandText) while a rowset is open will fail and return DB_E_OBJECTOPEN. Each call to ICommand::Execute creates a new rowset, which must be explicitly released by IUnknown::Release.
ICommand::Execute does not affect the prepared state of a command.
The consumer determines whether the command supports parameters by calling QueryInterface for ICommandWithParameters. If this interface is exposed, the command supports parameters; if it is not exposed, the command does not support parameters. If the command does not support parameters, ICommand::Execute ignores pParams. However, if the command text includes parameters, ICommand::Execute returns DB_E_ERRORSINCOMMAND.
Consumers should not assume providers will derive parameter information. Use ICommandWithParameters::SetParameterInfo to explictly set or ICommandWithParameters::GetParameterInfo to explictly derive parameter information.
If an input parameter value is not specified, ICommand::Execute returns DB_E_PARAMNOTOPTIONAL. If the provider cannot describe parameters and the consumer has not called ICommandWithParameters::SetParameterInfo for all parameters, the behavior of ICommand::Execute is undefined. For example, ICommand::Execute might guess at the parameter information or it might fail completely. For more information, see SetParameterInfo.
If ICommand::Execute returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED, the consumer can immediately call ICommandProperties::GetProperties with the DBPPROPSET_PROPERTIESINERROR property set to return the properties that could not be set. For more information, see "Property Sets" in Appendix C: OLE DB Properties.
ICommand::Execute does not alter the value of any properties. That is, ICommandProperties::GetProperties returns the same value for a property whether or not it is called before or after Execute and whether or not Execute succeeded or failed. However, if a property value is not required, IRowsetInfo::GetProperties can return a different value for that property than ICommandProperties::GetProperties. For more information, see IRowsetInfo::GetProperties.
If several threads concurrently request execution of a given command, the corresponding executions are serialized and each thread will block until its corresponding execution concludes.
ICommand::Execute can fail even if ICommandPrepare::Prepare has succeeded; this may be the case if, for example, the underlying schema has changed between the Prepare and Execute calls and the command text had therefore become illegal.
Except where otherwise indicated, the provider frees all streams used to pass input parameters.
ICommand::Execute operates on the last command specified by either ICommandText::SetCommandText or ICommandStream::SetCommandStream. If Execute is called again, the same command is re-executed even if the command is contained in a stream whose contents are normally inaccessible after having been read once.
ICommand::Cancel | ICommandPrepare::Prepare | ICommandText::SetCommandText | ICommandWithParameters::SetParameterInfo