The IDataValue Interface

 

typedef enum tagDataValueKind
{
  ResultSet        = 0, 
  InputParam       = 1, 
  OutputParam      = 2, 
  InputOutputParam = 3
} DataValueKind;

interface IDataValue: IDispatch
{
  [propget, id(0x00000001), helpstring("Retrieves the kind of data value.")]
   HRESULT _stdcall Kind([out, retval] DataValueKind * Value );
  [propput, id(0x00000001), helpstring("Sets the kind of data value.")]
   HRESULT _stdcall Kind([in] DataValueKind Value );

  [propget, id(0x00000002), helpstring("True if null value.")]
   HRESULT _stdcall IsNull([out, retval] VARIANT_BOOL * Value );
  [propput, id(0x00000002), helpstring("Sets whether the value should be the null one.")]
   HRESULT _stdcall IsNull([in] VARIANT_BOOL Value );

  [propget, id(0x00000003), helpstring("Retrieves data value as string.")]
   HRESULT _stdcall AsString([out, retval] BSTR * Value );
  [propput, id(0x00000003), helpstring("Sets data value as string.")]
   HRESULT _stdcall AsString([in] BSTR Value );

  [propget, id(0x00000004), helpstring("Retrieves data value as integer.")]
   HRESULT _stdcall AsInteger([out, retval] long * Value );
  [propput, id(0x00000004), helpstring("Sets data value as integer.")]
   HRESULT _stdcall AsInteger([in] long Value );

  [propget, id(0x00000005), helpstring("Retrieves data value as double.")]
   HRESULT _stdcall AsDouble([out, retval] double * Value );
  [propput, id(0x00000005), helpstring("Sets data value as double.")]
   HRESULT _stdcall AsDouble([in] double Value );

  [propget, id(0x00000006), helpstring("Retrieves data as boolean.")]
   HRESULT _stdcall AsBool([out, retval] VARIANT_BOOL * Value );
  [propput, id(0x00000006), helpstring("Sets data as boolean.")]
   HRESULT _stdcall AsBool([in] VARIANT_BOOL Value );

  [propget, id(0x00000007), helpstring("Retrieves data as date-time.")]
   HRESULT _stdcall AsDateTime([out, retval] DATE * Value );
  [propput, id(0x00000007), helpstring("Sets data as date-time.")]
   HRESULT _stdcall AsDateTime([in] DATE Value );

  [propget, id(0x00000008), helpstring("Retrieves handler for data value events.")]
   HRESULT _stdcall AsBinary([out, retval] IDataValueEvents ** Callback );
  [propput, id(0x00000008), helpstring("Sets handler for data value events.")]
   HRESULT _stdcall AsBinary([in] IDataValueEvents * Callback );

   [propget, id(0x00000009), helpstring("Retrieves the order of column in result set.")]
   HRESULT _stdcall ColNo([out, retval] long * Value );

  [id(0x0000000A), helpstring("Marks binary data as string.")]
   HRESULT _stdcall BinaryIsString( void );

  [id(0x0000000B), helpstring("Tells to driver the size of binary data to be sent.")]
   HRESULT _stdcall SetBinarySize([in] long Value );

  [id(0x0000000C), helpstring("Reads a block of binary data.")]
   HRESULT _stdcall BlockRead([in] void Buffer, [in] long Size, [in, out] long * Read );
}

The object implementing only the IDataValue interface wraps a value for reading. Any write attempt raises an exception. Only its descendants may modify this behavior and allow writing. However it is allowed to read data in different data type than stored, any conversion is done by driver and therefore you should take care about it as well as a conversion is not possible in all cases. This way also gives an opportunity to take advantage of driver-specific conversions, if any.

The BlockRead method allows two different modes of data reading in dependency of previous call of BinaryIsString. If this method (BinaryIsString) was not called, then BlockRead attempts to read Size of bytes and fills Read with number of read bytes. Else BlockRead attempts to read data as UNICODE string into buffer allocated to Size bytes and fills Read with number of UNICODE characters read into Buffer excluding null terminating character. In this mode the buffer contains null-terminated PWideChar (*wchar) string.

Each value can be read only one time. The IsNull property holds valid information only after a value has been read.