Использование ODBC в Visual C++ - Понимание RFX
ОГЛАВЛЕНИЕ
Понимание RFX
RFX - Record Field Exchange. Это механизм обмена данными между классом потомком от CRecordset и самой базой данных. Работа этого механизма по смыслу аналогична работе DDX. Данный механизм применяет ClassWizard при автоматическом создании класса CRecordset.
Для работы с RFX нам необходимо создать сына от класса CRecordset на основе известной структуры базы данных. Я создал в файле ACCESS новую таблицу TABLE3 с одним текстовых полем, и поместил туда две записи. Итак нам известна структура - одна текстовая колонка (не являющаяся ключевым полем). Эта текстовая колонка.
class MyCrec:public CRecordset
{
public:
MyCrec( CDatabase* pDatabase = NULL);
virtual void DoFieldExchange(CFieldExchange* pFX);
CString m_Fam;
};
Как видите ничего необычного нет. Простое наследование, перегрузка конструктора, обьявление функции DoFieldExchange для организации механизма обмена и переменной типа CString для соответствия формату поля колонки из таблицы базы данных. Я не сделал эту переменную private, но Вы можете это делать спокойно.
Реализация конструктора. Просто и ясно :-).
MyCrec::MyCrec( CDatabase* pDatabase)
:CRecordset(pDatabase)
{
}
Функция обмена:
void MyCrec::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX,_T("Famili"),m_Fam);
}
В простом приближении правило простое. Перед функциями обмена надо вызвать SetFieldType.
Опять сильно упрошено. Эта функция позволяет Вам произвести обмен между переменной типа CString и текущей строкой в конкретной колонке базы данных. У меня колонка называется Famili. Обратите внимание на то, что строка помещена в конструкцию _T(...), это сделано для гарантии создания объекта типа CString. А вот ниже полное описание этой функции.
void RFX_Text( CFieldExchange* pFX, const char* szName,
CString& value, int nMaxLength = 255, int nColumnType = SQL_VARCHAR,
short nScale = 0 );
После создания данного класса мы можем воспользоваться им, например, для добавления новой записи в Базу данных.
void CDatebaseDlg::OnOpen()
{
MyCrec cr(NULL);
try
{
cr.m_nFields=1;
cr.Open(CRecordset::dynaset, "SELECT * FROM TABLE3");
if(cr.CanAppend())
{
cr.AddNew();
}
cr.m_Fam="Kaev";
cr.Update();
cr.Close();
}
catch(CDBException cdb)
{
AfxMessageBox(cdb.m_strStateNativeOrigin);
}
}
Итак, объявляем объект от нашего класса. Устанавливаем количество колонок в m_nFields. Открываем набор записей, как динамический (т.е. в который можно вносить измения) - dynaset. CanAppend проверяет возможность добавления записей. Запись добавляется пустая. Вводим в переменную содержание и заносим данные непосредственно в базу данных Update.