Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ООПиП (часть 3). Пример лабораторной работы №2

..pdf
Скачиваний:
11
Добавлен:
01.04.2014
Размер:
321.51 Кб
Скачать

БГУИР: Дистанционное обучение (неофициальный сайт)

Министерство образования Республики Беларусь Учреждение образования

«Белорусский государственный университет информатики и радиоэлектроники»

Инженерно-экономический факультет Кафедра экономической информатики

Лабораторная работа №2: «Управление базами данных»

Проверил: Огневая Татьяна Анатольевна

Выполнил: студент группы (дистанционная форма обучения) Wasja

Минск 2009

http://do.ucoz.net

БГУИР: Дистанционное обучение (неофициальный сайт)

1 Краткие теоретические сведения

Базы данных относиться к широко распространенным компьютерным приложениям, которые находят применение практически в любом виде деятельности. Существование множества различных систем управления базами данных создает огромные сложности для программистов, поскольку необходимо было учитывать все тонкости механизма доступа к данным. Современные версии Visual C++ включают классы, базирующиеся на механизмах ODBC (Open Database Connectivity) и DAO (Data Access Objects). Различия между системами ODBC и DAO со-

стоят в следующем:

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

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

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

Система ODBC реализована в виде набора DLL-модулей, а DAO реализована как набор объектов OLE.

Создание БД-программы на основе классов ODBC состоит из трех этапов:

1.Регистрация БД в системе в качестве источника данных, доступ к которому будет осуществляться через драйвер ODBC.

2.Создание заготовки БД-приложения. Для генерации классов работы с БД

вмастере необходимо установить переключатель поддержки работы с БД в положение «Database view without file support» (без поддержки работы с файлами) или «Database view with file support» (с поддержкой), после чего необходимо выбрать тип доступа ODBC и указать зарегистрированный ранее источник данных ODBC и необходимые таблицы БД. Далее требуется выбрать тип набора записей. Набор записей (Recordset) – это выборка из таблицы (или запроса) базы данных. Существуют три вида набора записей:

Snapshot (моментальный снимок) – статическая копия данных, которые содержатся в одной или нескольких таблицах базы данных. Этот тип набора записей используется в основном для поиска и обобщения данных. Недостатки: а) не видны обновления, сделанные по сети другими пользователями (используется устаревшая информация); б) повышенная нагрузка на сеть (одновременная загрузка всех записей); в) повышение времени загрузки данных. Преимущества: а) после загрузки набора сеть не используется; б) повышение общей производительности приложения (все записи находятся на машине пользователя).

Dynaset (динамический набор) – динамическая копия данных, любые внесенные в набор изменения сразу же становятся доступны всем остальным пользователям базы данных. В этом случае для каждой запрашиваемой за-

http://do.ucoz.net

2

БГУИР: Дистанционное обучение (неофициальный сайт)

писи создается отдельный указатель, а с сервера загружаются только те записи, которые нужны для заполнения формы. Этот тип подходит для приложений, где пользователь больше всего времени будет тратить на корректировку данных, а также для больших баз данных. Преимущества: а) быстродействие; б) актуальность данных, как на машине пользователя, так и на сервере. Недостатки: а) необходим постоянный доступ к серверу; б) снижение производительности приложения.

Table (таблица) – доступен только для DAO, результат выполнения запроса помещается во временную таблицу, что сокращает объем информации, загружаемой с сервера, и обеспечивает возможность манипуляции полями и записями временной таблицы.

3.Модификация формы для отображения содержимого БД и добавление необходимого программного кода. После добавление на форму требуемых элементов редактирования, соответствующих полям таблиц БД, необходимо установить связь, посредством которой может происходить обмен данными между элементами и источником данных, в качестве которых выступают переменные-члены указателя m_pSet. Собственно обмен данными осуществляется с помощью механизма RFX (Record Field Exchange, обмен полями записи), который работает в обоих направления от полей данных результирующего набора к записям источника данных и наоборот.

Наиболее важными из классов ODBC библиотеки MFC являются:

1.Класс CDatabase – обеспечивает связь между создаваемым приложением

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

Данные – хранят информацию, используемую для работы непосредственно с базой данных.

Создание соединения – в эту категорию входят конструктор и методы для открытия (Open, OpenEx) и закрытия (Close) базы данных.

Атрибуты данных – функции, используемых для получения информации о соединении, драйвере и источнике данных, а также для установки некоторых опций источника данных: GetConnect – получение описывающей соединение строки; IsOpen – определение наличия соединения с источником данных; CanUpdate – проверка возможности обновления БД текущим пользователем.

Операции – функции, позволяющие обрабатывать транзакции и непосредственно выполнять команды SQL (ExecuteSQL).

Переопределяемый метод – метод, позволяющий программисту более конкретно настроить функционирование объекта CDatabase.

2.Класс CRecordSet – представляет собой реальные данные, выбранные в настоящий момент из источника данных (выборка данных), а его методы обеспечивают выполнение операций с этими данными. Все компоненты и методы класса можно разбить на семь категорий:

Компоненты данных – служат для хранения информации, используемой для непосредственной работы с базой данных, к которой объект этого класса был присоединен: m_nFields – число полей данных в результирующем наборе; m_nParams – число параметров в результирующем наборе;

http://do.ucoz.net

3

БГУИР: Дистанционное обучение (неофициальный сайт)

m_pDatabase – указатель на объект класса CDatabase, посредством которого результирующий набор соединяется с источником данных; m_strFilter – используется в качестве фильтра, что позволяет выбирать только записи, удовлетворяющие заданному критерию; m_strSort – используется в качестве фильтра, позволяющего сортировать записи, удовлетворяющие заданному критерию.

Конструирование – в эту категорию входят конструктор и методы для открытия (Open) и закрытия (Close) соединения с источником данных.

Атрибуты результирующего набора – функции, используемые для получения информации о результирующем наборе: CanAppend – определение, можно ли добавлять записи в результирующий набор; CanBookmark – определение, можно ли отмечать записи в результирующем наборе с помощью закладок; CanRestart – определение, можно ли обновлять данные в результирующем наборе; CanUpdate – определение, можно ли обновлять записи в результирующем наборе; GetRecordCount – возвращает размер (число записей) результирующего набора; GetStatus – возвращает индекс текущей записи в результирующем наборе и/или найдена ли последняя запись; GetTableName – получение имени таблицы, на которой основывается запрос результирующего набора, или пустую строку; GetSQL – получение оператора SQL, который используется для выборки записей результирующего набора; IsOpen – проверка, открыт ли уже результирующий набор; IsBOF – определение, является ли текущая запись первой в наборе данных; IsEOF – определение, является ли текущая запись последней в наборе данных; IsDeleted - определение, была ли текущая запись удалена.

Операции обновления результирующего набора – операции, предназначенные для обработки транзакций: AddNew – подготовка новой записи к добавлению в результирующий набор; Delete – удаляет текущую запись; Edit – позволяет изменять поля текущей записи; Update – вызов этой функции является обязательным для корректного завершения операции добавления и обновления записей в результирующий набор.

Операции перемещения по результирующему набору. Функции, позволяющие перемещаться по записям результирующего набора: Move – перемещение к заданной записи; MoveFirst – делает текущей первую запись результирующего набора; MoveLast – делает текущей последнюю запись результирующего набора; MoveNext – делает текущей первую запись следующего набора строк (или следующую запись); MovePrev – делает текущей первую запись предыдущего набора строк (или предыдущую запись).

Другие операции над результирующим набором – функции, предоставляющие дополнительные функциональные возможности: Cancel – вызов функции является просьбой к источнику данных отменить либо обрабатываемую асинхронную операцию, либо второй поток; IsFieldDirty – возвращает ненулевое значение, если поле данных было изменено после вызова AddNew или Edit; IsFieldNull – проверка поля на содержание значения Null; IsFieldNullable – проверка поля на допустимость хранения значения Null; Requery – обновление результирующего набора; SetFieldDirty – позволяет пометить поле данных результирующего набора как измененное

http://do.ucoz.net

4

БГУИР: Дистанционное обучение (неофициальный сайт)

или не изменившееся; SetFieldNull – позволяет пометить поле данных результирующего набора как содержащее или не содержащее значение Null; SetParamNull – позволяет установить параметр в значение Null или не Null.

Переопределяемые методы – функции, позволяющие программисту настроить функционирование объекта класса CRecorset: DoFieldExchange – вызывается для организации обмена данными между полями результирующего набора и соответствующими столбцами текущей записи в источнике данных; GetDefaultConnect – библиотека MFC вызывает данную функцию, чтобы получить строку, содержащую источник данных, на котором базируется результирующий нaбop; GetDefaultSQL – библиотека MFC вызывает эту функцию, чтобы получить строку, содержащую оператор SQL, на котором базируется результирующий набор.

3.Класс CRecordView – окно, создаваемое объектом класса, обеспечивает

вприложении связь с объектом класса CRecordSet, осуществляя обмен информацией между программой, элементами управления окна и выборкой данных. Объ-

екты CRecordView используют механизм DDX (Dialog Data Exchange, обмен дан-

ными с блоком диалога) и RFX (Record Field Exchange, обмен полями записей) для автоматического перемещения данных между элементами управления формы и полями результирующего набора. Вce компоненты и методы этого класса можно условно разбить на три категории:

Создание объекта – конструктор для создания объекта.

Атрибуты данных – функции, используемые для получения информации о результирующем наборе, к которому присоединена форма: OnGetRecordset

– возвращает указатель на объект CRecordSet, ассоциированный с формой, позволяет тем самым работать с некоторым результирующим набором (виртуальная функция, требующая обязательного переопределения); IsOnFirstRecord – позволяет определить, является ли текущая запись первой в результирующем наборе, ассоциированном с данной формой; IsOnLastRecord – позволяет определить, является ли текущая запись последней в результирующем наборе, ассоциированном с данной формой.

Операции – функция OnMove, позволяющая изменять указатель на текущую запись, т.е. перемещаться по записям результирующего набора и отображать его поля в элементах управления формы.

2Задание

Разработать приложение управления базой данных учета прибыли от выполнения ремонтно-строительных работ. В разрабатываемом приложении обеспечить добавление, редактирование, удаление, поиск записей, а также просмотр всех записей из базы данных. В качестве СУБД необходимо использовать MS SQL Server 2005, количество полей в таблице не менее 4-х, типы полей разные. Доступ к данным осуществлять с использованием ODBC.

http://do.ucoz.net

5

БГУИР: Дистанционное обучение (неофициальный сайт)

3 Выполнение работы

3.1 Разработка алгоритма программы

Разработка любого БД-приложения начинается с разработки структуры БД. В поставленной задаче необходимо разработать БД учета прибыли от выполнения ремонтно-строительных работ. Для выполнения поставленной задачи достаточно базы данных, содержащей одну таблицу «Works» со следующими полями:

Поле «ID»: первичный ключ, счетчик. Предназначено для хранения номера произведенной работы, позволяющего однозначно ее идентифицировать.

Поле «Name»: строка (30 символов). Предназначено для хранения ФИО заказчика.

Поле «Address»: строка (30 символов). Предназначено для хранения адреса проведения ремонтно-строительных работ.

Поле «Phone»: строка (15 символов). Предназначено для хранения номера телефона заказчика.

Поле «Price»: число с плавающей запятой. Предназначено для хранения

окончательной цены, произведенных ремонтно-строительных работ. После выполнения трех стандартных этапов разработки БД-приложения,

приведенных в теории, формируется приложение, поддерживающее редактирование данных из БД. Исходя из задания, полученное приложение необходимо дополнить возможностью добавления, удаления, поиска записей, а также возможностью просмотра всех записей из базы данных. Реализация данных функций удобно осуществить с помощью стандартных функций классов MFC для работы с

ODBC.

Блок-схемы алгоритмов функций добавления новой записи и удаления текущей записи приведены на рисунке 3.1.

Рисунок 3.1 – Блок-схемы алгоритмов: а) функции добавления новой записи; б) функции удаления текущей записи

http://do.ucoz.net

6

БГУИР: Дистанционное обучение (неофициальный сайт)

Для реализации поиска записей удобно применить средство фильтрации данных, используя возможности языка SQL для формирования требуемых запросов, благодаря чему обеспечивается возможность одновременного поиска по нескольким полям (вплоть до поиска по всем полям). Блок-схема алгоритма функции фильтрации (поиска) данных приведена на рисунке 3.2.

Рисунок 3.2 – Блок-схемы алгоритма функции фильтрации (поиска) данных

Для реализации возможности просмотра всех записей таблицы удобно использовать стандартные возможности печати и предварительного просмотра, предоставляемые мастером создания приложений Visual Studio. С учетом этого, блоксхема алгоритма функции печати (просмотра) всех записей БД примет вид, представленный на рисунке 3.2.

 

Начало

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Получение

 

 

 

 

Получение высоты

 

 

 

Вычисление

 

 

 

Перемещение на

 

 

 

информации о

 

 

 

 

 

 

 

параметров вывода

 

 

 

 

 

 

 

 

 

 

текста

 

 

 

 

 

 

первую запись БД

 

 

 

принтере

 

 

 

 

 

 

 

таблицы БД

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Перемещение на

Вывод строки

нет

следующую запись

Последняя

таблицы БД

запись?

БД

 

 

да

 

Загрузка данных из

 

 

 

 

Перемещение на

 

 

 

 

Вызов функции

 

 

переменных на

 

 

 

 

первую запись в

 

 

 

 

родительского

 

 

 

 

 

 

 

 

 

 

 

 

форму

 

 

 

 

БД

 

 

 

 

класса

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Вывод заголовка таблицы БД

Вычисление кол-ва строк на странице

Конец

Рисунок 3.3 – Блок-схемы алгоритма функции печати (просмотра) всех записей

http://do.ucoz.net

7

БГУИР: Дистанционное обучение (неофициальный сайт)

3.2 Исходные тексты программы

3.2.1Заголовок класса CLab3_2Set (CLab3_2Set.h)

//Заголовок класса CLab3_2Set

#pragma once

class CLab3_2Set : public CRecordset

{

public:

CLab3_2Set( CDatabase* pDatabase = NULL ); // Стандартный конструктор

virtual CString GetDefaultConnect(); // Соединение с БД

virtual CString GetDefaultSQL(); // SQL-запрос выборки данных

virtual void DoFieldExchange(CFieldExchange* pFX); // Поддержка RFX

DECLARE_DYNAMIC( CLab3_2Set )

// Динамическое создание объекта

/* =================== */ /* Поля выборки данных */ long m_ID; CStringm_Name; CStringm_Address; CStringm_Phone;

double m_Price;

/* =================== */

};

3.2.2Реализация класса CLab3_2Set (CLab3_2Set.cpp)

//Реализация класса CLab3_2Set

#include "stdafx.h" #include "Lab3_2.h" #include "Lab3_2Set.h"

#ifdef _DEBUG

#define new DEBUG_NEW #endif

IMPLEMENT_DYNAMIC(CLab3_2Set, CRecordset) // Динамическое создание объекта

CLab3_2Set::CLab3_2Set( CDatabase* pdb )

:CRecordset(pdb)

//Стандартный конструктор

{

m_ID = 0;

m_Name = _T(""); m_Address = _T(""); m_Phone = _T(""); m_Price = 0.0; m_nFields = 5;

m_nDefaultType = dynaset;

}

CString CLab3_2Set::GetDefaultConnect() // Соединение с БД

{

return _T("ODBC;DSN=Lab3_2");

}

http://do.ucoz.net

8

БГУИР: Дистанционное обучение (неофициальный сайт)

CString CLab3_2Set::GetDefaultSQL() // SQL-запрос выборки данных

{

return _T("[Works]");

}

void CLab3_2Set::DoFieldExchange( CFieldExchange* pFX ) // Поддержка RFX

{

pFX->SetFieldType( CFieldExchange::outputColumn );

// Указание, что все вызовы функций RFX являются полями

/* ============================================= */ /* Ассоциация полей выборки данных с переменными */ RFX_Long( pFX, _T("[ID]"), m_ID );

RFX_Text( pFX, _T("[Name]"), m_Name ); RFX_Text( pFX, _T("[Address]"), m_Address ); RFX_Text( pFX, _T("[Phone]"), m_Phone ); RFX_Double( pFX, _T("[Price]"), m_Price );

/* ============================================= */

}

3.2.3Заголовок класса CLab3_2Doc (CLab3_2Doc.h)

//Заголовок класса CLab3_2Doc

#pragma once

// Защита от повторных подключений заголовка

#include "Lab3_2Set.h"

class CLab3_2Doc : public CDocument

{

protected:

DECLARE_DYNCREATE( CLab3_2Doc )

//Динамическое создание объекта

DECLARE_MESSAGE_MAP()

//Функция генерации карты сообщений

public:

CLab3_2Set m_lab3_2Set;

// Экземпляр, ассоциированного с документом набора данных

};

3.2.4Реализация класса CLab3_2Doc (CLab3_2Doc.cpp)

//Реализация класса CLab3_2Doc

#include "stdafx.h" #include "Lab3_2.h" #include "Lab3_2Set.h" #include "Lab3_2Doc.h"

#ifdef _DEBUG

#define new DEBUG_NEW #endif

IMPLEMENT_DYNCREATE( CLab3_2Doc, CDocument ) // Динамическое создание объекта

BEGIN_MESSAGE_MAP( CLab3_2Doc, CDocument ) // Функция генерации карты сообщений

END_MESSAGE_MAP()

3.2.5 Заголовок класса CLab3_2View (CLab3_2View.h)

http://do.ucoz.net

9

БГУИР: Дистанционное обучение (неофициальный сайт)

// Заголовок класса CLab3_2View

#pragma once #include "afxwin.h"

class CLab3_2Set;

class CLab3_2View : public CRecordView

{

protected: CLab3_2View();

//Стандартный конструктор

DECLARE_DYNCREATE( CLab3_2View )

//Динамическое создание объекта

virtual void DoDataExchange( CDataExchange* pDX ); // Поддержка DDX/DDV

virtual void OnInitialUpdate(); // Инициализация

virtual BOOL OnPreparePrinting( CPrintInfo* pInfo );

//Обработчик запуска предварительного просмотра или печати virtual void OnBeginPrinting( CDC* pDC, CPrintInfo* pInfo );

//Обработчик начала печати (задание количества страниц) void OnPrepareDC( CDC* pDC, CPrintInfo* pInfo );

//Обаботчик подготовки к печати

void OnPrint( CDC* pDC, CPrintInfo* pInfo ); // Обработчик печати

afx_msg void OnRecordNew();

//Обработчик команды создания новой записи afx_msg void OnRecordDel();

//Обработчик команды удаления записи

afx_msg void OnBnClickedButtonFilter(); // Обработчик кнопки "Применить фильтр"

afx_msg void OnUpdateRecordDel( CCmdUI *pCmdUI );

//Обработчик обновления пользовательского интерфейса для кнопки

//удаления записи

/* =================================== */ /* Обработчики сброса/установки флагов */ afx_msg void OnBnClickedCheck1();

afx_msg void OnBnClickedCheck2(); afx_msg void OnBnClickedCheck3(); afx_msg void OnBnClickedCheck4();

/* =================================== */

DECLARE_MESSAGE_MAP()

// Функция генерации карты сообщений

public:

CLab3_2Doc* GetDocument(); // Получение документа

virtual CRecordset* OnGetRecordset(); // Получение набора данных

enum { IDD = IDD_LAB3_2_FORM };

//Данные диалога

CLab3_2Set* m_pSet;

//Экземпляр набора данных

/* ================================================== */ /* Ассоциированные с элементами управления переменные */ CEdit m_NameF;

CEdit m_AddressF; CEdit m_PhoneF; CEdit m_PriceF; BOOL m_PriceB; BOOL m_PhoneB;

http://do.ucoz.net

10