Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual2.doc
Скачиваний:
5
Добавлен:
07.03.2016
Размер:
3.31 Mб
Скачать

10.1.2. Підтримка класів сом

При написанні додатків з використанням ADO доцільно використовувати СОМ-класи, підтримувані компілятором Visual C++. До класів підтримки відносяться наступні.

_com_error. Використовується для обробки умов виняткових ситуацій, які виникають при помилках роботи з БД.

_com_ptr_t. Визначає гнучку вказівку для об'єкта інтерфейсу СОМ і застосовується при роботі з об'єктами ADO.

_variant_t. Інкапсулює тип даних VARIANT і може значно спростити код додатку, оскільки робота безпосередньо з даними VARIANT є трудомісткою.

_bstr_t. Інкапсулює тип даних BSTR. Цей клас забезпечує вбудовану обробку процедур розподілу і звільнення ресурсів, а також інших операцій.

Додаткова інформація про кожен з цих класів показана в роботі ADO6 у п. 10.11, де наводиться їх практичне використання.

10.1.3. Об'єкти ADO

Інтерфейс ADO складається з наступних класів об'єктів.

Connection. Використовується для зв'язку з джерелом даних, а також для обробки команд і транзакцій.

Command. Використовується для роботи з командами, які відправляються джерелу даних.

Recordset. Використовується для роботи з табличними даними, у тому числі для перегляду і модифікації даних.

Field. Використовується для надання інформації про стовпці в наборі записів, включаючи значення цього стовпця та іншу інформацію.

Рarameter. Використовується для обміну даними з командами, які відправляються джерелу даних.

Рroperty. Використовується для маніпулювання певними властивостями інших об'єктів, що використовуються в ADO.

Еrror. Використовується для більш конкретної інформації про можливі помилки.

Для взаємодії з об'єктами ADO використовуються вказівки, що дозволяють отримати доступ до різних об'єктів. Вказівки на наступні об'єкти описані у файлі msado15.tlh. Основні з них: _ConnectionPtr, _CommandPtr, _RecordsetPtr, FieldsPtr, FieldPtr.

При характеристиці властивостей і методів об'єктів ADO можуть використовуватися значення деяких параметрів за замовчуванням. Для завдання параметрів за замовчуванням необхідно задати порожній рядок "" для текстових даних і 0 – для числових даних.

Якщо параметри методів об'єктів мають різні значення, які можуть виконуватись спільно, то іноді ці значення можна складати за допомогою операнда "|" (порозрядне "АБО").

10.2. Об'єкт Connection

ADO використовує об'єкт Connection для з'єднання з джерелом даних. Якщо використовується ADODB, то ці об'єкти забезпечують з'єднання з джерелом даних OLE DB. Якщо використовується MSDASQL, то джерело даних – ODBC. З'єднання може представляти собою реальне мережеве з'єднання з сервером бази даних або з локальним файлом бази даних, наприклад Microsoft Access. Для виконання будь-яких операцій над джерелом даних потрібен об'єкт Connection, хоча цей об'єкт створювати не обов'язково. Надається можливість створювати з'єднання в об'єктах Command і Recordset. Тим не менш, багато операцій можна виконати лише з використанням об'єкта Connection. Наприклад, управління транзакціями і використання колекції Errors (з об'єктами Error) можливо тільки в об'єкті Connection.

Властивості і методи об'єкта Connection

У таблицях 10.1, 10.2 наведено відповідно основні властивості і методи об'єкта Connection.

Таблиця 10.1

Властивості об'єкта Connection

Властивості

Опис

Version

Повертає рядок, що визначає версію бібліотеки.

ConnectionString

Визначає параметри підключення до джерела даних. Цей рядок містить параметри, розділені крапкою з комою. Властивість ConnectionString може задаватися до відкриття з'єднання з використанням методу Open.

ConnectionTimeout

Встановлює або повертає число секунд очікування підключення до бази даних. Значення за замовчуванням – 15. Доцільно використовувати цю властивість при виникненні проблем через щільний мережевий трафік або завантаженості сервера. Якщо час, вказаний у ConnectionTimeout, закінчується до відкриття підключення, то відбувається помилка, і ADO скасовує спробу підключення. Якщо у властивість встановити нульове значення, то ADO буде чекати нескінченно, поки підключення не буде відкрито. Необхідно впевнитися, що використовуваний провайдер підтримує властивість ConnectionTimeout. Властивість необхідно встановити до відкриття з'єднання.

CommandTimeout

Встановлює або повертає число секунд очікування виконання команди. Значення за замовчуванням – 30. Необхідно використовувати цю властивість при виникненні проблем через щільний мережевий трафік або завантаженості сервера. Якщо час, вказаний у CommandTimeout, закінчується до завершення виконання команди, то відбувається помилка, і ADO скасовує команду. Якщо встановити у властивість нульове значення, то ADO буде чекати нескінченно, поки команда не буде виконана. Необхідно впевнитися, що використовуваний провайдер підтримує властивість CommandTimeout. Установка CommandTimeout об'єкта Connection не пов'язана з установкою властивості CommandTimeout об'єкта Command.

Provider

Встановлює або повертає рядкове значення, яке містить ім'я використовуваного провайдера. За замовчуванням – "MSDASQL". Провайдер може бути також встановлений вмістом властивості ConnectionString або параметром методу Open. Визначення провайдера в більш ніж одному місці може мати непередбачувані результати.

CursorLocation

Визначає розташування курсору, тобто місце, де виконується робота з даними. Можливі значення:

  • adUseServer(2) - курсор на стороні провайдера (за замовчуванням).

  • adUseClient(3) - курсор на стороні користувача. Може надавати додаткові можливості, які відсутні на стороні провайдера.

Зміна властивості CursorLocation не має ніякого ефекту при вже існуючому підключенні. Пов'язані об'єкти Recordset і курсори, повернуті методом Execute, успадковують цю установку. При відкритому об'єкті Recordset ця властивість доступна тільки для читання.

Продовження таблиці 10.1

Властивості

Опис

Mode

Визначає режим доступу для зміни даних в сеансі. Можливі значення:

  • adModeUnknown(0) - режим доступу не встановлений або не може бути визначений (за замовчуванням).

  • adModeRead(1) - режим тільки для читання.

  • adModeWrite(2) - режим тільки для запису.

  • adModeReadWrite(3) - режим для читання і запису.

  • adModeShareDenyRead(4) - не дозволяє відкривати з'єднання на читання іншим користувачам.

  • adModeShareDenyWrite(8) - не дозволяє відкривати з'єднання на запис іншим користувачам.

  • adModeShareExclusive(12) - не дозволяє відкривати з'єднання іншим користувачам.

  • adModeShareDenyNone(16) - дозволяє відкривати з'єднання з будь-яким видом доступу іншим користувачам.

Ви можете встановити цю властивість до відкриття об'єкта Connection.

State

Повертає стан об'єкта. Властивість State може приймати такі значення:

  • adStateClosed(0) - об'єкт закритий.

  • adStateOpen(1) - об'єкт відкритий.

  • adStateConnecting(2) - об'єкт з'єднується.

  • adStateExecuting(4) - об'єкт виконує команду.

  • adStateFetching(8) - об'єкт виконує вибірку рядків.

Properties

Містить колекцію динамічних властивостей з'єднання (об'єктів Property).

Таблиця 10.2

Методи об'єкта Connection

Методи

Опис

Open(ConnectionString, UserID, Password, Options)

Відкриває сеанс підключення до джерела даних. Параметри:

  • ConnectionString - необов'язковий. Рядок, що визначає параметри підключення до джерела даних. Автоматично успадковує значення властивості ConnectionString об'єкта Connection. Є можливість або встановити властивість ConnectionString об'єкта Connection перед викликом методу Open, або використовувати параметр ConnectionString методу Open.

  • UserID - необов'язковий. Ім'я користувача, використовуване при з'єднанні.

  • Password - необов'язковий. Пароль користувача.

  • Options. Спосіб підключення до джерела даних. Можливі значення:

    • adAsyncConnect(16) - відкриває підключення асинхронно, при якому нові запити виконуються, не чекаючи відповідей від попередніх запитів. Щоб визначити, коли підключення стане доступним, можна обробляти подію ConnectComplete.

    • adConnectUnspecified(-1) - відкриває підключення синхронно, при якому завжди очікується результат останнього запиту (за замовчуванням).

Якщо передається інформація про користувача і пароль як у рядку ConnectionString, так і в параметрах UserID і Password, то параметри UserID і Password мають пріоритет. Після завершення роботи з об'єктом Connection необхідно використовувати метод Close() для звільнення всіх пов'язаних системних ресурсів.

Close()

Закриває з'єднання з джерелом даних. Закриття об'єкта не призводить до видалення його з пам'яті. Можна змінити властивості об'єкта, а потім відкрити його знову. При закритті підключення закриваються також всі активні набори записів (об'єкти Recordset) для даного підключення. Об'єкти Command, пов'язані з даними підключенням, вже не будуть пов'язані з даним об'єктом Connection. Закриття об'єкта Connection під час транзакції генерує помилку і ADO автоматично відкатує транзакцію.

Execute(CommandText, RecordsAffected, Options)

Виконує запит, оператор SQL, збережену процедуру або будь-яку іншу команду, доступну провайдеру. Повертає об'єкт Recordset, доступний тільки для читання курсором, що проглядається тільки зверху-вниз (forward-only), якщо передана команда повертає записи. (Якщо потрібний об'єкт Recordset, доступний для запису, то слід створити його безпосередньо, і скористатися його властивостями і методами.) Параметри:

  • CommandText - обов'язковий. Рядок, що містить оператор SQL, ім'я таблиці, збереженої процедури або іншу команду провайдера.

  • RecordsAffected - необов'язковий. Ціле число (long), що визначає число записів.

  • Options - необов'язковий. Ціле число (long), що визначає тип команди. Можливі значення (можна вибирати кілька значень, використовуючи порозрядне "АБО"):

    • adCmdText(1) - текстове визначення команди або збереженої процедури.

    • adCmdTable(2) - створення SQL-запиту, який повертає всі рядки зазначеної таблиці.

    • adCmdStoredProc(4) - збережена процедура.

    • adCmdUnknown(8) - тип команди невідомий (за замовчуванням).

    • adAsyncExecute(16) - асинхронне виконання команди.

    • adExecuteNoRecords(128) - не повертати рядки.

Cancel()

Відміняє виконання останнього асинхронного виклику Execute() або Open(), якщо дію ще не завершено.

Продовження таблиці 10.2

Методи

Опис

BeginTrans() CommitTrans() RollbackTrans()

Виклик методу BeginTrans починає нову транзакцію. Провайдери, які підтримують вкладені транзакції, при виклику методу BeginTrans в межах відкритої транзакції починають нову, вкладену транзакцію. Повертаєме методом BeginTrans значення вказує рівень вкладення: якщо значення "1", то відкрита транзакція верхнього рівня (тобто транзакція не вкладена в межах іншої транзакції), "2" вказує, що відкрита транзакція другого рівня (транзакція, вкладена в межах транзакції верхнього рівня), і т.д.

Виклик методу CommitTrans зберігає зміни, зроблені в межах відкритої транзакції і завершує транзакцію. Виклик методу RollbackTrans повністю скасовує будь-які зміни, зроблені в межах відкритої транзакції і завершує транзакцію. Виклик будь-якого з цих методів у момент, коли немає відкритої транзакції, генерує помилку. Виклики методів CommitTrans або RollbackTrans зачіпають тільки останню відкриту транзакцію; необхідно закрити або зробити відкат поточної транзакції перш, ніж вирішити будь-які високорівневі транзакції.

OpenSchema(QueryType, Criteria, SchemaID)

Отримує інформацію структури бази даних. Повертає об'єкт Recordset тільки для читання. Параметри:

  • QueryType - число, тип запиту схеми.

  • Criteria - необов'язковий. Масив обмежень запиту (фільтр).

  • SchemaID - GUID для запиту схеми провайдера, із не визначеною специфікацією. Цей параметр потрібен, якщо QueryType встановлений в adSchemaProviderSpecific(-1); інакше цей параметр не використовується.

Клас _ConnectionPtr управляє інформацією, необхідною для підключення до постачальника джерела даних і дозволяє відкрити активне з'єднання з ним за допомогою методів Open і Close. Крім того, є можливість створювати транзакції і керувати ними: BeginTrans, CommitTrans і RollbackTrans. Для запуску транзакції викликається BeginTrans, в результаті чого всі зміни бази даних за допомогою цього з'єднання будуть розглядатися як єдина сутність. По завершенню змін бази даних необхідно викликати CommitTrans, щоб зберегти всі зміни в базі даних. Для скасування всіх змін, що відносяться до транзакції, треба викликати функцію RollbackTrans.

На закінчення, через метод Execute можна виконувати команди над джерелом даних.

Властивості ConnectionString, Provider, DefaultDatabase, ConnectionTimeout і Mode вказують, як і яким чином слід підключатися до постачальника джерела даних.

Приклад використання об'єкта Connection.

.............................................................

_ConnectionPtr pConn;

pConn.CreateInstance("ADODB.Connection");

pConn->ConnectionTimeout = 120;

pConn->Mode = adModeRead | adModeShareExclusive;

pConn->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\\VCCP\\ADO\\NWIND.MDB;", "Admin", "", 0);

.............................................................

pConn->Close();

.............................................................

У даному прикладі, за допомогою функції CreateInstance() створюється об'єкт Connection. Потім задається максимальний час на з'єднання з джерелом даних у мілісекундах. Після цього встановлюється властивість Mode (режими доступу для з'єднання), значення якого свідчить про те, що база відкривається тільки для читання, і в цей час жоден з користувачів не має доступу до цієї бази (див. табл . 10.1).

Після створення екземпляра класу Connection необхідно викликати його метод Open для підключення до джерела даних. Метод Open отримує чотири параметри (див. табл. 10.2): рядок з'єднання, ідентифікатор користувача, пароль і параметр Options, який вказує як буде здійснюватися з'єднання - синхронно (adConnectUnspecified - за замовчуванням) або асинхронно (adAsyncConnect). Значення adConnectUnspecified задає синхронне з'єднання, яке завжди чекає результат останнього запиту, значення adAsyncConnect задає асинхронне з'єднання, при якому нові запити виконуються, не чекаючи відповідей від попередніх запитів.

Рядок підключення може містити одне або кілька значень ключових параметрів, розділених «;». У нашому прикладі (рядок підключення "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\\VCCP\\ADO\\NWIND.MDB;") використовуються ключові параметри Provider та DataSource. Ключовому параметру Provider відповідає значення провайдера OLEDB, ключовому параметру DataSource - ім'я джерела даних у вигляді маршруту до бази даних nwind.mdb. При використанні ODBC ключові слова провайдера і джерела даних мають інші значення. Наприклад, рядок підключення для ODBC може бути наступним:

pConn->("DRIVER=Driver do Microsoft Access (*.mdb); DBQ=D:\__Ado\ado_otl\NWIND.MDB","admin","",0);

Доцільно при використанні ODBC у рядку підключення використовувати DSN. Наприклад,

pConn->Open("DSN=nwind","admin","",0);

По завершенню роботи з об'єктом Connection необхідно закрити з'єднання, викликавши його метод Close(). При цьому також закриються всі об'єкти ADO, що використовують дане з'єднання, такі як Recordset і Command. Як видно з наступного прикладу, метод Close() не залежить ні від яких параметрів:

pConn->Close();

У роботі з об'єктом Connection як і з іншими об'єктами ADO використовуються виняткові ситуації на основі об'єкту класу _com_error, де найбільш часто використовуються властивості, що визначають інформацію про помилку:

- Description - містить текстовий опис помилки, який можна відображати для користувача;

- Source - повертає рядок, що містить ім'я компонента, згенерувавшого помилку, наприклад ADODB.Connection або SQL Server;

- ErrorMessage - текстове повідомлення з вказівкою номера помилки.

Приклад обробки виняткових ситуацій.

try

{

< виконання методів і властивостей об’єктів ADO >

(наприклад, pConn->Close())

}

catch(_com_error &ce)

{

CString err="";

err+=ce.Description();

err+="\n";

err+="Source: ";

err+=ce.Source();

err+="\n";

err+=ce.ErrorMessage();

MessageBox(err,"Увага, помилка!!!",

MB_ICONINFORMATION);

}

Приклад роботи з транзакціями.

try

{

pConn->BeginTrans();

pConn->Execute((_bstr_t) "Delete otl_tab where id>100",

0, adCmdUnknown);

pConn->CommitTrans();

}

сatch (_com_error &ce)

{

CString err="";

err+=ce.Description();

err+="\n";

err+="Source: ";

err+=ce.Source();

err+="\n";

err+=ce.ErrorMessage();

MessageBox(err,"Увага, помилка!!!",

MB_ICONINFORMATION);

pConn->RollbackTrans();

}

У даному прикладі приведена робота з транзакціями.

Транзакції дозволяють виконати декілька різних операцій над базою даних як єдину операцію. Це дуже корисно, якщо доводиться одночасно модифікувати дані декількох таблиць. Крім того, транзакції дозволяють уникнути небажаного ефекту незавершених операцій, що власне і використовується в даному прикладі. Якби виконувався метод Execute без використання транзакції, то управління відразу ж після цього методу передавалося б іншим операторам програми по роботі з БД, у той час як виконання команди над базою даних (яка генерувалася методом Execute) ще не завершено. Транзакція виключає цю ситуацію, оскільки аналізує результат завершення команди.

Щоб почати транзакцію для деякого з'єднання, викликається метод BeginTrans(), що не залежить від параметрів. Потім можна вносити будь-які зміни до джерела даних, які становлять транзакцію.

Якщо всі операції були виконані успішно, і необхідно зберегти всі зміни в базі даних, потрібно викликати метод CommitTrans() класу _ConnectionPtr. Якщо сталася помилка або користувач передумав вносити зміни, необхідно викликати метод RollbackTrans(), який скасовує всі зміни, внесені з моменту виклику методу BeginTrans().

УВАГА !!! Транзакція працює тільки з командами в синхронному режимі. Рекомендується при роботі з SQL-запитами на виконання (видалення, оновлення, додавання даних і т. д.) використовувати транзакцію, так як вона контролює завершення операції.

Метод Execute об'єкта Connection містить три параметри:

- текст команди. Зазвичай перший параметр представляє собою команду SQL;

- містить кількість рядків, на які поширюються дії команди (даний параметр працює не при всіх з'єднаннях, тому рекомендуємо ставити нульове значення);

- значення третього параметра, що визначає тип команди наводиться в табл. 10.2.

Рекомендується метод Execute використовувати для SQL-запитів на виконання, тобто всі SQL-запити без запитів на вибірку. При цьому в якості 3-го параметра використовується adCmdText. Запит на вибірку доцільно формувати з використанням об'єкта Recordset, який містить значно більше параметрів управління набором даних, наприклад редагування бази даних через набір Recordset. Ця та багато інших можливостей відсутні при використанні методу Execute. Крім запитів на вибірку, виконання інших SQL-запитів з БД доцільно виконувати в об'єкті Connection з використанням методу Execute.

При виникненні помилки із транзакцією дається повідомлення про помилку, і управління передається методу RollbackTrans() об'єкта Connection для відкату транзакції.

ОСОБЛИВОСТІ РОБОТИ З ОБ'ЄКТОМ CONNECTION!!! При роботі з об'єктом Connection можна використовувати синхронний або асинхронний режими підключення і команди (за замовчуванням синхронний режим). Під час синхронного режиму завжди очікується результат останнього запиту, під час асинхронного - нові запити виконуються, не чекаючи відповідей попередніх запитів.

В об'єкті Connection підтримуються транзакції, які контролюють завершення синхронних операцій. Тобто, кожна наступна операція в межах транзакції очікує виконання попередньої. Транзакції доцільно використовувати при роботі з SQL-запитами на виконання дій з БД, а також при внесенні декількох послідовних змін даних. Причому, у разі збою при будь-якій із цих змін потрібно скасувати її, і всі попередні зміни транзакції. Класичний приклад транзакції - переказ грошей в банку з одного рахунку на інший. Так, якщо зробити зняття грошей з одного рахунку і не перевести на інший, потрібно буде скасувати операцію, інакше сума просто пропаде.

В об'єкті Connection має місце властивість CursorLocation, яку необхідно поставити до відкриття з'єднання. Дана властивість успадковується всіма об'єктами Recordset, створеними за допомогою методу Execute об'єкта Connection і вказує, де необхідно відкрити курсор: на стороні клієнта або сервера. За замовчуванням всі курсори відкриваються на стороні сервера.

При створенні об'єкта Recordset за допомогою методу Execute об'єкта Connection курсор буде створений тільки для читання, і його можна прокручувати тільки зверху-вниз (forward-only). Рекомендується метод Execute використовувати для роботи з командами - SQL-запити на виконання за винятком SQL-запитів на вибірку. Для більш повної роботи з набором його потрібно створювати, використовуючи метод Open об'єкту Recordset.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]