Основы проектирования приложений баз данных

       

Создание результирующего набора


При реализации доступа к БД посредством 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 };


Содержание раздела