DBBINDING Structures

A binding associates a single column or parameter to the consumer's buffer, and contains information about the buffer.

The DBBINDING structure describes a single binding.

typedef struct tagDBBINDING {
   ULONG   iOrdinal;
   ULONG   obValue;
   ULONG   obLength;
   ULONG   obStatus;
   ITypeInfo * pTypeInfo;
   DBOBJECT * pObject;
   DBBINDEXT * pBindExt;
   DBPART   dwPart;
   DBMEMOWNER   dwMemOwner;
   DBPARAMIO eParamIO;
   ULONG   cbMaxLen;
   DWORD   dwFlags;
   DBTYPE   wType;
   BYTE   bPrecision;
   BYTE   bScale;
} DBBINDING;

The elements of this structure are used as follows.

Element Description
iOrdinal The ordinal of the column or parameter to which the binding applies.

Column ordinals are fixed for the lifetime of the rowset. The self bookmark column is column 0 and other columns start with column 1. To retrieve column ordinals, consumers call IColumnsInfo::GetColumnInfo, IColumnsRowset::GetColumnsRowset, or IColumnsInfo::MapColumnIDs. If the rowset is generated from a command, the column ordinals returned by GetColumnInfo or GetColumnsRowset on the rowset must match the column ordinals returned by the same methods on the command.

Parameter ordinals are determined from the text command. The first parameter is parameter one. To retrieve parameter ordinals, consumers call ICommandWithParameters::GetParameterInfo.

obValue The offset in bytes in the consumer's buffer to the value part. obValue is ignored unless the DBPART_VALUE bit is set in dwPart. For more information about the value part, see "Value" earlier in this chapter.

This offset must be properly aligned for the processor architecture of the consumer's machine. If data is improperly aligned, consumers can expect alignment faults to occur when getting and setting data values. Consumers should use addresses that are multiples of the size of the data type. For example, if wType is DBTYPE_I4, the value part should be DWORD aligned.

obLength The offset in bytes in the consumer's buffer to the length part. obLength is ignored unless the DBPART_LENGTH bit is set in dwPart. For more information about the length part, see "Length" earlier in this chapter.

The length itself is a ULONG. This offset must be properly aligned for the processor architecture of the consumer's machine; that is, it should be a multiple of sizeof(ULONG). If it is improperly aligned, consumers can expect alignment faults when getting and setting length values.

obStatus The offset in bytes in the consumer's buffer to the status part. obStatus is ignored unless the DBPART_STATUS bit is set in dwPart. For more information about the status part, see "Status" earlier in this chapter.

The status part itself is a DBSTATUS value, which is a DWORD. This offset must be properly aligned for the processor architecture of the consumer's machine; that is, it should be a multiple of sizeof(DWORD). If it is improperly aligned, consumers can expect alignment faults when getting and setting status values.

pTypeInfo Reserved for future use. Consumers should set pTypeInfo to a null pointer.
pObject Pointer to a DBOBJECT structure. This structure describes how OLE objects in columns or parameters should be accessed.
typedef struct tagDBOBJECT {
 DWORD dwFlags;
 IID iid;
} DBOBJECT;

The elements of this structure are used as follows:

  • dwFlags—The combined storage mode flags to use when creating an instance of the OLE object.

  • iid—The interface to be exposed on the OLE object.

The storage mode flags are defined by the Structured Storage model in OLE. These are:

  • STGM_READ = OF_READ

  • STGM_WRITE = OF_WRITE

  • STGM_READWRITE = OF_READWRITE

  • STGM_SHARE_DENY_NONE = OF_SHARE_DENY_NONE

  • STGM_SHARE_DENY_READ = OF_SHARE_DENY_READ

  • STGM_SHARE_DENY_WRITE = OF_SHARE_DENY_WRITE

  • STGM_SHARE_EXCLUSIVE = OF_SHARE_EXCLUSIVE

  • STGM_DIRECT

  • STGM_TRANSACTED

  • STGM_CREATE = OF_CREATE

  • STGM_CONVERT

  • STGM_FAILIFTHERE

  • STGM_PRIORITY

  • STGM_DELETEONRELEASE

pObject is ignored unless the DBPART_VALUE bit is set in dwPart and wType is DBTYPE_IUNKNOWN. If neither of these conditions is true, it should be set to a null pointer.

Note  Consumers should not set wType to DBTYPE_IUNKNOWN and the DBPART_VALUE bit in dwPart without specifying a non-null value for pObject. However, providers can assume in this case that the interface to be bound is IID_IUnknown.

pBindExt The DBBINDEXT structure can be used for future extensions to the binding structure. pBindExt is reserved for future use and consumers should set it to a null pointer.
typedef struct tagDBBINDEXT{
 BYTE * pExtension;
 ULONG  ulExtension;
} DBBINDEXT;
dwPart Specifies which buffer parts are to be bound to the column or parameter. It is one or more DBPARTENUM values combined; these values have the following meaning:
  • DBPART_VALUE—The binding includes a value part.

  • DBPART_LENGTH—The binding includes a length part.

  • DBPART_STATUS—The binding includes a status part.
dwMemOwner For bindings in row accessors, specifies who owns memory allocated by the provider for a column and for which a pointer is returned to the consumer. For example, when wType is DBTYPE_BYREF | DBTYPE_STR, the provider allocates memory for the string and returns a pointer to the string to the consumer; dwMemOwner specifies whether the consumer or provider owns this memory. The provider ignores this when setting rowset data.

The following is a description of each of these values:

  • DBMEMOWNER_CLIENTOWNED—The consumer owns the memory and is responsible for freeing it.

  • DBMEMOWNER_PROVIDEROWNED—The provider owns the memory and is responsible for freeing it. When getting data, the provider returns a pointer into its copy of the row. When using provider-owned memory, the consumer's type must exactly match the provider's type, except that if wType is X | DBTYPE_BYREF, the provider's type can be X or X | DBTYPE_BYREF. If a column is NULL, the provider returns a null pointer for the data value.

    The consumer must not write to or free the memory to which the pointer points. The lifetime of the pointer is provider specific. However, pointers to row data are guaranteed to be valid until IRowset::ReleaseRows is called for the row and its reference count falls to zero; a method is called for the row that might invalidate the pointer; or the rowset is released, whichever occurs first. The methods that might invalidate the pointer depend on the method that returned it. These are as follows:

    Ptr returned by:Might be invalidated by:

    GetDataDeleteRows (immediate update mode)
    RefreshVisibleData
    SetData
    Update
    Undo

    GetLastVisibleDataGetLastVisibleData

    GetOriginalDataRefreshVisibleData
    SetData
    Update

    Although the consumer must not write to provider-owned memory, it can pass pointers to provider-owned memory when setting data. For example, suppose that the consumer wants to copy data efficiently from row A to row B. The consumer creates an accessor to the columns in row A in which wType is X | DBTYPE_BYREF and sets dwMemOwner to DBMEMOWNER_PROVIDEROWNED. When the consumer calls IRowset::GetData, the provider returns pointers to its copy of row A. The consumer then calls IRowsetChange::SetData for row B with the same accessor and a pointer to the memory passed to GetData. The provider dereferences the pointers and copies the data from the rowset's copy of row A to the rowset's copy of row B.

For bindings in row accessors, consumer-owned memory must be used unless wType is DBTYPE_BSTR, X | DBTYPE_BYREF, X | DBTYPE_ARRAY, or X | DBTYPE_VECTOR, in which case either consumer- or provider-owned memory can be used. However, provider-owned memory cannot be used if IColumnsInfo::GetColumnInfo returns the DBCOLUMNFLAGS_ISLONG for the column. Consumers can mix bindings for provider- and consumer-owned memory in the same accessor.

For bindings in parameter accessors, consumer-owned memory must always be used.

dwMemOwner is ignored in reference accessors.

All providers must support binding to client-owned memory. Providers support provider-owned memory only if they can efficiently return a pointer to a cached value. Providers are not required to support binding deferred columns to provider-owned memory.

eParamIO For parameter accessors, eParamIO specifies whether the parameter with which the binding is associated is an input, input/output, or output parameter. Providers support only those parameter I/O types that are supported by their underlying data source. eParamIO is one or more DBPARAMIOENUM values combined. These values have the following meaning:
  • DBPARAMIO_NOTPARAM—The accessor is not used for parameters. In most cases eParamIO is set to this value in row accessors to remind the programmer that it is ignored.

  • DBPARAMIO_INPUT—The parameter is an input parameter.

  • DBPARAMIO_OUTPUT—The parameter is an output parameter.

For row accessors, eParamIO is ignored.

cbMaxLen The length in bytes of the consumer's data structure allocated for the data value. That is, it is the number of bytes allocated at offset obValue for the data value. cbMaxLen is ignored unless the DBPART_VALUE bit is set in dwPart and the data value stored at that location is of variable length. For information about variable-length data types, see "Fixed- and Variable-Length Data Types" in Chapter 10.

cbMaxLen is used as follows:

  • Variable-length data types—The provider checks the length in bytes of variable-length data types against cbMaxLen. If the length is greater than cbMaxLen, the provider truncates the data to cbMaxLen bytes.

    When getting data, this is a warning and the provider sets the status to DBSTATUS_S_TRUNCATED and sets the length to the actual number of bytes of data available after conversion and before truncation. Thus, the consumer can determine the actual number of bytes of data available.

    When setting data, this is an error and the provider sets the status to DBSTATUS_E_CANTCONVERTVALUE; in most cases, this is a consumer programming error.

  • Fixed-length data types—The provider ignores cbMaxLen for fixed-length data types and assumes that the number of bytes available in the consumer's buffer for the data is the size of the data type.

  • DBTYPE_BYREF, DBTYPE_VECTOR, DBTYPE_ARRAY—The provider ignores cbMaxLen and assumes that the number of bytes available in the consumer's buffer is the size dictated by DBTYPE_BYREF, DBTYPE_VECTOR, or DBTYPE_ARRAY. For DBTYPE_BYREF and DBTYPE_ARRAY, this is sizeof(void *). For DBTYPE_VECTOR, this is sizeof(DBVECTOR).

    It is important to note that if DBTYPE_BYREF is combined with the type indicator for a variable-length data type, the data is not truncated to cbMaxLen bytes. This is because the data is in separately allocated memory, not the consumer's buffer, and cbMaxLen does not apply to this memory. The provider allocates this memory based on the length of the data, as bound at the offset obLength, so consumers can guarantee that variable-length data is not truncated if it is retrieved in this manner.

dwFlags dwFlags specifies information about how data is returned. The following flag is recognized:
DBBINDFLAG_HTML

The provider should format the returned data in HTML. If the provider does not support HTML formatting, the bit is ignored and regular text is returned. The provider will not be able to use an accessor created with the HTML flag to set data.

wType The indicator of the data type of the value part of the buffer. For more information about type indicators, see "Type Indicators" in Appendix A.

This type forms an implied conversion between the buffer type and the type of the column or parameter. For information about conversions providers are required to support, see "Data Type Conversion" in Chapter 10.

bPrecision The maximum precision to use when getting data and wType is DBTYPE_NUMERIC. This is ignored when setting data, wType is not DBTYPE_NUMERIC, or the DBPART_VALUE bit is not set in dwPart. For more information, see "Conversions Involving DBTYPE_NUMERIC or DBTYPE_DECIMAL" in Appendix A.
bScale The scale to use when getting data and wType is DBTYPE_NUMERIC or DBTYPE_DECIMAL. This is ignored when setting data, wType is not DBTYPE_NUMERIC or DBTYPE_DECIMAL, or the DBPART_VALUE bit is not set in dwPart. For more information, see "Conversions Involving DBTYPE_NUMERIC or DBTYPE_DECIMAL" in Appendix A.

Note  The offsets specified in obValue, obLength, and obStatus must not point to overlapping areas of memory. The provider is not required to check if this condition occurs, and consumers must be careful to avoid this condition when constructing bindings.