Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > MFC->CDatabase and CRecordset.


Автор: En_t_end 22.7.2005, 17:31
 В связи с постоянно добавляющимися темами по данному вопросу решено было зафиксировать одну тему.

MFC позволяет работать с ODBC через класс-интерфейс CDatabase и работь с записями, в частности делать выборку, используя CRecordset.

1. Открытие источника данных(в данном случае рассмотрим открытие источника данных Аксесса, поддержка которого стандартно реализованна наиболее полно)
а.) Можно открыть источник, используя строку сформированную драйвером ODBC ранее и находящуюся в его хранилище. ЗЫ доступ в это хранилище можно получить физ. путем, то есть пуск->настройка->панель управления->администрирование->источники данных(ODBC).
Или же программно, используя соответсвенное АПИ. Чтобы выйти на полный список функций для поиска в MSDN можно набрать SQLDataSources - функция, возврающая список всех добавленных источников данных(для получения всего списка необходимо использовать рекурсивно либо в цикле). В любом случае, для открытия источника вам потребуется сформировать строку такого формата: 
Код

"DSN=MySource\0UID=MyLogin\0PWD=MyPass" /* источник данных с именем MySource, логин - MyLogin, пароль - MyPass */ 

б.) Второй способ... это открытие источника путем полного формирования строки.
Код

    CString sDriver = "MICROSOFT ACCESS DRIVER (*.mdb)";
    CString sDsn;
    sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s;UID=admin;PWD=%s",sDriver,BASE_FILE_NAME,BASE_PASS);
/* sDriver - имя драйвера в данном случае драйвер Аксесс.
 BASE_FILE_NAME - путь к источнику.(желательно указывать полный путь.
 BASE_PASS - пароль к источнику данных, если его нет, то оставляем PWD пустым.
ЗЫ UID - это логин, естественно у вас он может быть другой.
*/

Универсальная функция...
Код

//Author: chaos(c) from forum.vingrad.ru
int OpenDb(const CString &so__connect_str, CDatabase &o__db) 
// so_connect_str - ссылка на строку подключения
//o_db - ссылка на обьект CDatabase
{    
    int i__ret_code = 0;
    try
    {
        o__db.OpenEx((LPCSTR)so__connect_str, CDatabase::openReadOnly | CDatabase::noOdbcDialog); 
/* Будьте осторожны, лучше посмотреть точно флаги CDatabase в MSDN, чтобы случайно не открыть базу на запиcь, когда это не нужно.*/
    }
    catch(CDBException *xo__err)
    {
        cerr << (LPCSTR)xo__err->m_strError << endl;
        i__ret_code = 1;
    }
    
    return i__ret_code;
}


2. Связываем с базой данных специальный обьект от класса CRecordes. Это нужно, чтобы удобнее управлять структурой базы и получать результаты выборки.
Код

/*mybase - это обьект базы данных, который ранее был связан с источником функциями Open или OpenEx.*/
CRecordset recset(&mybase);


3. Простейший пример выборки всех записей из предполагаемой таблицы Test:
Код

//Author: En_t_end(c) from forum.vingrad.ru
    CString SqlString = "SELECT test FROM Test ORDER BY test DESC";
    CString test; //Строка, куда мы будем ложить результаты выборки.
    recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::skipDeletedRecords); 
//Запускаем запрос SqlString на обработку в ODBC.
//PS внимательно присматривайтесь к флагам CRecordset.
    while(!recset.IsEOF()) /*Выводим результат в некий поток test_out пока ещё есть записи в Списке.*/
    {
        recset.GetFieldValue("test",test);
test_out << test;
        recset.MoveNext(); //Переходим к следующей записи.
    }


4.
Выполнение любого другого запроса кроме выборки нужно делать через CDatabase::ExecuteSql(SqlString);

Естественно чтобы использовать эти классы нужно подключить afxdb.h

Автор: Coocky 25.7.2005, 17:38
Цитата
Универсальная функция...

считаю самой безглючной CDatabase::Open();
Строка пути имеет вариант NULL.
Тогда у вас при выполнении этой функции появится диалоговое окно с настройками.
Окно простое и затруднений не вызовет при использовании.
Все остальные данные, после открытия базы, зaполняются в поля CDatabase.
Класс CRecordset имеет в себе поля для сортировки и фильтрации-m_strFilter и m_strSort
После заполнения этих полей не забывайте использовать метод CRecordset::Requery();
Который пересчитывает(обновляет) выборку, согласно новым условиям.

Автор: Coocky 26.7.2005, 15:33
Некоторые команды(синтаксис) для работы с БД может отличаться от синтаксиса драйвера.
Поэтому, если что-то не работает, см. описание к ДРАЙВЕРУ ОДБС!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)