Сообщений 1    Оценка 85        Оценить  
Система Orphus

IADORecordBinding - расширение ADO для Visual С++

Автор: Марк Балонкин
Опубликовано: 06.10.2001
Исправлено: 13.03.2005
Версия текста: 1.0

Исходный текст примера - 10 KB

Чтение/запись значений полей ADO Recordset. Использование IADORecordBinding

Значения полей ADO Recordset-а можно читать и записывать через объекты Field. Однако, в этом случае, приходится работать с преобразованиями из/в тип VARIANT. Альтернативой вызова методов GetFields()->GetItem(long(0)) для доступа к объектам ADO Field, GetValue() и PutValue() для чтения и записи, может служить интерфейс IADORecordBinding, предназначенный для связывания полей ADO Recordset-а с переменными C++.

IADORecordBinding – расширение ADO для Visual C++. Подробное описание можно найти в MSDN (по «указателю» IADORecordBinding). Краткое описание IADORecordBinding с примером использования будет приведено ниже.

Создаете класс, который будет включать переменные, соответствующие полям Recordset-а. Класс должен быть наследован от CADORecordBinding. Добавьте #include "icrsint.h" в ваш .h файл. Для каждого поля добавьте в класс по 2 переменные, первая типа соответствующего полю, вторая типа ULONG (переменная статуса). По переменной статуса можно узнать корректность значения первой переменной, ее использование не обязательно. Соответствие переменных полям указывается с помощью набора макросов:

Макрос
ADO_FIXED_LENGTH_ENTRY(<номер поля>, <тип данных>, <переменная>, <переменная статуса>, <возможность изменения>)
ADO_NUMERIC_ENTRY(<номер поля>, <тип данных>, <переменная>, <количество знаков>,<количество десятичных знаков>,<переменная статуса>, <возможность изменения>)
ADO_VARIABLE_LENGTH_ENTRY(<номер поля>, <тип данных>, <переменная>, <максимальный размер буфера>, <переменная статуса>, <реальная длина>, <возможность изменения>)
ADO_VARIABLE_LENGTH_ENTRY2(<номер поля>, <тип данных>, <переменная>, <максимальный размер буфера>, <переменная статуса>, <возможность изменения>)
или, если не без переменной статуса:
ADO_FIXED_LENGTH_ENTRY2(<номер поля>, <тип данных>, <переменная>, <возможность изменения>)
ADO_NUMERIC_ENTRY2(<номер поля>, <тип данных>, <переменная>, <количество знаков>,<количество десятичных знаков>, <возможность изменения>)
ADO_VARIABLE_LENGTH_ENTRY3(<номер поля>, <тип данных>, <переменная>, <максимальный размер буфера>, <реальная длина>, <возможность изменения>)
ADO_VARIABLE_LENGTH_ENTRY4(<номер поля>, <тип данных>, <переменная>, <максимальный размер буфера>, <возможность изменения>)
номер поля номер поля в Recordset-е (Не zero based, начиная с 1)
тип данных ADO DataTypeEnum
переменная имя переменной
переменная статуса имя переменной статуса
возможность изменения TRUE – переменная, возможно, будет изменяться; FALSE – переменная не будет изменяться

Таким образом, после определения переменных в классе, необходимо добавить в h-файл вашего класса набор описанных макросов, заключив их в пару:

BEGIN_ADO_BINDING(<имя класса>)
    // Макросы связи данных
END_ADO_BINDING()

Для подключения полученного класса к Recordset-у нужно получить интерфейс IADORecordBinding и вызвать его метод BindToRecordset с созданным классом в качестве параметра. Указатель на интерфейс можно получить через QueryInterface у Recordset-а и объявив интеллектуальный указатель с параметром Recordset.

Пример работы с IADORecordBinding

Применим IADORecordBinding для просмотра содержимого таблицы, точнее трех ее колонок типа int, varchar и float (MS SQL Server). В примере таблица создана на сервере NONAME (MS SQL Server 7.0) в базе данных UseADOBindinding. SQL script для создания:

CREATE TABLE [dbo].[TABLE1] (
        [ID] [int] IDENTITY (1, 1) NOT NULL ,
        [Title] [varchar] (50) NULL ,
        [Data1] [float] NULL 
) ON [PRIMARY]

h-файл класса с переменными соответствующими полям Recordset-а будет выглядеть следующим образом:

// MyRecordset.h: interface for the CMyRecordset class.
//
//////////////////////////////////////////////////////////////////////
#if 
!defined(AFX_MYRECORDSET_H__75DD2CD6_0AEE_49B6_B0AA_A880F81668C7__INCLUDED_)
#define AFX_MYRECORDSET_H__75DD2CD6_0AEE_49B6_B0AA_A880F81668C7__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "icrsint.h"
using namespace ADODB;//необходимо для макросов AD_BINDING

class CMyRecordset  : public CADORecordBinding
{
BEGIN_ADO_BINDING(CMyRecordset)
    ADO_FIXED_LENGTH_ENTRY(1, adInteger, m_iID, m_ulIDStatus, false)
    ADO_VARIABLE_LENGTH_ENTRY(2, adVarChar, m_chTitle, sizeof(m_chTitle), 
m_ulTitleStatus, m_iLen, false)
    ADO_FIXED_LENGTH_ENTRY(3, adDouble, m_dData1, m_ulData1Status, false)
END_ADO_BINDING()
public:
    CHAR m_chTitle[51];
    double m_dData1;
    long m_iID;
    DWORD m_iLen;

    // переменные статуса
    ULONG m_ulIDStatus;
    ULONG m_ulTitleStatus;
    ULONG m_ulData1Status;
    CMyRecordset();
    virtual ~CMyRecordset();

};

#endif // 
!defined(AFX_MYRECORDSET_H__75DD2CD6_0AEE_49B6_B0AA_A880F81668C7__INCLUDED_)

Импорт ADO сделаем в stdafx.h файле

#import "C:\Program Files\Common Files\system\ado\msado21.tlb" 
rename("EOF","ADOEOF") rename("BOF","ADOBOF")

Собственно программа

// HowToBind.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <icrsint.h>

#include <stdio.h>
#include "MyRecordset.h"

_COM_SMARTPTR_TYPEDEF(IADORecordBinding, __uuidof(IADORecordBinding));

int main(int argc, char* argv[])
{
    CoInitialize(NULL);
    ADODB::_RecordsetPtr pRset("ADODB.Recordset");
    CMyRecordset rs;
    try
    {
        IADORecordBindingPtr picRs(pRset);
        pRset->Open("SELECT ID, Title, Data1 FROM Table1",
            "Provider=SQLOLEDB.1;Persist Security Info=False;User 
            ID=sa;Initial Catalog=UseADOBinding;Data Source=NONAME", 
            ADODB::adOpenStatic, ADODB::adLockOptimistic, ADODB::adCmdText);
        picRs->BindToRecordset(&rs);
        pRset->MoveFirst();
        while(!pRset->ADOEOF)
        {
            printf("%d  %s  %f\n", 
                (rs.m_ulIDStatus==adFldOK ? rs.m_iID: 0), 
                (rs.m_ulTitleStatus==adFldOK ? rs.m_chTitle : ""), 
                (rs.m_ulData1Status==adFldOK ? rs.m_dData1 : 0));
            pRset->MoveNext();
        }
    }
    catch(_com_error&)
    {}
    CoUninitialize();
    return 0;
}

На CodeGuru есть интересная утилита создающая h-файлы для класса Recordset-а. Она предлагает выбрать источник данных и таблицу. Для сложных запросов она не подходит, однако можно сделать заготовку и потом ее отредактировать.


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.
    Сообщений 1    Оценка 85        Оценить