Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции ОТИ - копия.doc
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
8.91 Mб
Скачать

Занятие №27

Использование инструментальных средств Visual C++. Классы MFC для поддержки ODBC.

Данные — это необходимое сырье информационных систем. Большинство программного обеспечения компьютеров создано для транспортировки данных и преобразования их в информацию. В связи с такой важностью данных большинство современных приложений хранят их в базах данных, что делает возможным их безопасное совместное использование. Однако защита и удобство иногда ведут себя несколько странно: доступ к данным, защищенным в базе данных, может оказаться слишком громоздким. В этой работе вы увидите, как использовать несколько возможностей MFC, позволяющих заполнять источники данных и выкачивать из них данные при необходимости.

Visual C++ — чрезвычайно гибкий инструмент; если приложение вообще может быть написано, значит, оно может быть написано на Visual C++. То же самое сказать, например, о Visual Basic или о Microsoft Access, нельзя. Но вы не должны писать приложение с использованием определенного продукта только из-за того, что он это позволяет. Если вы, например, хотите разрабатывать коммерческие приложения баз данных, Visual C++, вероятно, не подойдет для такой работы — вместо этого вы должны рассмотреть варианты использования Visual FoxPro, Powersoft PowerBuilder или Borland Visual dBASE. Средства поддержки баз данных позволяют получать доступ к базам данных из программ C++, но это еще не делает Visual C++ средой разработки баз данных.

Несмотря на то что у вас установлена новейшая версия Visual C++, обновлены не все составляющие ее средства и технологии. Приведем пример. При использовании ODBC (Open Database Connectivity — Открытое соединение с базами данных) для подключения к источнику данных необходимо задать местонахождение источников данных и драйвер, который хотите использовать. Когда ODBC только появился, это производилось при помощи средства ODBC Data Source Administrator, в котором создавалось имя источника данных (Data Source Name, DSN) на пользовательской машине.

С течением времени и появлением новых версий ODBC изъяны этого метода ставали все более очевидными. В ответ Microsoft разработала файловые DSN, позволяющие совместно использовать DSN в сети, и таким образом исключить необходимость установки DSN на каждый компьютер. Если для подключения к базе данных применяется средство Microsoft типа Visual InterDev, оно по умолчанию использует файловые DSN. Однако при использовании MFC для подключения к базе данных использовать файловый DSN возможности нет. Дело не в том, что поддержка ODBC в MFC устарела — просто она не реализована должным образом.

Создание имени источника данных (Data Source Name)

ODBC позволяет создавать программы, работающие одинаковым образом независимо от того, где сохранены реальные данные – в базе данных Oracle, Microsoft Access или в файлах индексированного последовательного метода доступа (ISAM), поддерживаемого dBASE и Paradox.

Для использования ODBC вначале потребуется создать DSN с помощью администратора источников данных ODBC. DSN определяет тип базы данных, местонахождение файлов данных и драйвер, используемый для доступа к файлам. В своих MFC-программах вы работаете так, как будто DSN и является вашей базой данных, хотя на самом деле вы будете общаться с драйвером баз данных, направляющим ваши запросы самой системе баз данных.

Cоздадим для примера DSN с именем POSTAVKA. Важно помнить, что POSTAVKA не является базой данных — он только ссылается на нее. Сначала следует соединить POSTAVKA с базой данных POSTAVKA.mdb, используя драйвер Microsoft Access 7.0.

Для создания DSN POSTAVKA выполняем следующие шаги:

  1. Запустим 32-разрядный администратор источников данных ODBC, дважды щелкнув на его пиктограмме в панели управления. Когда откроется окно программы, перейдём на вкладку User DSN. (Было бы лучше использовать File DSN или System DSN, но AppWizard, к сожалению, поддерживает только источники User DSN.) Нажмём на Add.

  2. Администратор источников данных ODBC должен знать, какой из драйверов будет использоваться. Выберем из списка диалогового окна Create New Data Source драйвер Microsoft Access Driver (*.mdb). И нажмём на Finish.

  3. Каждый из доступных драйверов слегка отличается набором опций, новсе они позволяют вводить имя источника данных и добавлять краткое его описание. В появившемся диалоговом окне ODBC Microsoft Access 97 Setup, введём имя источника данных “POSTAVKA”. При желании можно добавить какое-то описание. Если вы хотите защитить базу данных паролем, то можно добавить имя пользователя и пароль, нажав на Advanced.

  4. После именования источник данных необходимо подключить к базе данных. Нажмём на Select; диалоговое окно Select Database позволяет отыскать на диске требуемый файл. Найдите копию POSTAVKA mdb, сохранённую в своём каталоге данных, выберем её и нажмём OK.

  5. Теперь в администраторе источников данных ODBC появился новый пользовательский источник данных POSTAVKA. Нажмём на OK для закрытия приложения.

Классы MFC для поддержки ODBC.

MFC содержит несколько классов, предоставляющих широкий набор средств для поддержки взаимодействия вашего приложения с базами данных средствами ODBC.

Главную роль в этой поддержке выполняет класс Cdatabase.

Установка соединения

Класс CDatabase представляет собой класс, который обеспечивает связь с источником данных. Под источником данных может пониматься как непосредсвенно файл, в котором находится таблица, например dBase, так и файл с многими таблицами, например Microsoft Access или сервер баз данных Oracle, MS SQL Server и т.д. Для связи с источником данных используется интерфейс ODBC. У данного класса есть папа в виде класса CObject.

Для работы необходимо включить описание функций, которые находятся в файле afxdb.h:

// пример

#include "afxdb.h"

Для начала работы необходимо используя класс создать объект используя конструктор. В конструктор нет необходимости передавать параметры. После создания обьекта с ним можно проводить различные операции. Например окрывать базу данных, устанавливать тайм ауты соединения , закрывать и т.д.:

// Описание консруктора CDatabase();

// пример

CDatabase cdbMyDB();

У данного класса есть всего один член данных. Это m_hdbc. Он указывает на текущее соединение ODBC. Имеет смысл только если оно установленно. Эта переменная имеет тип HDBC.

Для установки соединения Вам необходимо вызвать функцию Open. Вот её описание.

virtual BOOL Open( LPCTSTR lpszDSN, BOOL bExclusive = FALSE,

BOOL bReadOnly = FALSE, LPCTSTR lpszConnect = "ODBC;",

BOOL bUseCursorLib = TRUE);

throw(CDBException, CMemoryException);

Как видите все параметры кроме первого не устанавливать. Первый параметр lpszDSN указывает на имя DNS для связи с источником данных. Эти имена находятся в настройке ODBC в панели управления на вкладке File DNS. Это имя можно установить в NULL, и тогда при выполнении программы Вам предложат выбрать источник. Данная ситуация изображена на рисунке ниже:

// Пример

void CDatebaseDlg::OnOpen()

{

CDatabase cdbMyDB;

cdbMyDB.Open(NULL);

}

Если вы укажите имя и оно будет ошибочно, то получите сообщение о ошибке.

// Пример

void CDatebaseDlg::OnOpen()

{

CDatabase cdbMyDB;

cdbMyDB.Open("Bad date source");

}

Для контроля над данной ситуацией необходимо воспользоваться обработкой прерываний VC++. В примере ниже перехватываются все прерывания возможные при открытии источника данных. В ответ на ошибку появится диалоговое окно.

// Пример

CDatabase cdbMyDB;

try

{

cdbMyDB.Open("Bad date source");

}

catch(...)

{

AfxMessageBox("Error Open DNS");

}

При указании правильного имени процесс установки связи может пойти двумя путями. Если с истоником не связан конкретный файл, то появится диалоговое окно с предложением выбрать файл.

// Пример

void CDatebaseDlg::OnOpen()

{

CDatabase cdbMyDB;

try

{

cdbMyDB.Open("MS Access 97 Database");

}

catch(...)

{

AfxMessageBox("Error Open DNS");

}

}

В случае, если с источником данных файл связан вы ничего не увидите. Но установку связи молжно проверить вызвав функцию IsOpen, которая вернет TRUE в случае успеха. Эта же функция поможет Вам при работе и ответит на вопрос - Связь установлена или нет. Например вы захотите испоьзовать один класс CDatabase для множества разных соединений.

// Описание BOOL IsOpen( ) const;

// Пример

void CDatebaseDlg::OnOpen()

{

CDatabase cdbMyDB;

try

{

cdbMyDB.Open("MS Access 97 Database");

if (cdbMyDB.IsOpen())

AfxMessageBox("Open Base");

else

AfxMessageBox("Not Open");

}

catch(...)

{

AfxMessageBox("Error Open DNS");

}

}

По завершению работы источник данных необходимо закрыть используя функцию Close.

// Описание virtual void Close( );

// Пример

void CDatebaseDlg::OnOpen()

{

CDatabase cdbMyDB;

try

{

cdbMyDB.Open("MS Access 97 Database");

if (cdbMyDB.IsOpen())

AfxMessageBox("Ok Open Base");

else

AfxMessageBox("Not Open");

cdbMyDB.Close();

}

catch(...)

{

AfxMessageBox("Error Open DNS");

}

}

Для работы с данным примером нам необходимо установить связь ODBC драйвера с файлом. Это очень удобно. Если у Вас есть файл на сетевом диске, то при изменении его местоположения необходиом только изменить путь в ODBC и программе. Так же и при установке нового рабочего место настраиваете доступ и программа работает.

Настройка происходит по пути - Мой компьютер -> Панель управления -> ODBC.

Настройка связи драйвера с файлом происходит на вкладке File DNS.

Здесь нам нужно выбрать пункт меню Configure.

Если файл выбран, то Вы увидите запись в разделе Database, если нет, выберите пунк Select и выберите файл. Дальнейшее описание подразумевает, что файл выбран.

В прошлый раз мы с вами упустили ряд параметров и обработку исключительных ситуаций. Так как в курсе объектно-ориентированного программирования вы изучали описание и обработку исключительных ситуаций, то мы их можем обрабатывать.

Ниже процедура открытия с новым параметром и обработкой ошибок.

CDatabase cdbMyDB;

try

{

cdbMyDB.Open("MS Access 97 Database",TRUE);

// Если TRUE не указать то по умолчанию FALSE

}

catch(CDBException cdbThrow)

{

AfxMessageBox(cdbThrow.m_strError);

}

Функция Open итмеет второй параметр который говорит и типе открытия со стороны доступа. Если здесь установлено TRUE то после открытия программой данной базы данных доступ к ней для других программ будет запрещен.

Внимание В реализацию этих функций встроены макросы ASSERT, и поэтому для проверки работоспособности данного кода надо пользоваться типом реализации Release иначе вы просто получите сообщение о прерывании программы.

Соберите и запустите программу. Нажмите кнопку. Все нормально. Выйдите из программы. Запустите ACCESS откройте таблицу и опять запустите программу, жмите кнопку. Вот теперь, так как таблица открыта, Вы и получите соответствующее сообщение. Эксклюзивный доступ подразумевает, что только один пользуется таблицей.

Данный тип доступа применим часто. Например 1C бухгалтерия использует его для востановления работоспособности таблиц. Он нужен если с Вашей базой одновременно могут работать несколько человек. Так как базы данных должны быть нормализованны, и в них выделяются таблицы с классфикаторами, то в момент изменения таблиц классификаторов доступ к ним должне быть запрешен. Вот пример. У Вас поменялся материально отвественный на складе. Есть таблица со списком данных людей. Вы перед внесением изменений должны заблокировать данную таблицу, дабы фамилия несушествуюшего человека не попала в расходные ведомости.

Результат работы функции возвращается в виде иключения, у исключения конктерный тип класса. Вот его мы и отлавливаем. А у этого класса есть член данных m_strError, который отвественнен за строку с ошибкой.

Открывать базу данных можно и так.

cdbMyDB.Open("MS Access 97 Database",TRUE,TRUE);

// Если TRUE не указать то по умолчанию FALSE

Добавленный параметр говорит о том, что база данных будет открыта только для чтения. Это тоже полезно. Например бухгалтер по складам не имеет право никак править должности людей, но он должен иметь доступ к данным. Соотвественно открывать он должен эти таблицы только для чтения. Этот режим говорит о том, что изменения в базу вноситься не будут. Если вы его явно не указали, то открыто с разрешением для правки.

На базе данных может стоять пароль.

Соотвественно когда если пароль установлен, и Вы запустите программу, то у Вас появится окно с именем пользователя и просьбой ввести пароль. Для автоматического ввода пароля используется следующий параметр.

cdbMyDB.Open("MS Access 97 Database",TRUE,TRUE,"ODBC;UID=ADMIN;PWD=123");

Последний параметр это текстовая строка с набором данных разделенных точной с запятой.

ODBC; // Тип соединения. Создан для дальнейшего использования,

// если будете пользоваться не ODBC

UID=ADMIN; // Имя пользователя

PWD=123 // Пароль

Этот набор может меняться от одной базы данных к другой. Например при связи с MS SQL есть дополнительные параметры, как HOST.

И последний возможный параметр:

cdbMyDB.Open("MS Access 97 Database",TRUE,TRUE,"ODBC;UID=ADMIN;PWD=123",TRUE);

Этот параметр указывает надо загружать или нет библиотеку курсоров. Библиотека кусоров улучшает функциональность ODBC, но нужна она не всегда.

Информация о соединении

Сразу после установки соединения есть возможность проверить его работоспособность, и получить ряд параметров соединения.

Вероятно в первую очередь вы заинтересуетесь правильностью открытия и установки соединения. Эта возможность реализована в функции IsOpen. Эта функция возвращает значение отличное от нуля, если связь установлена.

// BOOL IsOpen( ) const;

//......

CDatabase cdbMyDB;

cdbMyDB.Open("MS Access 97 Database");

if (cdbMyDB.IsOpen())

{

//......

}

//......

При установки связи в прошлый раз мы с Вами передавали строку соединения, но использовали часть параметров. Функция GetConnect() возвращает строку CString, в которой перечислены все параметры используемые при установке соединения.

// const CString& GetConnect();

if (cdbMyDB.IsOpen())

{

AfxMessageBox(cdbMyDB.GetConnect());

}

Часть параметров в строке соединенияможно не упоминать, они присутсвуют так как заданы по умолчанию. И если Вы хотите посмотреть параметры соединения с конкретным сервером, то используйте этот код для получения информации.

Теперь получим имя базы данных, с которой мы установили соединение.

// CString GetDatabaseName();

cdbMyDB.Open("MS Access 97 Database");

if (cdbMyDB.IsOpen())

{

AfxMessageBox(cdbMyDB.GetDatabaseName());

}

Возникает вопрос, зачем нам знать имя, мы же его задаем. А вот нет. Мы задаем универсальное имя, псевдоним по которому не известно, что и где раположенно. А вот именно эта функция позволяет нам на основе псевдонима узнать настоящее лицо - т.е. где и какая конкретно база данных открыта.

Проверим можно ли вносить в базу данных изменения. То есть убедимся, что открыли в режиме отличном от Read Only. Для этого воспользуемся функцией CanUpdate.

// BOOL CanUpdate();

cdbMyDB.Open("MS Access 97 Database");

if (cdbMyDB.IsOpen())

{

if (cdbMyDB.CanUpdate()) AfxMessageBox("Update Yes");

}

И проверим возможность использования транзакций используя функцию CanTransact(). Не все драйвера ODBC имеют данную возможность.

// BOOL CanTransact();

if (cdbMyDB.IsOpen())

{

if (cdbMyDB.CanTransact()) AfxMessageBox("Transact Yes");

}