IAccessor::CreateAccessor

Creates an accessor from a set of bindings.

Syntax

HRESULT CreateAccessor (
   DBACCESSORFLAGS   dwAccessorFlags,
   DBCOUNTITEM       cBindings,
   const DBBINDING   rgBindings[],
   DBLENGTH          cbRowSize,
   HACCESSOR        *phAccessor,
   DBBINDSTATUS      rgStatus[]);

Parameters

  • dwAccessorFlags
    [in] A bitmask that describes the properties of the accessor and how it is to be used. These flags have the following meanings.

    Value

    Description

    DBACCESSOR_INVALID

    This flag is used by IAccessor::GetBindings to indicate that the method failed.

    DBACCESSOR_PASSBYREF

    The accessor is a reference accessor.

    The value passed in the consumer buffer is a pointer to the passer's internal buffer. This pointer need not point to the start of the internal buffer as long as the relative offsets of all elements of the buffer align with the offsets specified in the accessor. The passee must know the internal structure of the passer's buffer in order to read information from it. The passee must not free the buffer at the pointer nor may it write to this buffer.

    For row accessors, this buffer is the rowset's copy of the row. The consumer reads information directly from this copy of the row at a later point in time, so the provider must guarantee that the pointer remains valid.

    For parameter accessors, this buffer is the consumer's buffer. The provider reads data from this buffer only when ICommand::Execute is called; therefore, the pointer is not required to remain valid after Execute returns.

    Support for this flag is optional. A consumer determines whether a provider supports this bit by calling IDBProperties::GetProperties for the DBPROP_BYREFACCESSORS property.

    When this flag is used, the dwMemOwner in the DBBINDING structure is ignored. If the accessor is used for row data, the accessor refers to the provider's memory; the consumer must not write to or free this memory. If the accessor is used for input parameters, the provider copies the row of data without assuming ownership.

    It is an error to specify an output or input/output parameter in a reference accessor.

    For more information, see Reference Accessors in Getting and Setting Data (OLE DB).

    DBACCESSOR_ROWDATA

    The accessor is a row accessor and describes bindings to columns in the rowset.

    An accessor may be a row accessor, a parameter accessor, or both.

    DBACCESSOR_PARAMETERDATA

    The accessor is a parameter accessor and describes bindings to parameters in the command text. In a parameter accessor, it is an error to bind an input or an input/output parameter more than one time.

    DBACCESSOR_OPTIMIZED

    The row accessor is to be optimized. This hint may affect how a provider structures its internal buffers. A particular column can be bound by only one optimized accessor. The column can also be bound by other, nonoptimized accessors, but the types specified in the nonoptimized accessors must be convertible from the type in the optimized accessor. All optimized accessors must be created before the first row is fetched with IRowset::GetNextRows, IRowsetLocate::GetRowsAt, IRowsetLocate::GetRowsByBookmark, or IRowsetScroll::GetRowsAtRatio.

    This flag is ignored for parameter accessors and may be ignored by providers that do not provide further optimizations or restrictions based on its setting. Providers that enforce restrictions, such as limiting the number or types of columns bound in optimized accessors, must set this flag when IAccessor::GetBindings is called on an optimized accessor. Providers that do not impose any restrictions on optimized accessors or that ignore this flag entirely are not required to return this flag when IAccessor::GetBindings is called.

    DBACCESSOR_INHERITED

    Indicates an accessor on a command should be inherited by a rowset when the rowset implementation is in a separate component from the command object. IAccessor::CreateAccessor is then used to pass an existing command accessor to the rowset implementation.

    When DBACCESSOR_INHERITED is specified, phAccessor is used as an [in] argument and contains a pointer to the value of the existing accessor handle. The rowset component then creates an internal accessor according to the specified bindings for this handle value.

  • cBindings
    [in] The number of bindings in the accessor.

    If cBindings is zero, IAccessor::CreateAccessor creates a null accessor. Null accessors are used only by IRowsetChange::InsertRow to create a new row in which each column is set to its default value, NULL, or a status of DBSTATUS_E_UNAVAILABLE. Providers that support IRowsetChange::InsertRow must support the creation of null accessors. For more information, see InsertRow.

  • rgBindings
    [in] An array of DBBINDING structures. For more information, see DBBINDING Structures.

  • cbRowSize
    [in] The number of bytes allocated for a single set of parameters or criteria values in the consumer's buffer.

    cbRowSize is used by ICommand::Execute to process multiple sets of parameters and by IViewFilter::GetFilter and IViewFilter::SetFilter to get and set multiple OR conditions in criteria. In either case, a single accessor may describe multiple sets of values. cbRowSize is generally the size of the structure that contains a single set of parameter or criteria values and is used as the offset to the start of the next set of values within the array of structures. For example, if cParamSets is greater than 1 in the DBPARAMS structure passed to ICommand::Execute, the provider assumes that the pData element of this structure points to an array of structures containing parameter values, each cbRowSize bytes in size. Similarly, if cRows is greater than 1 in IViewFilter::SetFilter, the provider assumes that the pCriteriaData argument points to an array of structures containing criteria values, each cbRowSize bytes in size.

    cbRowSize must be large enough to contain the structure defined by the bindings in rgBindings. The provider is not required to verify this, although it may.

    cbRowSize is not used when fetching rowset data.

  • phAccessor
    [out] A pointer to memory in which to return the handle of the created accessor. If IAccessor::CreateAccessor fails, it must attempt to set *phAccessor to a null handle.

  • rgStatus
    [out] An array of cBindings DBBINDSTATUS values in which IAccessor::CreateAccessor returns the status of each binding ? that is, whether or not it was successfully validated. If rgStatus is a null pointer, no bind status values are returned. The consumer allocates and owns the memory for this array. The bind status values are returned for the reasons described in the following table.

    Value

    Description

    DBBINDSTATUS_OK

    No errors were found in the binding. Because accessor validation can be deferred, a status of DBBINDSTATUS_OK does not necessarily mean that the binding was successfully validated.

    DBBINDSTATUS_BADORDINAL

    A parameter ordinal was zero in a parameter accessor.

    If the accessor is validated against the metadata when IAccessor::CreateAccessor is called, DBBINDSTATUS_BADORDINAL can be returned for the following reasons:

    • In a row accessor, a column ordinal in a binding was outside the range of available columns on the rowset.

    • In a parameter accessor, a parameter ordinal was greater than the number of parameters in the command text.

    These reasons cause a status value of DBSTATUS_E_BADACCESSOR to be returned if the accessor is validated when used.

    Some providers may support binding more parameters than the number of parameters in the command text, and such providers do not return DBBINDSTATUS_BADORDINAL in this case.

    DBBINDSTATUS_UNSUPPORTEDCONVERSION

    If the accessor is validated against the metadata when IAccessor::CreateAccessor is called, DBBINDSTATUS_UNSUPPORTEDCONVERSION can be returned for the following reasons:

    • The specified conversion was not supported by the provider. For a list of conversions the accessor must support, see Data Type Conversion in Data Types in OLE DB (OLE DB).

    • The consumer attempted to convert a column to a storage object (ISequentialStream, IStorage, IStream, ILockBytes), and the particular conversion is not supported by the provider.

    These reasons cause a status value of DBSTATUS_E_BADACCESSOR to be returned if the accessor is validated when used.

    DBBINDSTATUS_BADBINDINFO

    dwPart in a binding was not a combination of two or more of the following:

    DBPART_VALUE DBPART_LENGTH DBPART_STATUS

    eParamIO in a binding in a parameter accessor was not one of the following:

    DBPARAMIO_INPUT DBPARAMIO_OUTPUT DBPARAMIO_INPUT | DBPARAMIO_OUTPUT

    A row accessor was optimized, and a column ordinal in a binding was already used in another optimized accessor.

    In a parameter accessor, two or more bindings contained the same ordinal for an input or input/output parameter.

    wType in a binding was DBTYPE_EMPTY or DBTYPE_NULL.

    wType in a binding was one of the following:

    DBTYPE_BYREF | DBTYPE _EMPTY, DBTYPE_BYREF | DBTYPE_NULL, or DBTYPE_BYREF | DBTYPE_RESERVED.

    wType in a binding was used with more than one of the following mutually exclusive type indicators: DBTYPE_BYREF, DBTYPE_ARRAY, or DBTYPE_VECTOR.

    wType in a binding was DBTYPE_IUNKNOWN, pObject in the same binding was a null pointer, and the provider did not assume that the bound interface is IID_IUnknown.

    Provider-owned memory was specified for a nonpointer type in a nonreference row accessor.

    Provider-owned memory was specified for a column, and the provider does not support binding to provider-owned memory for this column.

    Provider-owned memory was specified for a column for which IColumnsInfo::GetColumnInfo returned DBCOLUMNFLAGS_ISLONG, and the provider does not support binding long data to provider owned memory.

    In a nonreference parameter accessor, a binding specified provider-owned memory.

    An output or input/output parameter was specified in a parameter reference accessor.

    dwFlags in a binding was set to DBBINDFLAG_HTML, and wType for the same binding was not a string value.

    The provider is an OLE DB 2.5 or later provider, and dwFlags was set to an unknown or invalid value.

    dwMemOwner was invalid. Providers are not required to return DBBINDSTATUS_BADBINDINFO. If they ignore an invalid value of dwMemOwner, they must default to DBMEMOWNER_CLIENTOWNED.

    If the accessor is validated against the metadata when IAccessor::CreateAccessor is called, DBBINDSTATUS_BADBINDINFO can be returned for the following reasons:

    • A row accessor was not optimized, a column number in a binding specified a column that was already used in an optimized accessor, and the provider did not support a conversion from the type specified in the optimized accessor for the column to the type specified in wType.

    • In a parameter accessor, eParamIO in a binding specified the incorrect I/O type for the parameter. Some providers cannot determine parameter I/O types and never return DBBINDSTATUS_BADBINDINFO in this case.

    • In a reference accessor, the value specified for dwPart, obValue, cbMaxLen, or wType in a binding did not match the format of the corresponding element in the rowset's copy of the row.

    • In a nonreference accessor, a binding specified provider-owned memory, wType was X | DBTYPE_BYREF, and the data type of the corresponding element of the rowset's copy of the row was not X or X | DBTYPE_BYREF.

    • In a nonreference accessor, a binding specified provider-owned memory, wType was DBTYPE_BSTR, and the data type of the corresponding element of the rowset's copy of the row was not DBTYPE_BSTR.

    • The accessor was used for passing key column values in IRowsetIndex::Seek or IRowsetIndex::SetRange, and the order in which the key columns were bound did not match the order in which they were returned in IColumnsInfo::GetColumnInfo.

    • The accessor was used for passing key column values in IRowsetIndex::Seek or IRowsetIndex::SetRange, and a less significant key column was bound without binding all more significant key columns.

    • The accessor was used for passing key column values in IRowsetIndex::Seek or IRowsetIndex::SetRange, and a non-key column was bound before the last bound key column.

    • These reasons cause a status value of DBSTATUS_E_BADACCESSOR to be returned if the accessor is validated when used.

    DBBINDSTATUS_BADSTORAGEFLAGS

    dwFlags, in the DBOBJECT structure pointed to by a binding, specified invalid storage flags.

    If the accessor is validated against the metadata when IAccessor::CreateAccessor is called, DBBINDSTATUS_BADSTORAGEFLAGS can be returned if dwFlags, in the DBOBJECT structure pointed to by a binding, specified a valid storage flag that was not supported by the object.

    This causes a status value of DBSTATUS_E_BADACCESSOR to be returned if the accessor is validated when used.

    DBBINDSTATUS_NOINTERFACE

    If the accessor is validated against the metadata when IAccessor::CreateAccessor is called, DBBINDSTATUS_NOINTERFACE can be returned for the following reasons:

    • The provider did not support the storage interface specified in iid in the DBOBJECT structure pointed to by a binding in the accessor.

    • The COM object in a column or parameter did not support the interface specified in iid in the DBOBJECT structure pointed to by the corresponding binding in the accessor.

    • The provider supports only one open storage object at a time ? that is, DBPROP_MULTIPLESTORAGEOBJECTS is VARIANT_FALSE, the provider does not support setting data with multiple storage objects in a single accessor, and wType in more than one binding was DBTYPE_IUNKNOWN. Providers for whom DBPROP_MULTIPLESTORAGEOBJECTS is VARIANT_FALSE that still support setting data with multiple consumer storage objects specified in a single accessor allow the creation of accessors with more than one binding to DBTYPE_IUNKNOWN and return DBSTATUS_E_CANTCREATE if the accessor is used to open multiple storage objects from the provider (such as in a call to IRowset::GetData).

    These reasons cause a status value of DBSTATUS_E_BADACCESSOR to be returned if the accessor is validated when used.

Return Code

  • S_OK
    The method succeeded. If rgStatus is not a null pointer, each element is set to DBBINDSTATUS_OK.

  • E_FAIL
    A provider-specific error occurred.

  • E_INVALIDARG
    phAccessor was a null pointer.

    cBindings was not zero, and rgBindings was a null pointer.

  • E_UNEXPECTED
    ITransaction::Commit or ITransaction::Abort was called, and the object is in a zombie state. This error can be returned only when the method is called on a rowset.

  • DB_E_BADACCESSORFLAGS
    dwAccessorFlags was invalid.

    The DBACCESSOR_PARAMETERDATA bit was set in dwAccessorFlags, and the provider does not support parameters.

    Neither the DBACCESSOR_PARAMETERDATA bit nor the DBACCESSOR_ROWDATA bit was set in dwAccessorFlags.

    A method that fetches rows (IRowset::GetNextRows, IRowsetLocate::GetRowsAt, IRowsetLocate::GetRowsByBookmark, or IRowsetScroll::GetRowsAtRatio) had already been called, and the DBACCESSOR_OPTIMIZED bit in dwAccessorFlags was set.

    The DBACCESSOR_ PARAMETERDATA bit was set, and IAccessor::CreateAccessor was called on a rowset.

  • DB_E_BYREFACCESSORNOTSUPPORTED
    dwAccessorFlags was DBACCESSOR_PASSBYREF, and the value of the DBPROP_BYREFACCESSORS property is VARIANT_FALSE.

    Consumers should always check to see whether the provider supports the property DBPROP_BYREFACCESSORS and call IAccessor::CreateAccessor with the DBACCESSOR_PASSBYREF flag only if the provider supports this property. For performance reasons, some service providers might be unable to detect whether the underlying data provider supports DBACCESSOR_PASSBYREF on the CreateAccessor call and might return DB_E_BYREFACCESSORNOTSUPPORTED.

  • DB_E_ERRORSOCCURRED
    Accessor validation failed. To determine which bindings failed, the consumer checks the values returned in rgStatus, at least one of which is not DBBINDSTATUS_OK.

  • DB_E_NOTREENTRANT
    The provider called a method from IRowsetNotify in the consumer that had not yet returned, and the provider does not support reentrancy in this method.

  • DB_E_NULLACCESSORNOTSUPPORTED
    cBindings was zero, and either the rowset does not expose IRowsetChange::InsertRow or IAccessor::CreateAccessor was called on a command.

Comments

For general information about accessors, see Accessors in Getting and Setting Data (OLE DB).

IAccessor::CreateAccessor always checks all error conditions that do not require it to validate the accessor against the metadata. As a general rule, this means it checks the error conditions for all of the return codes except those that return DB_E_ERRORSOCCURRED. CreateAccessor may validate the accessor against the metadata for row accessors created on the rowset; it never validates the accessor against the metadata for row or parameter accessors created on the command. When CreateAccessor validates the accessor against the metadata, it validates each binding in the accessor, setting the appropriate DBBINDSTATUS values as it goes. If CreateAccessor fails in any way, it does not create the accessor and sets *phAccessor to a null handle.

If IAccessor::CreateAccessor does not validate the accessor against the metadata, the validation is said to be delayed. CreateAccessor simply creates the accessor and validation is done by the first method that uses the accessor. If the accessor is found to be invalid, it remains in existence and can be used again.

If accessor validation is delayed, the provider determines whether the method validating the accessor validates it against the metadata before or during data transfer. If the method validates the accessor before transferring any data, it can return any of the return codes listed below for this purpose. If the method validates the accessor while transferring the data, it sets the status value of any column or parameter for which the accessor is invalid (within the context of the method) to DBSTATUS_E_BADACCESSOR and returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED. Whether the method continues processing other columns or parameters depends on both the method and the provider.

The return codes listed in the following table are returned by methods that perform delayed accessor validation before transferring any data. The DBBINDSTATUS value to which each corresponds is also listed.

Return code

DBBINDSTATUS value

E_NOINTERFACE

DBBINDSTATUS_NOINTERFACE

DB_E_BADBINDINFO

DBBINDSTATUS_BADBINDINFO

DB_E_BADORDINAL

DBBINDSTATUS_BADORDINAL

DB_E_BADSTORAGEFLAGS

DBBINDSTATUS_BADSTORAGEFLAGS

DB_E_UNSUPPORTEDCONVERSION

DBBINDSTATUS_UNSUPPORTEDCONVERSION

Providers that do not support conversion of BLOB or non-BLOB data to a data structured storage interface should fail the accessor creation method with DB_E_ERRORSOCCURRED and report DBBINDSTATUS_UNSUPPORTEDCONVERSION on the column specifying the incorrect binding.

See Also

Reference

IAccessor::GetBindings

IAccessor::ReleaseAccessor

IConvertType::CanConvert

IRowset::GetData

IRowsetChange::SetData