Executes the command.
HRESULT Execute (
IUnknown * pUnkOuter,
REFIID riid,
DBPARAMS * pParams,
LONG * pcRowsAffected,
IUnknown ** ppRowset);
Parameters
pUnkOuter
[in]
A pointer to the controlling IUnknown interface if the rowset is being created as part of an aggregate; otherwise, it is null.
riid
[in]
The requested IID for the rowset returned 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, then 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, Execute returns E_NOINTERFACE.
pParams
[in/out]
A pointer to a DBPARAMS structure that specifies the values for one or more parameters. In text commands that use parameters, if no value is specified for a parameter through pParams, an error occurs.
struct DBPARAMS {
void * pData;
ULONG cParamSets;
HACCESSOR hAccessor;
};
The elements of this structure are used as follows.
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 "Setting Data" and "Getting Data" in Chapter 6. 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, then 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 CreateAccessor was 0), then Execute does not retrieve or return any parameter values. |
If the command text does not include parameters, the provider ignores this argument.
pcRowsAffected
[out]
A pointer to memory in which to return the count of rows affected by a command that updates, deletes, or inserts rows. If cParamSets is greater than one, *pcRowsAffected is the total number of rows affected by all of the sets of parameters specified in the execution. If the number of affected rows is not available, *pcRowsAffected is set to DB_COUNTUNAVAILABLE on output. If riid is IID_IMultipleResults, the value returned in *pcRowsAffected is either DB_COUNTUNAVAILABLE or the total number of rows affected by the entire command; to retrieve individual row counts, the consumer calls IMultipleResults::GetResult. If the command does not update, delete, or insert rows, *pcRowsAffected is undefined on output. If pcRowsAffected is a null pointer, no count of rows is returned.
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.
ppRowset
[in/out]
A pointer to the memory in which to return the rowset's pointer. If ppRowset is a null pointer, no rowset is created.
Return Code
S_OK
The method succeeded. In all DBPROP structures returned by the method, dwStatus is set to DBPROPSTATUS_OK, the status of all input parameters bound by the accessor is set to DBSTATUS_S_OK or DBSTATUS_S_ISNULL, and the status of all output parameters bound by the accessor is set to DBSTATUS_S_OK, DBSTATUS_S_ISNULL, or DBSTATUS_S_TRUNCATED or is unknown because the parameter value has not been returned yet.
DB_S_ASYNCHRONOUS
The method has initiated asynchronous creation of the rowset. The consumer can call IDBAsynchStatus to poll for status or IConnectionPointContainer to obtain the IID_IDBAsynchNotify connection point. Attempting to call any other interfaces may fail, and the full set of interfaces may not be available on the object until asynchronous initialization of the rowset has completed.
DB_S_ERRORSOCCURRED
This can be returned for any of the following reasons.
DB_S_STOPLIMITREACHED
Execution has been stopped because a resource limit has been reached. The results obtained so far have been returned. Execution cannot be resumed.
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.
E_FAIL
A provider-specific error occurred.
E_INVALIDARG
pParams was not ignored, cParamSets in the DBPARAMS structure pointed to by pParams was greater than one, ppRowset was not a null pointer, and the provider does not support multiple results.
pParams was not ignored and, in the DBPARAMS structure pointed to by pParams, pData was a null pointer.
pParams was not ignored, was not a null pointer, and in the DBPARAMS structure pointed to by pParams, cParamSets was zero.
riid was not IID_NULL and ppRowset was a null pointer.
E_NOINTERFACE
The rowset did not support the interface specified in riid.
riid was IID_IMultipleResults and the provider did not support multiple results objects.
DB_E_ABORTLIMITREACHED
Execution has been aborted because a resource limit has been reached. For example, a query timed out. No results have been returned.
DB_E_BADACCESSORHANDLE
pParams was not ignored and hAccessor in the DBPARAMS structure pointed to by pParams was invalid.
DB_E_BADACCESSORTYPE
hAccessor in the DBPARAMS structure pointed to by pParams was not the handle of a parameter accessor.
DB_E_CANCELED
The command was canceled by a call to Cancel on another thread. No records were affected.
DB_E_CANTCONVERTVALUE
A literal value in the command text 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 overflowed the type specified by the associated column.
DB_E_ERRORSINCOMMAND
The command text 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. 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.
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.
DB_E_INTEGRITYVIOLATION
A literal value in the command text violated the integrity constraints for the column.
DB_E_NOAGGREGATION
pUnkOuter was not a null pointer and the rowset being created does not support aggregation.
pUnkOuter was non-null and riid was not IID_Unknown.
DB_E_NOCOMMAND
No command text was currently set on the command object.
DB_E_NOTABLE
The specific table or view does not exist in the current data source.
DB_E_PARAMNOTOPTIONAL
A value was not supplied for a required parameter.
The command text used parameters and pParams was a null pointer.
DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to execute the command. For example, a rowset-returning command specified a column for which the consumer does not have read permission, or an update command specified a column for which the consumer does not have write permission.
DB_E_OBJECTOPEN
The provider would have to open a new connection to support the operation and DBPROP_MULTIPLECONNECTIONS is set to VARIANT_FALSE.
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:
E_NOINTERFACE
DB_E_BADBINDINFO
DB_E_BADORDINAL
DB_E_BADSTORAGEFLAGS
DB_E_UNSUPPORTEDCONVERSION
Comments
If the command returns rows, 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 returns multiple results (rowsets or row counts), the consumer requests a multiple-results object by setting riid to IID_IMultipleResults. 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.
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.
If 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.
Execute can be called when a rowset is already open on the command only 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 Execute creates a new rowset, which must be explicitly released by IRowset::Release.
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, Execute ignores pParams. However, if the command text includes parameters, Execute returns DB_E_ERRORSINCOMMAND.
If an input parameter value is not specified, Execute returns DB_E_PARAMNOTOPTIONAL. If the provider cannot describe parameters and the consumer has not called SetParameterInfo for all parameters, the behavior of Execute is undefined. For example, Execute might guess at the parameter information or it might fail completely. For more information, see SetParameterInfo.
If 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 Chapter 11.
Execute does not alter the value of any properties. That is, ICommandProperties::GetProperties returns the same value for a property regardless of whether it is called before or after Execute and whether 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.
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.
See Also
ICommand::Cancel, ICommandPrepare::Prepare, ICommandText::SetCommandText, ICommandWithParameters::SetParameterInfo