MDAC 2.5 SDK - OLE DB Providers
OLE DB Provider for ODBC


 

Error Support

A feature called diagnostic fields is introduced in ODBC 3.0. Following is information about how to use the ODBC Provider to access error information from those diagnostic fields.

The ODBC Provider includes a new interface, ISQLRequestDiagFields, to facilitate the retrieval of diagnostic information. When an OLE DB consumer needs to retrieve certain diagnostic fields after a method call, it calls ISQLRequestDiagFields::RequestDiagFields on the OLE DB object before calling the method to notify the ODBC Provider that it can request the diagnostic information. The ODBC Provider then caches those diagnostic fields. If the consumer does not call ISQLRequestDiagFields::RequestDiagFields, the ODBC Provider does not cache any extra diagnostic data except the information needed in the existing OLE DB error model.

ISQLRequestDiagFields (defined in the header file Msdasql.h) is an optional interface of any OLE DB object implemented in the ODBC Provider. Any object that supports diagnostic fields exposes this interface. It has one method, RequestDiagFields. Here is its calling convention:

enum KAGREQDIAGFLAGSENUM
{ KAGREQDIAGFLAGS_HEADER = 0x1,
KAGREQDIAGFLAGS_RECORD = 0x2
   };

typedef struct tagKAGREQDIAG
{
ULONG ulDiagFlags;
VARTYPE vt;
SHORT sDiagField;
} KAGREQDIAG;
ISQLRequestDiagFields : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE RequestDiagFields(
ULONG cDiagFields,
KAGREQDIAG rgDiagFields[      ]) = 0;

};

The parameter cDiagFields is the number of diagnostic fields to be requested; rgDiagFields is an array of KAGREQDIAG. KAGREQDIAG describes the diagnostic identifier, type, and flags of a diagnostic field. KAGREQDIAGFLAGS_HEADER or KAGREQDIAGFLAGS_RECORD can be the value of ulDiagFlags. These two parameters tell whether the diagnostic field is a header field or record field. The type, vt, is a data type of the diagnostic information, and it must be VT_I2, VT_UI2, VT_I4, VT_UI4, VT_BSTR, or VT_UI1 | VT_ARRAY, depending on the type of diagnostic field. For example, if the diagnostic field type is SQLINTEGER in ODBC, it must be VT_I4 here; if the type is string in ODBC, it must be VT_BSTR here. Otherwise, the result is undefined. This function clears the previous request of the diagnostic fields in the object. Setting cDiagFields to 0 means that no diagnostic fields should be cached by the provider on this object.

Although the ODBC Provider will support diagnostic fields for both 2.x and 3.x ODBC drivers, the functionality is limited for ODBC 2.x drivers because no 2.x driver supports diagnostics.

The diagnostic information is retrieved through IGetDiagField::GetDiagField. IGetDiagField is a new optional interface of TCustomErrorObject.

Definition of the tagKAGGETDIAG Structure

typedef struct tagKAGGETDIAG
{
ULONG ulSize;
VARIANTARG vDiagInfo;
SHORT sDiagField;
} KAGGETDIAG;
ISQLGetDiagField : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE GetDiagField(
KAGGETDIAG *pDiagInfo) = 0;
};

pDiagInfo is an input/output argument.

On input, pDiagInfo->ulSize should be set to the size of KAGGETDIAG; pDiagInfo->vDiagInfo should be initialized with VariantInit; and pDiagInfo->sDiagField is the diagnostic field identifier.

At return, pDiagInfo->vDiagInfo has the data for the diagnostic information. vDiagInfo.vt can be any of the values listed for argument vt in ISQLRequestDiagFields::RequestDiagFields.

If the diagnostic data is a string or binary, the data is stored as BSTR or VT_UI1 | VT_ARRAY. When the diagnostic information is no longer needed, pDiagInfo->vDiagInfo should be freed with VariantClear by the consumer.