Московский государственный университет имени М.В.Ломоносова
Опубликован: 20.12.2005 | Доступ: свободный | Студентов: 3142 / 371 | Оценка: 4.22 / 3.86 | Длительность: 12:03:00
ISBN: 978-5-9556-0068-0
Лекция 9:

Объектная модель OLE DB

< Лекция 8 || Лекция 9: 123 || Лекция 10 >

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

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