Type Indicators

A type indicator indicates a data type. For more information, see Chapter 10, "Data Types in OLE DB."

typedef WORD DBTYPE;

enum DBTYPEENUM {
 // The following values exactly match VARENUM 
 // in Automation and may be used in VARIANT
 DBTYPE_EMPTY = 0,
 DBTYPE_NULL,
 DBTYPE_I2,
 DBTYPE_I4,
 DBTYPE_R4,
 DBTYPE_R8,
 DBTYPE_CY,
 DBTYPE_DATE,
 DBTYPE_BSTR,
 DBTYPE_IDISPATCH,
 DBTYPE_ERROR,
 DBTYPE_BOOL,
 DBTYPE_VARIANT,
 DBTYPE_IUNKNOWN,
 DBTYPE_DECIMAL,
 DBTYPE_UI1 = 17,
 DBTYPE_ARRAY = 0x2000,
 DBTYPE_BYREF = 0x4000,

 // The following values exactly match VARENUM 
 // in Automation but cannot be used in VARIANT
 DBTYPE_I1 = 16,
 DBTYPE_UI2 = 18,
 DBTYPE_UI4,
 DBTYPE_I8,
 DBTYPE_UI8,
 DBTYPE_GUID = 72,
 DBTYPE_VECTOR = 0x1000,
 DBTYPE_FILETIME = 64,
 DBTYPE_RESERVED = 0x8000,

 // The following values are not in VARENUM in OLE
 DBTYPE_BYTES = 128,
 DBTYPE_STR = 129,
 DBTYPE_WSTR,
 DBTYPE_NUMERIC,
 DBTYPE_UDT,
 DBTYPE_DBDATE,
 DBTYPE_DBTIME,
 DBTYPE_DBTIMESTAMP,
DBTYPE_HCHAPTER = 136,
DBTYPE_PROPVARIANT = 138,
DBTYPE_VARNUMERIC = 139
};

The following table describes each type indicator, including the C data type it corresponds to.

Type indicator Description
DBTYPE_EMPTY No value was specified. This indicator is valid only in a VARIANT structure and exists only to match the VT_EMPTY value in the VARENUM enumerated type in OLE. It does not correspond to any C data type.
DBTYPE_NULL A NULL value. This indicator is valid only in a VARIANT structure and exists only to match the VT_NULL value in the VARENUM enumerated type in OLE. It does not correspond to any C data type.
DBTYPE_
RESERVED
Reserved for future use by OLE. This indicator does not correspond to any C data type.
DBTYPE_I1 A one-byte, signed integer:
signed char
DBTYPE_I2 A two-byte, signed integer:
SHORT
DBTYPE_I4 A four-byte, signed integer:
LONG
DBTYPE_I8 An eight-byte, signed integer:
LARGE_INTEGER
DBTYPE_UI1 A one-byte, unsigned integer:
BYTE
DBTYPE_UI2 A two-byte, unsigned integer:
unsigned short
DBTYPE_UI4 A four-byte, unsigned integer:
unsigned int
DBTYPE_UI8 An eight-byte, unsigned integer:
ULARGE_INTEGER
DBTYPE_R4 A single-precision floating point value:
float
DBTYPE_R8 A double-precision floating point value:
double
DBTYPE_CY A currency value:
LARGE_INTEGER

Currency is a fixed-point number with four digits to the right of the decimal point. It is stored in an eight-byte signed integer, scaled by 10,000.

DBTYPE_
DECIMAL
An exact numeric value with a fixed precision and fixed scale, stored in the same way as in Automation:
typedef struct tagDEC {
 USHORT wReserved;
 union {
  struct {
   BYTE scale;
   BYTE sign;
  };
  USHORT signscale;
 };
 ULONG Hi32;
 union {
  struct {
   ULONG Lo32;
   ULONG Mid32;
  };
  ULONGLONG Lo64;
 };
} DBTYPE_DECIMAL;
The elements of this structure are used as follows:
  • wReserved—Reserved. Should be 0.

  • scale—The scale specifies the number of digits to the right of the decimal point and ranges from 0 to 28.

  • sign—The sign: 0 if positive, 0x80 if negative.

  • Hi32—The high part of the integer (32-bit aligned).

  • Mid32—The middle part of the integer (32-bit aligned).

  • Lo32—The low part of the integer (32-bit aligned).

For example, to specify the number 12.345, the scale is 3, the sign is 0, and the number stored in the 12-byte integer is 12345.

For information about what precision and scale the provider uses when accessing DBTYPE_DECIMAL structures, see "Conversions Involving DBTYPE_NUMERIC or DBTYPE_DECIMAL" later in this appendix.

DBTYPE_
NUMERIC
An exact numeric value with a fixed precision and scale:
typedef struct tagDB_NUMERIC {
 BYTE precision;
 BYTE scale;
 BYTE sign;
 BYTE val[16];
} DBTYPE_NUMERIC;

The elements of this structure are used as follows:

  • precision—The maximum number of digits in base 10.

  • scale—The number of digits to the right of the decimal point.

  • sign—The sign: 1 for positive numbers, 0 for negative numbers.

  • val—A number stored as a 16-byte scaled integer, with the least-significant byte on the left.

For example, to specify the base 10 number 20.003 with a scale of 4, the number is scaled to an integer of 200030 (20.003 shifted by four tens digits), which is 30D5E in hexadecimal. The value stored in the 16-byte integer is 5E 0D 03 00 00 00 00 00 00 00 00 00 00 00 00 00, the precision is the maximum precision, the scale is 4, and the sign is 1.

For information about what precision and scale the provider uses when accessing DBTYPE_NUMERIC structures, see "Conversions Involving DBTYPE_NUMERIC or DBTYPE_DECIMAL" later in this appendix.

DBTYPE_DATE A date stored in the same way as in Automation:
DATE

A DATE is a double, the whole part of which is the number of days since December 30, 1899, and the fractional part of which is the fraction of a day. For example, the number 2.25 represents the datetime January 1, 1900 6:00 AM.

DBTYPE_BOOL A Boolean value stored in the same way as in Automation:
VARIANT_BOOL

0 means false and ~0 (bitwise, the value is not 0; that is, all bits are set to 1) means true.

DBTYPE_BYTES A binary data value. That is, an array of bytes:
BYTE[length]

The length of the array is specified by cbMaxLen in the DBBINDING structure if DBTYPE_BYTES is used by itself. It is specified by the bound length value if DBTYPE_BYTES is combined with DBTYPE_BYREF.

For columns containing binary data, the provider reports the data type as DBTYPE_BYTES and the maximum length as the true maximum length of the binary data (assuming there is one). For small, fixed-length binary data, such as a column in an SQL database of type BINARY(1000), the consumer generally binds the column as DBTYPE_BYTES. For small, variable-length binary data, such as a column in an SQL database of type VARBINARY(1000), the consumer generally binds the column as DBTYPE_BYTES | DBTYPE_BYREF, so no space is wasted and no data is truncated. For long binary data, the consumer generally binds the column as DBTYPE_IUNKNOWN and uses a storage interface such as ISequentialStream to manipulate the data. For more information, see "Accessing BLOB Data" in Chapter 7.

When null-terminated string data is converted to or from DBTYPE_BYTES, the null termination character is not included in the length count or the data transferred.

DBTYPE_BSTR A pointer to a BSTR, as in Automation:
typedef WCHAR * BSTR;

A BSTR is a pointer to a null-terminated character string in which the string length is stored with the string. Because the length is stored with the string, BSTR variables can contain embedded null characters. To determine the length of the BSTR in characters, call SysStringLen. To determine the length of the BSTR in bytes, call SysStringByteLen. In both cases, the length does not include the null termination character.

In Win32 (the environment for OLE DB) a BSTR contains Unicode.

Consumers are responsible for freeing the memory used by BSTRs. Failure to free such memory is a common cause of memory leaks. For example, if a consumer calls IRowset::GetData to retrieve a BSTR, the provider allocates memory for the BSTR and returns a pointer to it in the memory pointed to by pData. A memory leak occurs when the consumer calls GetData again with the same value of pData without first freeing the memory for the BSTR. In this case, the provider allocates new memory for the BSTR and overwrites the pointer to the old BSTR with the pointer to the new BSTR. The old BSTR is still allocated, but the pointer to it is lost. For more information, see "Memory Management" in Chapter 6 and the OLE Programmer's Reference, Volume 2.

DBTYPE_STR A null-terminated ANSI character string:
char[length]

If DBTYPE_STR is used by itself, the number of bytes allocated for the string, including the null termination character, is specified by cbMaxLen in the DBBINDING structure. If DBTYPE_STR is combined with DBTYPE_BYREF, the number of bytes allocated for the string, including the null termination character, is at least the length of the string plus one. In either case, the actual length of the string is determined from the bound length value.

If a locale is applicable, it is indicated first by the column metadata, or if none is available then by table metadata, or if none is available then by the database locale.

DBTYPE_WSTR A null-terminated Unicode character string:
wchar_t[length]

If DBTYPE_WSTR is used by itself, the number of bytes allocated for the string, including the null termination character, is specified by cbMaxLen in the DBBINDING structure. If DBTYPE_WSTR is combined with DBTYPE_BYREF, the number of bytes allocated for the string, including the null termination character, is at least the length of the string plus two. In either case, the actual length of the string is determined from the bound length value. Note that the maximum length of the string is the number of allocated bytes divided by sizeof(wchar_t) and truncated to the nearest integer.

DBTYPE_
VARIANT
An Automation VARIANT:
VARIANT

The DBTYPE values that do not match Automation VARENUM values represent data types that cannot be stored in a VARIANT. If the VARIANT structure contains a pointer to the data, then the buffer for that data is allocated separately.

DBTYPE_
IDISPATCH
A pointer to an IDispatch interface on an OLE object:
IDispatch *

For more information, see the OLE Programmer's Reference, Volume 2.

DBTYPE_
IUNKNOWN
A pointer to an IUnknown interface on an OLE object:
IUnknown *

For columns containing OLE objects, the provider reports the data type as DBTYPE_IUNKNOWN. The consumer specifies the interface to use through the pObject element of the DBBINDING structure. For more information, see "IPersist* Objects" in Chapter 7.

DBTYPE_GUID A globally unique identifier (GUID):
GUID

GUIDs are also known as universally unique identifiers (UUIDs) and are used as class identifiers (CLSIDs) and interface identifiers (IIDs). For more information, see the OLE documentation.

DBTYPE_ERROR A 32-bit error code:
SCODE

For more information, see the OLE documentation.

DBTYPE_BYREF A pointer to data:
void *

DBTYPE_BYREF must be combined with another type indicator. This indicates that the data in the consumer's buffer is a pointer to the other type. For example, DBTYPE_STR | DBTYPE_BYREF means that the data is a pointer to an ANSI string and DBTYPE_I2 | DBTYPE_BYREF means that the data is a pointer to a two-byte integer. DBTYPE_BYREF is commonly used to return pointers to variable-length data. It is used with provider-owned bindings to return pointers to the data in the rowset's copy of a row.

When DBTYPE_BYREF is used, the data in the consumer's buffer can be a null pointer only when the corresponding status value is DBSTATUS_S_ISNULL. When setting a column value, if the data in the consumer's buffer is a null pointer and the status is not DBSTATUS_S_ISNULL, the provider returns a conversion error.

DBTYPE_BYREF is mutually exclusive with the DBTYPE_ARRAY and DBTYPE_VECTOR modifiers and cannot be combined with the following values:

DBTYPE_EMPTY
DBTYPE_NULL
DBTYPE_RESERVED

For information about how DBTYPE_BYREF values are allocated, see "Memory Management" in Chapter 6.

DBTYPE_ARRAY A pointer to a SAFEARRAY:
SAFEARRAY *

DBTYPE_ARRAY must be combined with another type indicator. This indicates that the data in the consumer's buffer is a pointer to a SAFEARRAY of the other type. For example, DBTYPE_I2 | DBTYPE_ARRAY means that the data is a pointer to a SAFEARRAY of two-byte integers.

When DBTYPE_ARRAY is used, the data in the consumer's buffer can be a null pointer only when the corresponding status value is DBSTATUS_S_ISNULL. When setting a column value, if the data in the consumer's buffer is a null pointer and the status is not DBSTATUS_S_ISNULL, the provider returns a conversion error.

DBTYPE_ARRAY is mutually exclusive with the DBTYPE_BYREF and DBTYPE_VECTOR modifiers and cannot be combined with indicators for variable-length data types because there is no way to determine the length of each element of the array. DBTYPE_ARRAY can be combined with DBTYPE_BSTR because DBTYPE_BSTR is a fixed-length data type: A BSTR is a pointer to a separately allocated string that contains its own length.

For information about how SAFEARRAYs are allocated, see "Memory Management" in Chapter 6. For more information about SAFEARRAYs, see the OLE documentation.

DBTYPE_
VECTOR
A DBVECTOR structure:
typedef struct tagDBVECTOR {
 void * ptr;
 ULONG  size;
} DBVECTOR;

DBTYPE_VECTOR must be combined with another type indicator. This indicates that the data in the consumer's buffer is a DBVECTOR structure, which contains a pointer to an array of the other type. For example, DBTYPE_I2 | DBTYPE_VECTOR means that the data is a DBVECTOR structure that contains a pointer to an array of two-byte integers.

When DBTYPE_VECTOR is used, the pointer in the DBVECTOR structure can be a null pointer only when the corresponding status value is DBSTATUS_S_ISNULL. When setting a column value, if the pointer is a null pointer and the status is not DBSTATUS_S_ISNULL, the provider returns a conversion error.

DBTYPE_VECTOR is mutually exclusive with the DBTYPE_BYREF and DBTYPE_ARRAY modifiers and cannot be combined with indicators for variable-length data types because there is no way to determine the length of each element of the array.

For information about how the memory pointed to by DBVECTOR structures is allocated, see "Memory Management" in Chapter 6.

DBTYPE_UDT A user-defined data type of variable length. In future versions, OLE DB may define the use of type libraries to support user-defined data types. This indicator does not correspond to any C data type.
DBTYPE_
DBDATE
A date structure:
typedef struct tagDBDATE {
 SHORT  year;
 USHORT month;
 USHORT day;
} DBDATE;

The elements of this structure are used as follows:

  • year—The year: 0-9999 measured from 0 A.D.

  • month—The month: 1 – 12.

  • day—1 – n where n is the number of days in the month.
DBTYPE_
DBTIME
A time structure:
typedef struct tagDBTIME {
 USHORT hour;
 USHORT minute;
 USHORT second;
} DBTIME;

The elements of this structure are used as follows:

  • hour—The hour: 0–23.

  • minute—The minute: 0–59.

  • second—The second: 0–61.

The range of seconds allows as many as two leap seconds to maintain synchronization with sidereal time.

DBTYPE_
DBTIMESTAMP
A timestamp structure:
typedef struct tagDBTIMESTAMP {
 SHORT  year;
 USHORT month;
 USHORT day;
 USHORT hour;
 USHORT minute;
 USHORT second;
 ULONG  fraction;
} DBTIMESTAMP;
The elements of this structure are used as follows:
  • year—The year: 0-9999 measured from 0 A.D.

  • month—The month: 1–12.

  • day—1 – n where n is the number of days in the month.

  • hour—The hour: 0–23.

  • minute—The minute: 0–59.

  • second—The second: 0–61.

  • fraction—Billionths of a second: 0–999,999,999.

The range of seconds allows as many as two leap seconds to maintain synchronization with sidereal time.

DBTYPE_FILETIME A 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601. This type is equivalent to the FILETIME type used in the time-conversion functions between DOS and Win32.
typedef struct tagFILETIME {
 DWORD  dwLowDateTime;
 DWORD  dwHighDateTime;
} FILETIME;

The elements of the structure are used as follows:

  • dwLowDateTime—The lower 32 bits of the Win32 date/time value.

  • dwHighDateTime—The upper 32 bits of the Win32 date/time value.
DBTYPE_PROPVARIANT An Automation PROPVARIANT:
PROPVARIANT

If the VARIANT structure contains a pointer to the data, then the buffer for the data is allocated separately.

DBTYPE_PROPVARIANT should support the same set of conversions as DBTYPE_VARIANT (including conversions to/from DBTYPE_VARIANT).

DBTYPE_HCHAPTER A 4-byte chapter value that can be used to identify rows in a child rowset.
DBTYPE_VARNUMERIC A variable-length, exact numeric value with a signed scale value:
typedef struct  tagDB_VARNUMERIC {
 BYTE    precision;
 SBYTE    scale;
 BYTE    sign;
 BYTE    val[ 1 ];
} DB_VARNUMERIC;