Executes the command.
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.
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.
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.