Объектная модель OLE DB
Создание результирующего набора
При реализации доступа к БД посредством OLE DB провайдера сначала следует создать объект данных и установить соединение с базой данных. Далее необходимо создать объект "сеанс". И только потом можно создавать результирующий набор.
Механизм создания объекта "сеанс" приведен на следующей схеме.
Результирующий набор может быть создан одним из следующих способов:
- Для объекта "сеанс" вызывается метод IOpenRowset::OpenRowset, выполняющий непосредственное создание результирующего набора (интерфейс IOpenRowset должен поддерживаться любым провайдером);
- Для объекта "сеанс" вызывается метод IDBCreateCommand::CreateCommand, создающий объект Command. Далее для объекта "команда" вызывается метод ICommand::Execute. (при использовании интерфейса IMultipleResults можно работать с несколькими результирующими наборами);
- Вызывается один из следующих методов IColumnsRowset::GetColumnsRowset, IDBSchemaRowset::GetRowset, IViewRowset::OpenViewRowset или ISourcesRowset::GetSourcesRowset.
Чтобы результирующий набор, хранимый на сервере, можно было использовать, необходимо выполнить связывание и извлечение данных. Для этого следует определить структуры типа DBBINDING, описывающие столбцы, и создать аксессор. Далее для получения строк результирующего набора можно использовать один из следующих методов:
- IRowset::GetNextRows ;
- IRowsetLocate::GetRowsByBookMarks ;
- IRowsetLocate::GetRowAt ;
- IRowsetScroll:: GetRowAtRatio.
В заключение для записи данных в структуру, определенную аксессором, вызывается метод IRowset::GetData.
После получения и обработки строк их следует освободить, вызвав метод IRowset::ReleaseRows.
После просмотра всего результирующего набора следует также освободить аксессор, вызвав метод IRowset::ReleaseAccessor, и освободить сам результирующий набор, вызвав метод IRowset::Release.
Интерфейс IAccessor определяет следующие методы:
- AddRefAccessor - увеличивает число ссылок на данный аксессор;
- CreateAccessor - создает аксессор из набора связываний;
- GetBindings - возвращает связывания, установленные данным аксессором;
- ReleaseAccessor - освобождает аксессор.
Для создания аксессора следует запросить интерфейс IAccessor и выполнить следующий код:
HRESULT hr=pIAccessor-> CreateAccessor();
Метод CreateAccessor имеет следующее формальное описание:
HRESULT CreateAccessor (
DBACCESSORFLAGS dwAccessorFlags, // Свойства
// аксессора и как он используется
DBCOUNTITEM cBindings, // Число связей
// в аксессоре
const DBBINDING rgBindings[], // Описание
// столбца или параметра
DBLENGTH cbRowSize, // Число байтов,
// используемых для одного набора параметров
HACCESSOR *phAccessor, // Указатель
//на созданный аксессор
DBBINDSTATUS rgStatus[]); // Массив значений,
// определяющий статус
// каждого связыванияКаждый столбец формируемого результирующего набора или параметр описывается структурой DBBINDING, которая имеет следующее формальное описание:
typedef struct tagDBBINDING {
DBORDINAL iOrdinal; // Порядковый номер
// столбца или параметра (начиная с 1)
DBBYTEOFFSET obValue; // Сдвиг в байтах для
// значения столбца или параметра в буфере
// (указатель на буфер задается при
// создании аксессора)
DBBYTEOFFSET obLength;
DBBYTEOFFSET obStatus;
ITypeInfo *pTypeInfo;
DBOBJECT *pObject;
DBBINDEXT *pBindExt;
DBPART dwPart;
DBMEMOWNER dwMemOwner;
DBPARAMIO eParamIO;
DBLENGTH cbMaxLen;
DWORD dwFlags;
DBTYPE wType;
BYTE bPrecision;
BYTE bScale;
} DBBINDING;Поле wType определяет тип столбца или параметра, который описывается следующим образом:
typedef WORD DBTYPE;
enum DBTYPEENUM {
// Следующие значения точно соответствуют VARENUM
// при автоматизации и не могут быть использованы
// как VARIANT.
DBTYPE_EMPTY = 0, // Значение отсутствует,
// соответствующего типа С нет
DBTYPE_NULL = 1, // Значение равно NULL,
// соответствующего типа С нет
DBTYPE_I2 = 2, // Двухбайтовое целое со знаком,
// соответствует С типу short
DBTYPE_I4 = 3, // Четырехбайтовое целое со знаком,
// соответствует С типу long
DBTYPE_R4 = 4,
DBTYPE_R8 = 5, // Вещественное двойной точности,
// соответствует С типу Double
DBTYPE_CY = 6, // Тип для значения Cyrrency
DBTYPE_DATE = 7, // Тип для значения даты
// (дата хранится в виде вещественного числа:
// целочисленная часть определяет дату,
// а дробная - время)
DBTYPE_BSTR = 8, // Указатель на строку BSTR
DBTYPE_IDISPATCH = 9, // Указатель на интерфейс
// IDispatch
DBTYPE_ERROR = 10, // 32-битовый код ошибки
DBTYPE_BOOL = 11, // Для логического значения
DBTYPE_VARIANT = 12, // Для значения VARIANT
DBTYPE_IUNKNOWN = 13, // Указатель на интерфейс
// IUnknown
DBTYPE_DECIMAL = 14,
DBTYPE_UI1 = 17, // Однобайтовое беззнаковое целое,
// соответствует С типу byte
DBTYPE_ARRAY = 0x2000,
DBTYPE_BYREF = 0x4000,
DBTYPE_I1 = 16,
DBTYPE_UI2 = 18,
DBTYPE_UI4 = 19,
// Следующие значения точно соответствуют VARENUM
// при автоматизации, но не могут быть использованы
// как VARIANT.
DBTYPE_I8 = 20,
DBTYPE_UI8 = 21,
DBTYPE_GUID = 72, // Для уникального
идентификатора GUID
DBTYPE_VECTOR = 0x1000,
DBTYPE_FILETIME = 64,
DBTYPE_RESERVED = 0x8000,
// Следующие значения недопустимы в VARENUM для OLE.
DBTYPE_BYTES = 128,
DBTYPE_STR = 129,
DBTYPE_WSTR = 130,
DBTYPE_NUMERIC = 131,
DBTYPE_UDT = 132,
DBTYPE_DBDATE = 133,// Для даты, определяемой
// как структура
// Typedef struct tagDBDATE {
// SHORT year;
// USHORT month;
// USHORT day;
// } DBDATE;
DBTYPE_DBTIME = 134,
DBTYPE_DBTIMESTAMP = 135 // Для даты и времени,
// определяемых как структура
// Typedef struct tagDBTIMESTAMP {
// SHORT year;
// USHORT month;
// USHORT day;
// USHORT hour;
// USHORT minute;
// USHORT second;
// ULONG fraction;
} DBTIMESTAMP;
DBTYPE_HCHAPTER = 136
DBTYPE_PROPVARIANT = 138,
DBTYPE_VARNUMERIC = 139
};
