- •О.С. Зеленський
- •Розділ 9. Структура створення додатків
- •9.1. Загальна структура додатків
- •9.2. Додатки без використання архітектури «Документ-вид»
- •9.2.1. Приклад додатку реєстрації wnd-класу вікна
- •9.2.2. Створення та видалення дочірніх вікон без використання архітектури «Документ-Вид»
- •9.2.3. Створення дочірніх вікон без використання архітектури «Документ-Вид» (переключення вікон з використанням функції ShowWindow)
- •9.3. Архітектура «Документ-Вид»
- •Idr_mainframe формат строкового ресурсу.
- •9.3.1. Приклад додатку з використанням архітектури «Документ-Вид»
- •9.3.2. Види у архітектурі «Документ-Вид»
- •9.3.3. Створення видів у архітектурі «Документ-Вид» (переключення видів з використанням функції ShowWindow)
- •9.3.4. Робота з документами та видами на прикладі додатку SingleTemplate
- •9.4. Додатки mdi, робота з шаблонами
- •9.4.1. Приклад додатку mdi з одним шаблоном
- •9.4.2. Приклад додатку mdi з декількома шаблонами
- •Контрольні питання
- •Розділ 10. Робота з базами даних з використанням об'єктів ado
- •10.1.1. Ініціалізація об'єктів com з використанням директиви #import
- •10.1.2. Підтримка класів сом
- •10.2. Об'єкт Connection
- •10.3. Об'єкт Command
- •10.4. Об'єкт Recordset
- •10.5. Об'єкт Field і колекція Fields
- •10.6. Об'єкт Error і колекція Errors
- •10.8. Коротка характеристика структури мови sql
- •10.9. Синтаксис оператора вибору Select
- •10.10. Приклад програмування об'єктів ado
- •10.11. Опис розробленого навчального пакету ado6 для роботи з базами даних access та MySql
- •Int tip_bd; // тип бд 1- ms access, 2- MySql, 3 - xml
- •Void Connect_Baza(cString str);
- •Void ErrMessage(_com_error &ce);
- •If(pConn.CreateInstance("adodb.Connection"))
- •If(pRecordset.CreateInstance("adodb.RecordSet"))
- •Void cAdo6Doc::ErrMessage(_com_error &ce)
- •Void cAdo6Doc::OnMsaccess()
- •Void cAdo6Doc::OnMysql()
- •Void cAdo6Doc::OnXmlRead()
- •Void cAdo6Doc::Connect_Baza(cString str)
- •Virtual void DoDataExchange(cDataExchange* pDx);
- •Void cAdo6Dlg::DoDataExchange(cDataExchange* pDx)
- •Void cAdo6Dlg::Struct_MySql()
- •Void cAdo6Dlg::OnSelchangeListBaza()
- •Void cAdo6Dlg::OnVibor_bd()
- •Void cAdo6Dlg::AccessOpen()
- •Void cAdo6Dlg::xmlOpen()
- •Void cAdo6Dlg::Structura_bd()
- •Void cAdo6Dlg::OnSelchangeListTab()
- •Void cAdo6Dlg::show(int kod, int kod_bd)
- •Void cAdo6Dlg::Recordset_Baza(cString str)
- •Void cAdo6Dlg::OnClose()
- •10.11.2. Формування списку бд (MySql), відкриття бази даних (ms access), відкриття xml-файлу, формування списку таблиць (MySql і ms access) та полів (MySql, ms access, xml)
- •Void cAdo6Dlg::OnSelchangeListTab()
- •1. Обрану таблицю необхідно брати в зворотні лапки "`", щоб виключити помилку в тому випадку, якщо в імені таблиці будуть зустрічатися пробіли.
- •10.11.3. Робота з sql-запитами
- •Void cAdo6Dlg::OnZapros_Select()
- •If (str_query.Mid(0,6).Compare("select"))
- •If(!baza.Left(3).Compare("otl") &&
- •Void cAdo6Dlg::Recordset_Baza(cString str)
- •Void cado6Dlg::OnZapros_Make()
- •Vr_zap.Format(" Запрос выполнен за %f сек ",conec - nach);
- •10.11.4. Видалення, сортування, пошук, фільтрація, оновлення набору записів
- •Void cado6Dlg::OnZapis_Delete()
- •Void cado6Dlg::OnCheck_Sort()
- •Void cado6Dlg::OnFind()
- •0L,adSearchForward,bb);
- •Void cado6Dlg::OnFilter()
- •Void cado6Dlg::OnVozvrat()
- •10.11.5. Переходи по записах
- •Void cado6Dlg::OnButtonFirst()
- •Void cado6Dlg::OnButtonLast()
- •Void cado6Dlg::OnButtonLeft()
- •Void cado6Dlg::OnButtonRight()
- •Void cado6Dlg::OnButtonRecno()
- •Void cado6Dlg::OnButtonPgup()
- •Void cado6Dlg::OnButtonPgdn()
- •Void cado6Dlg::OnButtonBookmark()
- •10.11.6. Запис даних до xml-файлу
- •Void cAdo6Dlg::OnButtonSave()
- •10.11.7. Кнопки, призначені тільки для роботи з otl_tab
- •Void cado6Dlg::OnZapis_Add1()
- •Void cado6Dlg::OnZapis_Add2()
- •Void cado6Dlg::OnZapis_Update1()
- •Void cado6Dlg::OnZapis_Update2()
- •Void cado6Dlg::OnFormir_bd()
- •Void cAdo6Dlg::OnValues_Fields()
- •10.12. Використання у якості джерела даних електронної таблиці Excel
- •Контрольні питання
- •Завдання
- •Розділ 11. Програмування для інтернет
- •11.1. Створення броузера
- •11.3. Використання протоколу http
- •If ((pInternetSession)
- •11.4. Використання протоколу ftp
- •Контрольні питання
- •Розділ 12. Створення елементів activex
- •12.1. Створення елементів ActiveX
- •Invalidate();
- •12.2. Тестування елемента ActiveX
- •12.4. Створення елемента ActiveX на базі стандартних елементів
- •12.5. Відображення елементів ActiveX
- •Контрольні питання
- •Розділ 13. Налагодження програм
- •Int data[5];
- •Invalidate();
- •13.3. Установка точки переривання
- •13.2. Покрокове виконання програми
- •13.4. Перевірка значень змінних під час виконання програми
- •Контрольні питання
- •Список літератури
- •Додатки
10.11.3. Робота з sql-запитами
У даному розділі розглядаються функції відгуку на роботу з SQL-запитами. Це, відповідно <Запрос на выборку> – функція OnZapros_Select() і <Запрос на выполнение> (оновлення, видалення, додавання записів і т.д.) – OnZapros_Make().
Розглянемо функцію відгуку OnZapros_Select(), текст якої наведений нижче.
// кнопка <Запрос на выборку>
Void cAdo6Dlg::OnZapros_Select()
{
CString str_query;
m_editquery.GetWindowText(str_query);
str_query.MakeUpper ();
If (str_query.Mid(0,6).Compare("select"))
{
MessageBox("В запросе на выборку отсутствует параметр
SELECT","Ошибка!!!",MB_ICONINFORMATION );
m_editquery.SetWindowText("SELECT <*>|<список полей> FROM <список таблиц>");
m_editquery.SetFocus();
return;
}
try
{
//Реалізація SQL - запиту
Recordset_Baza(str_query);
// Прив'язка об'єкта Recordset до Datagrid
m_datagrid1.SetRefDataSource(pRecordset);
If(!baza.Left(3).Compare("otl") &&
!table.Compare("OTL_TAB")&&fields->GetCount()== 5)
show();
else show(SW_SHOW,1);
}
catch(_com_error &ce)
{
Doc->ErrMessage(ce);
}
m_editquery.SetFocus ();
}
У функції відгуку OnZapros_Select() формується запит на вибірку, результат якого записується в набір Recordset та якщо він сформований – виводиться в елемент керування DataGrid.
Спочатку перевіряється наявність першого слова SELECT у текстовому вікні за допомогою методу Compare() класу CString. Якщо ключове слово SELECT відсутнє, на екран буде виведене відповідне повідомлення. Крім того, у текстове поле m_editquery буде даний повний синтаксис команди SELECT.
Виконання SQL-запиту на вибірку винесено в окрему функцію Recordset_Baza(), текст якої наведений нижче.
//Функція створення об'єкта Recordset (MySQL та ACCESS)
//Вхід str - запит на вибірку
Void cAdo6Dlg::Recordset_Baza(cString str)
{
if (pRecordset->GetState())pRecordset->Close();
pRecordset->CursorLocation = adUseClient;
pRecordset->Open ((_bstr_t)str,(IUnknown *)pConn,
adOpenDynamic,adLockOptimistic,adCmdText);
fields = pRecordset->GetFields();
// 1-й параметр - текст SQL-запиту
// 2-й параметр - об'єкт Connection або рядок підключення
// 3-й параметр - тип курсору
// 4-й параметр - тип блокування
// 5-й параметр - опція; для SQL-запиту - adCmdText
}
За допомогою методу GetState() перевіряємо стан об’єкту pRecordset. Якщо він відкритий, його необхідно закрити. Властивості CursorLocation привласнюється значення adUseClient. Це означає, що курсор буде створений на стороні клієнта. Слід зазначити, що для оптимальної роботи з таблицями БД, а саме, редагування, додавання, оновлення записів доцільно створювати курсор на стороні клієнта й створювати об'єкт Recordset за допомогою об'єкта Recordset (метод Open()). Для роботи із груповими SQL-запитами на виконання (DELETE, UPDATE, INSERT) доцільно використовувати курсор на стороні сервера й створювати об'єкт Recordset за допомогою об'єктів Connection та Command (метод Execute()). Особливості роботи й використання об'єктів Connection, Command, Recordset наведені в підрозділах 10.2-10.4 посібника.
У метод Open() об'єкта pRecordset передається SQL-запит, вказівка на об'єкт з'єднання pConn. Особливістю є те, що в якості 2-го вхідного параметра методу Open() об'єкта Recordset (тип _variant_t) можна передати як об'єкт Connection, так і рядок підключення. У випадку передачі рядка підключення буде створений новий об'єкт Connection. У нашому випадку передається вказівка існуючого об'єкта pConn, яку необхідно привести до універсального типу вказівки COM-об'єкту (IUnknown*). Потім встановлюється тип курсору (динамічний), тип блокування (оптимістична), а також тип команди adCmdText, що доцільно використовувати при роботі із запитами на вибірку або збережені процедури. Після створення об'єкта Recordset вказівці fields привласнюється адреса на об'єкт сімейства полів (FieldsPtr), що повертається методом GetFields() об'єкта Recordset.
Важливою особливістю в тексті функції відгуку OnZapros_Select() є прив'язка набору Recordset до ActiveX-компонента DataGrid для роботи з даними набору.
Здійснюється прив'язка в такий спосіб:
m_datagrid1.SetRefDataSource(pRecordset);
В якості ресурсу для ActiveX об'єкта m_datagrid1 є pRecordset. Входом у метод SetRefDataSource() є універсальна вказівка COM-об'єкта *IUnknown. Також можуть зустрічатися синоніми даної вказівки – LPUNKNOWN, IUnknownPtr. Можна скористатися іншим варіантом, де явно передати вказівку на IUnknown (метод GetDataSource()).
m_datagrid1.SetRefDataSource(pRecordset->GetDataSource ());
Для відв’язки набору Recordset від елемента керування необхідно в метод SetRefDataSource() об'єкта CDataGrid передати 0, як показано в наступному рядку.
m_datagrid1.SetRefDataSource(0);
Відв'язуватися, потрібно в тому випадку, коли доцільно працювати тільки з об'єктом Recordset автономно, без відображення поточних змін в елементі керування DataGrid. Рекомендується це робити при роботі із сортуванням, фільтрацією даних набору, а також при виконанні незалежних операцій з набором (наприклад, формування набору, виконання розрахункових операцій).
При спрацьовуванні кожного запиту на вибірку здійснюється контроль обраної бази, таблиці й кількості полів обраної таблиці. Так якщо перші 3 символи бази даних відповідають "OTL" (otl.mdb для MS ACCESS або otl для MySQL), ім'я таблиці відповідає "OTL_TAB", і кількість полів відповідає 5 – на екран дисплея будуть показані всі елементи керування show(). У іншому випадку буде мати місце обмежена робота з таблицею обраної БД – show(SW_SHOW,1). Другий параметр у функції show(), говорить про те, чи потрібно приховувати певні елементи керування. За замовчуванням цей параметр дорівнює 0, тобто будуть показані всі елементи керування. Якщо цей параметр відмінний від нуля – на екран не виведуться наступні кнопки: (<Добавление 1>, <Добавление 2>, <Обновление 1>, <Обновление 2>, <Значение полей>, <Формирование БД>).
Слід відзначити, що в цьому випадку як й у попередніх варіантах використовується технологія try ... catch() для обробки помилок, інформація про які повертається за допомогою користувацької функції ErrMessage().
Розглянемо функцію відгуку OnZapros_Make() (кнопка <Запрос на выборку>), у якій виконуються SQL-запити, пов'язані зі зміною даних у таблиці (SQL-запити на виконання за винятком SQL-запитів на вибірку). Текст функції OnZapros_Make() наведений нижче.
// кнопка <Запрос на выполнение>