Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
практичні 2012.doc
Скачиваний:
13
Добавлен:
25.11.2019
Размер:
4 Мб
Скачать
☆

Порядок виконання роботи

  1. У вікні бази даних вибираємо об'єкт Macros.

  2. На панелі інструментів вікна бази даних натискаємо кнопку створення нового макросу New.

  3. Формуємо вертикальне меню.

  4. На основі вертикального меню створюємо горизонтальне меню.

  5. Активізуємо користувацьке меню.

  6. Тепер при відкритті створеної бази даних у середовищі СКБД MS ACCESS замість головного меню відображатиметься користувацьке меню.

Контрольні запитання

1. Що таке макрос?

2. Які ви знаєте види макросів?

3. Перелічіть способи створення макросів.

4. Назвіть макрокоманди і їх призначення.

5. Перелічіть функції користувацького меню.

Студенти повинні

знати:

  • Призначення макросу.

  • Способи створення макросів.

  • Макрокоманди.

  • Події та їх використання.

  • Призначення користувацького меню.

  • Секрети створення користувацького меню.

вміти:

  • Створювати макроси відомими способами.

  • Використовувати макрокоманди при створенні макросів.

  • Використовувати події при створенні макросів.

  • Створювати користувацьке меню.

Завдання

  1. У практичній роботі необхідно розробити проект структури та призначення елементів користувацького меню, у якому врахувати основні функції інформаційної системи, а саме: відображення та опрацювання таблиць; вибір даних за допомогою запитів; вивід вихідних документів, тощо; інші функції роботи з базою даних.

  2. Побудувати набір макросів, які реалізують спроектований інтерфейс у вигляді горизонтального основного меню та множини вертикальних підпорядкованих меню.

  3. Побудувати необхідні зв’язки та посилання між макросами.

  4. Описати механізм активізації користувацького меню.

Практична робота №11 Підключення баз даних до програм розроблених в Delphi

Мета роботи: Вивчення порядку, методів та засобів підключення БД до програм, розроблених в Delphi.

Теоретичні відомості

Використання ADO засобами Delphi

Разом з традіційними інструментами доступу до даних Borland Database Engine і ODBC в додатках Delphi можна застосовуваті технологію Microsoft ACTIVEX Data Objects (ADO), яка заснована на можливостях СОМ, а саме інтерфейсів OLE DB.

Технологія ADO завоювала популярність в розробників, завдяки універсальності — базовій набір інтерфейсів OLE DB є у кожній сучасній операційній системі Microsoft. Тому для забезпечення доступу додатка до даних досить лише правильно вказати провайдер з'єднання ADO і потім переносити програму на будь-який комп'ютер, де є необхідна база даних і, звичайно, встановлено ADO.

У палітрі компонентів Delphi є сторінка ADO, що містить набір компонентів, що дозволяють створювати повноцінні додатки БД, що звертаються до даних через ADO.

У цій практичній роботі розглядаються наступні питання:

  •  короткий огляд технології ADO, доступних провайдерів ADO, а також об'єктів, що працюють в ній, і інтерфейсів;

  •  як створити з'єднання з базою даних через ADO в додатку Delphi;

  •  вживання об'єкту набору записів ADO в додатку;

  •  як використовувати таблиці, запити SQL і процедури, що зберігаються;

  •  що таке команди і об'єкти команди ADO.

Основи ADO

Технологія Microsoft ACTIVEX Data Objects забезпечує універсальний доступ до джерел даних з додатків БД. Таку можливість надають функції набору інтерфейсів, створені на основі загальної моделі об'єктів СОМ і описані в специфікації OLE DB.

Технологія ADO та інтерфейси OLE DB забезпечують для додатків єдиний спосіб доступу до джерел даних різних типів. Наприклад, додаток, використовуючи ADO, може застосовувати однаково складні операції і до даних, що зберігаються на корпоративному сервері SQL, і до електронних таблиць, і локальних СУБД. Запит SQL, направлений будь-якому джерелу даних через ADO, буде виконаний.

Виникає питання: яким чином джерела даних зможуть виконати цей запит?

За сервери БД турбуватися не варто, обробка запитів SQL — це їх основний обов'язок. Але як бути з файловими послідовностями, електронними таблицями, файлами електронної пошти і т. д.? Тут на допомогу приходять механізми ADO і інтерфейси OLE DB.

OLE DB є набором спеціалізованих об'єктів СОМ, що інкапсулюють стандартні функції обробки даних, і спеціалізовані функції конкретних джерел даних і інтерфейсів, що забезпечують передачу даних між об'єктами.

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

Об'єкти OLE DB створюються і функціонують так само, як і інші об'єкти СОМ. Кожному об'єкту відповідає ідентифікатор класу CLSID, що зберігається в системному реєстрі. Для створення об'єкту використовується метод Cocreateinstance і відповідна фабрика класу. Об'єкту відповідає набір інтерфейсів, до методів яких можна звертатися після створення об'єкту.

В результаті додаток звертається не прямо до джерела даних, а до об'єкту OLE DB, який "вміє" представити дані (наприклад, з файлу електронної пошти) у вигляді таблиці БД або результату виконання запиту SQL.

Технологія ADO в цілому включає не лише самі об'єкти OLE DB, але і механізми, що забезпечують взаємодію об'єктів з даними і додатками. На цьому рівні найважливішу роль грають провайдери ADO, що координують роботу додатків з сховищами даних різних типів.

Така архітектура дозволяє зробити набір об'єктів та інтерфейсів відкритим і розширюваним. Набір об'єктів і відповідний провайдер може бути створений для будь-якого сховища даних без внесення змін у вихідну структуру ADO. При цьому істотно розширюється само поняття даних — адже можна розробити набір об'єктів та інтерфейсів і для нетрадиційних табличних даних. Наприклад, це можуть бути графічні дані геоінформаційних систем, деревовидні структури з системних реєстрів, дані CASE-інструментів і так далі

Специфікація OLE DB розрізняє наступні типи об'єктів, які будуть розглянуті нижче.

  •  Нумератор (Enumerator) виконує пошук джерел даних або інших нумераторів. Використовується для забезпечення функціонування провайдерів ADO.

  •  Об'єкт-джерело даних (Data Source Object) представляє сховище даних.

  •  Сесія (Session) об'єднує сукупність об'єктів, що звертаються до одного сховища даних.

  •  Транзакція (Trasaction) інкапсулює механізм виконання транзакції.

  •  Команда (Command) містить текст команди і забезпечує її виконання. Командою може бути запит SQL, звернення до таблиці БД і так далі

  •  Набір рядків (Rowset) є сукупністю рядків даних, що є результатом виконання команди ADO.

  •  Об'єкт-помилка (Error) містить інформацію про виняткову ситуацію.

Розглянемо функціональні можливості основних об'єктів і інтерфейсів OLE DB.

Нумератори

Об'екти- нумератори забезпечують пошук будь-яких об'єктів ADO, які мають доступ до джерел даних. При цьому інші нумератори також видно в даному нумераторі. Первинний пошук джерел даних здійснюється в провайдерові ADO. Нумератори можуть відбирати лише джерела даних конкретних типів, тому провайдер забезпечує доступ до конкретного типа сховища даних. У складі ADO є системний кореневий нумератор, який виконує початковий пошук інших нумераторів і джерел даних. Його можна використовувати, знаючи його ідентифікатор класу Clsid_oledb_enumerator.

У Delphi GUID глобального нумератора міститься у файлі \Delphi7\Source \Vcl\OleDB.pas.

Clsid_oledb_enrjmerator: Tguid= '{C8b522do-5cf3-11ce-ade5-ooaa0044773d}

Функції нумератора містяться в інтерфейсі isourcesrowset. Метод

function Getsourcesrowset(const punkouter: lunknown; const riid: TGUID; cpropertysets: UINT; rgproperties: Pdbpropsetarray; out ppsourcesrowset: lunknown): Hresult; stdcall;

повертає заслання на об'єкт набору рядів (див. вищий), що містить зведення про знайдені джерела даних або нумераторах.

Об'єкти з'єднання з джерелами даних

Внутрішній механізм ADO, що забезпечує з'єднання з сховищем даних, використовує два типи об'єктів. Це об'єкти-джерела даних і об'єкти-сесії. Об'єкт-джерело даних забезпечує уявлення інформації про необхідне реальне джерело даних і підключення до нього. Для введення відомостей про сховище даних використовується інтерфейс idbproperties. Для успішного підключення необхідно задати обов'язкові відомості. Ймовірно, для будь-якого сховища даних буде актуальною інформація про його ім'я, користувача і пароль. Проте кожен тип сховища має власні унікальні налаштування. Для здобуття списку всіх обов'язкових параметрів з'єднання з даним сховищем можна скористатися методом

function Getpropertylnfo(cpropertyldsets: UINT; rgpropertyldsets: Pdbpropidsetarray; var pcpropertylnfosets: UINT; out prgpropertylnfosets: Pdbpropinfoset; ppdescbuffer: Ppolestr): Hresult; stdcall; який повертає заповнену структуру DBPROPINFO.

Pdbpropinfo = ^TDBPropInfo;

 DBPROPINFO = packed record

pwszdescription: Pwidechar;

dwpropertyld: DBPROPID;

dwflags: DBPROPFLAGS;

vttype: Word;

vvalues: Olevariant;

end; 

Tdbpropinfo = DBPROPINFO;

Для кожного обов'язкового параметра в елементі dwflags встановлюється значення Dbpropflags_required. Для ініціалізації з'єднання необхідно використовувати метод

function Initialize: Hresult; stdcall;

інтерфейсу idbinitiaiize об'єкту-джерела даних.

Сесія

З об'єкту-джерела даних можна створювати об'єкти-сесії. Для цього використовується метод

function Createsession(const punkouter: lunknown; const riid: TGUID; out ppdbsession: lunknown}: Hresult; stdcall;

інтерфейсу idbcreatesession. Сесія призначена для забезпечення роботи транзакцій і набору рядів.

Транзакції

Управління транзакціями в OLE DB реалізоване на двох рівнях. По-перше, всіма необхідними методами володіє об'єкт сесії. Він має інтерфейси Itransaction, Itransactionjoin, Itransactionlocal, Itransactionobject. Усередині сесії транзакція керується інтерфейсами Itransactionlocal, ITRANSACTIONSC, Itransaction і їх методами Starttransaction, Commit, Rollback. По-друге, для об'єкту сесії можна створити об'єкт транзакції за допомогою методу

function Gettransactionobject(ultransactionlevel: UINT; out pptransactionobject: Itransaction): Hresult; stdcall;

інтерфейсу Itransactionobjectякий повертає заслання на інтерфейс об'єкту-транзакції.

Набір рядків

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

Об'єкт сесії має обов'язковий інтерфейс IOpenrowset з методом

function Openrowset(const punkouter: lunknown; ptableld: PDBID; plndexid: PDBID; const riid: TGUID; cpropertysets: UINT; rgpropertysets: Pdbpropsetarray; pprowset: Plunknown): Hresult; stdcall;

який відкриває необхідний набір рядів.

Залежно від можливостей джерела даних набір рядів може підтримувати різні інтерфейси. Але п'ять з них є обов'язковими:

  • Irowset — забезпечує навігацію по рядах;

  • Iaccessor — забезпечує уявлення інформації про формат рядів, що містяться в буфері набору рядів;

  • Irowsetinfo — дозволяє отримати інформацію про набори рядів (наприклад, число рядів або число оновлених рядів);

  • Icoiumnsinfo — дозволяє отримати інформацію про колонки рядів (найменування, тип даних, можливість оновлення і т. д.);

  •  Iconverttype — містить єдиний метод canconvert, що дозволяє визначити можливість перетворення типів даних в наборі рядів.

Додаткові можливості по керуванню набором рядків надають наступні інтерфейси:

  •  Irowsetchange — виконує зміни в наборі рядів (вносить зміни, додає нові ряди, видаляє ряди і т. д.);

  •  Irowsetidentity — дозволяє порівнювати ряди різних рядів;

  •  Irowsetindex — забезпечує використання індексів;

  •  Irowsetlocate — виконує пошук в наборі рядів;

  •  Irowsetupdate — реалізує механізм кешування змін.

Команди

Програмні засоби ADO були б неповними, якби не мали можливості використовувати для роботи з даними мову SQL. Оператори DML і DDL, ряд спеціальних операторів ADO носять загальну назву текстових команд. Об'єкт-команда інкапсулює саму текстову команду і механізм обробки і передачі команди. Об'єкт команди виконує наступні операції:

  •  пов'язання команди з джерелом даних;

  •  оптимізацію команди;

  • передачу команди джерелу даних.

Головний інтерфейс об'єкту команди icommand має три методи:

  •  function Cancel: Hresult; stdcall; - відміняє виконання команди;

  •  function Execute(const punkouter: lunknown; const riid: TGUID; var pparams: DBPARAMS; pcrowsaffected: Pinteger; pprowset: Plunknown): Hresult; stdcall; - виконує команду;

  •  function Getdbsession(const riid: TGUID; out ppsession: lunknown): Hresult; stdcall; - повертає заслання на інтерфейс сесії, що викликав дану команду.

Окрім основного, об'єкт команди забезпечує доступ до додаткових інтерфейсів:

  •  Icommandprepare — містить два методи (Prepare і Unprepare) для підготовки команди;

  •  icommandproperties — задає для команди властивості, які повинні підтримуватися повертаним командою набором даних;

  •  icommandtext — управляє текстом команди (цей інтерфейс обов'язковий для об'єкту команди);

  •  icommandwithparameters — забезпечує роботу з параметрами команди.

Провайдери ADO

Провайдери ADO забезпечують з'єднання додатка, що використовує дані через ADO, з джерелом даних (сервером SQL, локальною СКБД, файловою системою і т. д.). Для кожного типу сховища даних повинен існувати провайдер ADO. Провайдер "знає" про місце розташування сховища даних і його вміст, уміє звертатися до даних із запитами і інтерпретувати повертану службову інформацію і результати запитів з метою їх передачі додатку. Список встановлених в даній операційній системі провайдерів доступний для вибору при установці з'єднання через компонент Tadoconnection.

При інсталяції Microsoft ACTIVEX Data Objects в операційній системі встановлюються наступні стандартні провайдери.

  •  Microsoft Jet OLE DB Provider забезпечує з'єднання з даними СУБД Access за посередництва технології ВАТ.

  •  Microsoft OLE DB Provider for Microsoft Indexing Service забезпечує доступ лише для читання до файлів і Internet-ресурсам Microsoft Indexing Service.

  •  Microsoft OLE DB Provider for Microsoft Active Directory Service забезпечує доступ до ресурсів служби каталогів (Active Directory Service).

  •  Microsoft OLE DB Provider for Internet Publishing дозволяє використовувати ресурси, Microsoft Frontpage, що надаються, Microsoft Internet Information Server, HTTP-файлы.

  •  Microsoft Data Shaping Service for OLE DB дозволяє використовувати ієрархічні набори даних.

  •  Microsoft OLE DB Simple Provider призначений для організації доступу до джерел даних, що підтримують лише базисні можливості OLE DB.

  •  Microsoft OLE DB Provider for ODBC drivers забезпечує доступ до даних, які вже "прописані" за допомогою драйверів ODBC. Проте реальне використання настільки екзотичних варіантів з'єднань представляється проблематичним. Драйвери ODBC і так славляться своєю повільністю, тому додатковий шар сервісів тут ні до чого.

  •  Microsoft OLE DB Provider for Oracle забезпечує з'єднання з сервером Oracle.

  •  Microsoft OLE DB Provider for SQL Server забезпечує з'єднання з сервером Microsoft SQL Server.

Реалізація ADO в Delphi

Механізм доступу до даних через ADO і багаточисельні об'єкти і інтерфейси реалізовані в VCL Delphi у вигляді набору компонентів, розташованих на сторінці ADO. Всі необхідні інтерфейси, що забезпечують роботу компонентів, оголошені і описані у файлах OLEDB.pas і ADODB.pas у теці \Delphi7\Source\Vcl.

Компоненти ADO

Компонент Tadoconnection увібрав можливості нумератора, джерела даних і сесії з можливостями обслуговування транзакцій. Текстові команди ADO реалізовані в компоненте Tadocommand. Набори рядків (нотація Microsoft) можна отримати за допомогою компонентів Tadotable, Tadoquery, Taoostoredproc. Кожен з них реалізує спосіб доступу до конкретного типа представлення даних в сховищі. Далі по тексту, стосовно компонентам Delphi, сукупність повертаних з сховища даних рядків називатимемо набором записів, що відповідає документації Inprise (див. www.borland.com або www.borland.ru) і стилю викладу попередніх глав. Набір властивостей і методів компонентів ADO забезпечує реалізацію всіх необхідних додатку БД функцій. Способи використання компонентів ADO мало чим відрізняються від стандартних компонентів VCL доступу до даних.

Механізм з'єднання з сховищем даних ADO

Компоненти доступу до даних ADO можуть використовувати два варіанти підключення до сховища даних. Це стандартний метод ADO і стандартний метод Delphi. У першому випадку компоненти використовують властивість connectionstring для прямого звернення до сховища даних. У другому випадку використовується спеціальний компонент Tadoconnection, який забезпечує розширене управління з'єднанням і дозволяє звертатися до даних декільком компонентам одночасно.

Властивість connectionstring призначено для зберігання інформації про з'єднання з об'єктом ADO. У нім через крапку з комою перераховуються всі необхідні параметри. Як мінімум, це мають бути імена провайдера з'єднання або віддаленого сервера:

Connectionstring:='remote Server=servername;Provider=ProviderName';

 При необхідності вказуються шлях до віддаленого провайдера:

Connectionstring:='remote Provider=providername';

і параметри, необхідні провайдерові:

'User Name=user_name;Password=Password';

Кожен компонент, що звертається до сховища даних ADO самостійно, задаючи параметри з'єднання у властивості Connectionstring відкриває власне з'єднання. Чим більше додаток містить компонентів ADO, тим більше з'єднань може бути відкриті одночасно.

Тому доцільно реалізувати механізм з'єднання ADO через спеціальний компонент — Tadoconnection. Цей компонент відкриває з'єднання, також задане властивістю Connectionstring (див. вищий)і надає розробникові додаткові засоби управління з'єднанням.

Компоненти, що працюють з сховищем даних ADO через дане з'єднання, підключаються до компонента Tadoconnection за допомогою властивості

property Connection: Tadoconnection;

яке має кожен компонент, що інкапсулює набір даних ADO.

  Компонент Tadoconnection

Компонент Tadoconnection призначений для управління з'єднанням з об'єктами сховища даних ADO. Він забезпечує доступ до сховища даних компонентам ADO, що інкапсулюють набір даних. Вживання цього компонента дає розробникові ряд переваг:

  •  всі компоненти доступу до даних ADO звертаються до сховища даних через одне з'єднання;

  •  можливість безпосередньо задати об'єкт провайдера з'єднання;

  •  доступ до об'єкту з'єднання ADO;

  •  можливість виконувати команди ADO;

  •  виконання транзакцій;

  •  розширене управління з'єднанням за допомогою методів-обробників подій.

Налаштування з'єднання

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

property Connectionstring: Widestring;

Додамо лише, що набір параметрів змінюється залежно від типу провайдера і може набудовуватися як вручну, так і за допомогою спеціального редактора параметрів з'єднання, який викликається подвійним клацанням на компоненті Tadoconnection перенесеним на форму, або клацанням на кнопці в полі редагування властивості Connectionstring у Інспекторові об'єктів (мал. 1).

Мал. 1.Редактор налаштування з'єднання ADO

Тут можна набудувати з'єднання через властивість Connectionstring (радіокнопка Use Connection String) або завантажити параметри з'єднання з файлу з розширенням udl (радіокнопка Use Data Link File).

Файл UDL (лістинг 1) є звичайним текстовим файлом, в якому вказується назва параметра і через знак рівності його значення. Параметри розділяються крапкою з комою.

Лістинг 1  Демонстраційний файл DBDEMOS.UDL

[oledb]

Everything after this line is an OLE DB initstring

Provider=microsoft.Jet.OLEDB.4.0;Data Source=c:\program Files\common Files\borland Shared\data\dbdemos.mdb

Якщо файл параметрів з'єднання відсутній, налаштування доведеться здійснювати вручну. Для цього слід натискувати кнопку Build. У результаті з'являється діалогове вікно Data Link Properties у якому можна набудувати параметри з'єднання вручну. Воно є чотирьохсторінковим блокнотом, етап, що дозволяє вам, за етапом задати всі необхідні параметри (мал. 2).

Мал. 2. Діалогове вікно налаштування параметрів з'єднання на сторінці вибору провайдера

Перша сторінка Provider дозволяє вибрати провайдер OLE DB для конкретного типу джерела даних з числа провайдерів, встановлених в системі. Тут ви бачите провайдери не лише для серверів БД, але і служб, встановлених в операційній системі. Склад елементів управління наступних сторінок залежить від типу джерела даних, але розрізняється не так вже сильно. Далі практично скрізь необхідно задати джерело даних (ім'я сервера, базу даних, файл і т. д.), режим аутентифікації користувача, а також визначити ім'я і пароль користувача.

Розглянемо процес налаштування на прикладі провайдера OLE DB для сервера Microsoft SQL Server.

Мал. 3. Діалогове вікно налаштування параметрів з'єднання на сторінці вибору джерела даних

Наступна сторінка Connection (мал. 3) набудовує джерело даних.

На першому етапі потрібно вибрати ім'я сервера з доступних для даного комп'ютера.

Другий етап визначає режим аутентифікації користувача. Це або система безпеки Windows, або власна система аутентифікації сервера. Тут же треба визначити ім'я і пароль користувача.

Третій етап призначений для вибору бази даних сервера.

Після закінчення налаштування джерела даних ви можете перевірити з'єднання, натискує кнопку Test Connection.

Тепер перейдемо на наступну сторінку.

Сторінка Advanced (мал. 4) задає додаткові параметри з'єднання. Залежно від типу сховища даних деякі елементи цієї сторінки можуть бути недоступні.

Мал. 4. Діалогове вікно налаштування параметрів з'єднання на сторінці додаткових параметрів.

Список Impersonation level визначає можливості клієнтів при підключенні відповідно до повноважень їх ролей. У списку можуть бути вибрані наступні значення:

  •  Anonymous — роль клієнта недоступна серверу;

  •  Identify — роль клієнта пізнається сервером, але доступ до системних об'єктів заблокований;

  •  Impersonate — процес сервера може бути представлений захищеним контекстом клієнта;

  •  Delegate — процес сервера може бути представлений захищеним контекстом клієнта, при цьому сервер може здійснювати інші підключення.

Список Protection level дозволяє задати рівень захисту даних. У списку можуть бути вибрані наступні значення:

  •  None — підтвердження не потрібне;

  •  Connect — підтвердження необхідне лише при підключенні; 

  •   Call — підтвердження джерела даних при кожному запиті; 

  •  Pkt — підтвердження здобуття від клієнта всіх даних;

  •  Pkt Integrity — підтвердження здобуття від клієнта всіх даних з дотриманням цілісності;

  •  Pkt Privacy — підтвердження здобуття від клієнта всіх даних з дотриманням цілісності і захист шифруванням.

У полі Connect timeout можна задати час чекання з'єднання в секундах. Після закінчення цього часу процес уривається.

При необхідності список Access permissions задає права доступу до окремих видів виконуваних операцій. У списку можна вибрати наступні значення:

  • Read — лише читання;

  • Readwrite — читання і запис;

  •  Share Deny None — повний доступ всім на читання і запис;

  •   Share Deny Read — читання заборонене всім;

  •  Share Deny Write — запис заборонений всім;

  •  Share Exclusive — читання і запис заборонена всім;

  •  Write — лише запис.

Остання сторінка All (мал.5) дозволяє проглянути і при необхідності змінити всі зроблені налаштування (для цього призначена кнопка Edit Value) для вибраного провайдера.

Мал. 5. Діалогове вікно налаштування параметрів з'єднання на сторінці перегляду налаштувань

Після підтвердження зроблених в діалозі налаштувань з них формується значення властивості Connectionstring.

Управління з'єднанням

З'єднання з сховищем даних ADO відкривається і закривається за допомогою властивості

property Connected: Boolean;

або методів

procedure Open; overload;

procedure Openfconst USERLD: Widestring; const Password: Widestring); overload;

і

procedure Close;

Метод open є перенавантажуваним при необхідності використання видаленого або локального з'єднання. Для видаленого з'єднання застосовується варіант з параметрами USERID і Password. До і після відкриття і закриття з'єднання розробник може використовувати відповідні стандартні методи-обробники подій:

property Beforeconnect: Tnotifyevent;

property Beforedisconnect: Tnotifyevent; 

property Afterconnect: Tnotifyevent; 

property Afterdisconnect: Tnotifyevent;

Окрім цього, компонент Tadoconnection має додаткові методи-обробники. Після здобуття підтвердження від провайдера про те, що з'єднання буде відкрито, перед його реальним відкриттям викликається метод

Twillconnectevent = procedure(Connection: Tadoconnection; var Connectionstring, USERLD, Password: Widestring; var Connectoptions: Tconnectoption; 

var Eventstatus: Teventstatus) of object;

 property Onwillconnect: Twillconnectevent;

Параметр Connection містить покажчик на опрацювання компонент, що викликані.

Параметри Connectionstring, userid і Password визначають рядок параметрів, ім'я і пароль користувача. З'єднання може бути синхронним або асинхронним, що і визначається параметром Connectoptions типа Tconnectoption:

type Tconnectoption = (coconnectunspecified, coasyncconnect);

coconnectunspecified — синхронне з'єднання завжди чекає результат останнього запиту;

coasyncconnect — асинхронне з'єднання може виконувати нові запити, не чекаючи відповіді від попередніх запитів.

Нарешті, параметр Eventstatus дозволяє визначити успішність виконання посланого запиту на з'єднання:

type

Teventstatus = (esok, eserrorsoccured, escantdeny, escancel, esunwantedevent);

esok — запит на з'єднання виконаний успішно;

eserrorsoccured — в процесі виконання запиту виникла помилка;

escantdeny — з'єднання не може бути перерване;

escancel — з'єднання було перерване до відкриття;

esunwantedevent — внутрішній прапор ADO.

Наприклад, в разі успішного з'єднання можна вибрати синхронний режим роботи компонента:

procedure Tforml.ADOConnectionWillConnect(Connection: Tadoconnection;

 var Connectionstring, USERLD, Password: Widestring;

 var Connectoptions: Tconnectoption;

 var Eventstatus: Teventstatus); 

begin if Eventstatus = esok

then Connectoptions := coconnectunspecified; 

end;

До речі, параметр синхронності/асинхронності можна також задати за допомогою властивості

Connectoptions property Connectoptions: Tconnectoption;

Після відкриття з'єднання для виконання власної коди можна використовувати метод-обробник

Tconnecterrorevent = procedure(Connection:

  Tadoconnection; Error: Error;

 var Eventstatus: Teventstatus) of object; 

property Onconnectcomplete: Tconnecterrorevent;

Тут, якщо в процесі відкриття з'єднання виникла помилка, параметр Eventstatus буде рівний eserrorsoccuredа параметр Error містить об'єкт помилки ADO. Тепер перейдемо до допоміжних властивостей і методів компонента Tadoconnectionщо забезпечує з'єднання. Для обмеження часу відкриття з'єднання для повільних каналів зв'язку використовується властивість

property Connectiontimeout: Integer;

задаючий час чекання відкриття з'єднання в секундах. За умовчанням воно рівне 15 сек.

Також можна визначити реакцію компонента на невживане з'єднання. Якщо через з'єднання не підключений жоден активний компонент, властивість

property Keepconnection: Boolean;

у значенні True зберігає з'єднання відкритим. Інакше, після закриття останнього зв'язаного компонента ADO, з'єднання закривається. При необхідності провайдер з'єднання ADO визначається безпосередньо властивістю

property Provider: Widestring;

Ім'я джерела даних за умовчанням задається властивістю

property Defaultdatabase: Widestring;

Але якщо цей же параметр вказаний в рядку з'єднання, то він перекриває собою значення властивості. При необхідності прямий доступ до об'єкту з'єднання OLE DB забезпечує властивість

property Connectionobject: _connection;

При відкритті з'єднання необхідно вводити ім'я користувача і його пароль. Поява стандартного діалогу керується властивістю property Loginprompt: Boolean;

Без цього діалогу для завдання даних параметрів можна використовувати властивість Connectionstringметод open або метод-обробник

type Tloginevent = procedure(Sender:tobject; 

Username, Password: string)

of object;

property Onlogin: Tloginevent;

Властивість

type Tconnectmode = (cmunknown, cmread, cmwrite, cinreadwrite, cmsharedenyread, cmsharedenywrite, cmshareexclusive, cmsharedenynone);

 property Mode: Tconnectmode;

задає доступні для з'єднання операції:

  • cmunknown — дозвіл невідомий або не може бути встановлено;

  • cmread — дозвіл на читання;

  • cmwrite — дозвіл на запис;

  • cmreadwrite — дозвіл на читання і запис;

  • cmsharedenyread — дозвіл на читання для інших з'єднань заборонений;

  • cmshareoenywrite — дозвіл на запис для інших з'єднань заборонений;

  • cmshareexciusive — дозвіл на відкриття для інших з'єднань заборонений;

  • cmsharedenynone — відкриття інших з'єднань з дозволами заборонене.

Доступ до зв'язаних наборів даних і команд ADO

Компонент Tadoconnection забезпечує доступ до всіх компонентам, які використовують його для доступу до сховища даних ADO. Всі відкриті таким чином набори даних доступні через індексовану властивість

property Datasets[Index: Integer]: Tcustomadodataset;

Кожен елемент цього списку містить дескриптор компонента доступу до даних ADO (тип Tcustomadodataset). Загальне число зв'язаних компонентів з наборами даних повертається властивістю

property Datasetcount: Integer;

Для цих компонентів можна централізований встановити типа використовуваного курсора за допомогою властивості

type Tcursorlocation = (cluseserver, cluseclient); property Cursorlocation: Tcursorlocation;

Значення cluseclient задає локальний курсор на стороні клієнта, що дозволяє виконувати будь-які операції з даними, у тому числі не підтримувані сервером. Значення ciuseserver задає курсор на сервері, який реалізує лише можливості сервера, але забезпечує швидку обробку великих масивів даних.

Наприклад:

for i := 0 to Adoconnection.DataSetCount — 1 do

 begin

if Adoconnection.DataSets[i].Active = True then Adoconnection.DataSets[i].Close;

Adoconnection.DataSets[i].CursorLocation := cluseclient; end;

Окрім наборів даних компонент Tadoconnection забезпечує виконання команд ADO. Команду ADO інкапсулює спеціальний компонент Tadocommandякий розглядається нижчим. Всі команди ADO, що працюють з сховищем даних через це з'єднання, доступні для управління через індексовану властивість

property Commands[Index: Integer]: Tadocommand

Кожен елемент цього списку є екземпляром класу Tadocommand. Загальне число доступних команд повертається властивістю property Commandcount: Integer

Наприклад, відразу після відкриття з'єднання можна виконати всі зв'язані команди ADO, реалізувавши таким чином щось начебто скрипта:

procedure Tforml.ADOConnectionConnectComplete(Connection: Tadoconnection; 

const Error: Error; var Eventstatus: Teventstatus); 

var i, Errorcnt: Integer;

 begin

if Eventstatus = esok then

for i := 0 to Adoconnection.CommandCount — 1 do

 try if Adoconnection.Commands[i].CommandText <> 

then Adoconnection.Commands[i].Execute; except

on E: Exception do Inc(Errorcnt);

  end;  end;

Проте компонент Tadoconnection може виконувати команди ADO самостійно, без допомоги інших компонентів. Для цього використовується перенавантажуваний метод

function Execute(const Commandtext: Widestring; Executeoptions:

Texecuteoptions = []): _recordset; overload;

procedure Execute(const Commandtext: Widestring; 

var Recordsaffected:

Integer; Executeoptions: Texecuteoptions = [eoexecutenorecords]);

overload;

Виконання команди здійснюється процедурою Execute (якщо команда не повертає набір записів) або однойменною функцією Execute (якщо команда повертає набір записів). Параметр commandtext повинен містити текст команди. Параметр Recordsaffected повертає число оброблених командою записів (якщо вони є). Параметр

type

Texecuteoption = (eoasyncexecute, eoasyncfetch, eoasyncfetchnonblocking, eoexecutenorecords);

Texecuteoptions = set of Texecuteoption;

задає умови виконання команди:

  •  eoasyncexecute — команда виконується асихронно (з'єднання не чекатиме закінчення виконання команди, а продовжить роботу, обробивши сигнал про завершення команди, коли він поступить);

  •  eoasyncfetch — команда отримує необхідні записи також асихронно;

  •  eoasyncfetchnonblocking — команда отримує необхідні записи також асихронно, але при цьому створена нитка не блокується;

  •  eoexecutenorecords — команда не повинна повертати запису.

Якщо джерело даних прийняло команду для виконання і повідомило про це з'єднання, викликається метод-обробник

Twillexecuteevent = procedure(Connection: Tadoconnection;

var Commandtext: Widestring; var Cursortype: Tcursortype; var Locktype:

Tadolocktype; var Executeoptions: Texecuteoptions;

 var Eventstatus:

Teventstatus; const Command: _command;

 const Recordset: _recordset)

of object;

property Onwillexecute: Twillexecuteevent;

Після виконання команди викликається метод-обробник

Texecutecompleteevent = procedure(Connection: Tadoconnection; Recordsaffected: Integer; 

const Error: Error; var Eventstatus: Teventstatus; 

const Command: _command;

 const Recordset: _recordset) of object;

 property Onexecutecomplete: Texecutecompleteevent;

Об'єкт помилок ADO

Всі помилки часу виконання, що виникають при відкритому з'єднанні, зберігаються в спеціальному об'єкті ADO, що інкапсулює колекцію повідомлень про помилки. Доступ до об'єкту можливий через властивість

property Errors: Errors;

Детальніше про об'єкт помилок ADO див. нижче.

Транзакції

Компонент Tadoconnection дозволяє виконувати транзакції. Методи

function Begintrans: Integer;

 procedure Committrans; 

procedure Rollbacktrans;

забезпечують початок, фіксацію і відкіт транзакції відповідно. Методи-обробники

Tbegintranscompleteevent = procedure(Connection: Tadoconnection;

Transactionlevel: Integer; 

const Error: Error; 

var Eventstatus:

Teventstatus) of object;

property Onbegintranscomplete: Tbegintranscompleteevent;

Tconnecterrorevent = procedure(Connection: Tadoconnection; 

Error: Error;

var Eventstatus: Teventstatus) of object;

property Oncornmittranscomplete: Tconnecterrorevent;

викликаються після початку і фіксації транзакції. Властивість

type Tisolationlevel = (ilunspecified, ilchaos, ilreaduncommitted, ilbrowse, ilcursorstability, ilreadcorranitted, ilrepeatableread, ilserializable, illsolated); 

property Isolationlevel: Tisolationlevel;

дозволяє задати рівень ізоляції транзакції:

  •  Ilunspecif led — рівень ізоляції не задається;

  • Iichaos — зміни захищеніших транзакцій не перезаписуються даною транзакцією;

  • Ilreaduncommitted — незафіксовані зміни інших транзакцій видимі;

  •  Ilbrowse — незафіксовані зміни інших транзакцій видимі;

  • Ilcursorstability — зміни інших транзакцій видимі лише після фіксації;

  •  Ilreadcommitted — зміни інших транзакцій видимі лише після фіксації;

  • Ilrepeatableread — зміни інших транзакцій не видимі, але доступні при оновленні даних;

  • Iserializable — транзакція виконується ізольовано від інших транзакцій;

  • Ilisolated — транзакція виконується ізольовано від інших транзакцій.

Властивість Txactattribute = (xacommitretaining, xaabortretaining); property Attributes: Txactattributes; задає спосіб управління транзакціями при їх фіксації і відкаті:

  •  xacommitretaining — після фіксації чергової транзакції автоматично починається виконання новою;

  •  xaabortretaining — після відкоту чергової транзакції автоматично починається виконання новою.

Набори даних ADO

На сторінці ADO Палітри компонентів Delphi, окрім компонентів з'єднання є стандартні компоненти, що інкапсулюють набір даних і адаптованих для роботи з сховищем даних ADO (мал. 6). Це компоненти:

  •  Tadodataset — універсальний набір даних;

  •  TАоотаblе — таблиця БД;

  •  Tadoquery — запит SQL;

  •  Taoostoredproc — процедура, що зберігається.

Мал. 6. Ієрархія класів набору даних ADO

Компоненти ADO володіють звичайним набором властивостей і методів, а необхідний для доступу до даних через ADO механізм успадковують від свого загального предка — класу Tcustomadodataset. Окрім цього, клас Tcustomadodataset містить ряд загальних для всіх нащадків властивостей і методів, розглянути які буде дуже корисно.

Клас Tcustomadodataset

Клас Tcustomadodataset інкапсулює механізм доступу до сховища даних через ADO. Цей клас наповнює абстрактні методи загального предка Tdataset функціями конкретного механізму доступу до даних. Тому тут ми розглянемо лише унікальні властивості і методи класу Tcustomadodatasetщо забезпечують роботу з ADO.

З'єднання набору даних з сховищем даних ADO здійснюється через компонент Tadoconnection (властивість connection) або шляхом завдання параметрів з'єднання через властивість connectionstring (див. вищий). Перед відкриттям набору даних необхідно встановити тип використовуваного при редагуванні записів блокування. Для цього застосовується властивість

type Tadolocktype = (Itunspecified, Itreadonly, Itpessimistic, Itoptimistic, Itbatchoptimistic); property Locktype: Tadolocktype;

Itunspecified — блокування задається джерелом даних, а не компонентом; 

Itreadonly — набір даних відкриється в режимі лише для читання;

Itpessimistic — редагований запис блокується на весь час редагування до моменту збереження в сховищі даних;

Itoptimistic — запис блокується лише на час збереження змін в сховищі даних;

Itbatchoptimistic — запис блокується на час збереження в сховищі даних при виклику методу updatebatch.

Для того, щоб блокування спрацювало, властивість Locktype повинна бути обов'язково модифікованою до відкриття набору даних. Набір даних відкривається методом Open і закривається методом close. Також можна використовувати властивість property Active: Boolean;

Поточний стан набору даних можна визначити властивістю

type

Tobjectstate = (stclosed, stopen, stconnecting, stexecuting, stretching);

Tobjectstates = set of Tobjectstate;

property Recordsetstate: Tobjectstates;

Набір даних в компонентах ADO заснований на використанні об'єкту набору записів ADO, прямий доступ до цього об'єкту можливий за допомогою властивості property Recordset: _recordset;

Але оскільки всі основні методи інтерфейсів об'єкту набору записів ADO перекриті методами класу, в звичайних випадках прямий доступ до об'єкту вам не знадобиться. Після оновлення набору даних викликається метод-обробник

Trecordsetevent = procedure(Dataset: Tcustomadodataset; const Error: Error;

 var Eventstatus: Teventstatus) of object; property Onfetchcomplete: Trecordsetevent;

де Error — заслання на об'єкт помилки ADO, якщо вона виникла.

Якщо ж набір даних працює в асинхронному режимі, при оновленні викликається метод-обробник

Tfetchprogressevent = procedure(Dataset: Tcustomadodataset;

Progress, Maxprogress: Integer;

var Eventstatus: Teventstatus) of object; 

property Onfetchprogress: Tfetchprogressevent;

де параметр Progress показує долю виконання операції.

Курсор набору даних

Для набору даних ADO залежно від його призначення можна вибрати тип і місце розташування використовуваного курсора. Місце розташування курсора задається властивістю

type Tcursorlocation = (cluseserver, cluseclient); property Cursorlocation: Tcursorlocation;

Курсор може знаходитися на сервері (Ciuseserver) або на клієнтові (Ciuseclient).

  •  Серверний курсор використовується при роботі з великими наборами даних, які недоцільно пересилати клієнтові цілком. При цьому знижується швидкість роботи клієнтського набору даних.

  •  Клієнтський курсор забезпечує передачу набору даних клієнтові. Це позитивно позначається на швидкодії, але такий курсор розумно використовувати лише для невеликих наборів даних, що не завантажують канал зв'язку з сервером.

При використанні клієнтського курсору необхідно додатково встановити властивість

Tmarshaloption = (momarshalall, momarshalmodifiedonly); property Marshaloptions: Tmarshaloption

яке управляє обміном даних клієнта з сервером. Якщо з'єднання з сервером швидке, можна використовувати значення momarshalallщо вирішує повернення серверу всіх записів набору даних. Інакше для прискорення роботи компоненту можна застосувати властивість momarshalmodifiedonlyщо забезпечує повернення лише модифікованих клієнтом записів.

Тип курсора визначається властивістю

Tcursortype = (ctunspecified, Ctopenforwardonly, ctkeyset, ctdynamic

ctstatic);

property Cursortype: Tcursortype;

ctunspecified — курсор не заданий, тип курсора визначається можливостями джерела даних;

ctopenforwardonly — однонаправлений курсор, що допускає переміщення лише вперед; використовується при необхідності швидкого одиночного проходу по всіх записах набору даних;

ctkeyset — двонаправлений локальний курсор, що не забезпечує перегляд доданих і видалених іншими користувачами записів;

 ctdynamic — двонаправлений курсор, відображує всі зміни, вимагає найбільших витрат ресурсів;

ctstatic — двонаправлений курсор, повністю ігнорує зміни, внесені іншими користувачами.

Якщо курсор розташований на клієнтові (Cursortype = ciusedient)то для нього доступний лише один тип — ctstatic. Відповідно до і після кожного переміщення курсора в наборі даних викликаються методи - обробники:

Trecordsetreasonevent = procedure(Dataset: Tcustomadodataset;

const Reason: Teventreason; 

var Eventstatus: Teventstatus) of object;

property Onwillmove: Trecordsetreasonevent;

і

TP.ecordsetErrorEvent = procedure(Dataset: Tcustomadodataset; const --eason: Teventreason;

const Error: Error; var Eventstatus: Teventstatus) if object; 

property Onmovecomplete: Trecordseterrorevent;

де параметр Reason дозволяє взнати, який метод викликав це переміщення.

Локальний буфер

Після передачі клієнтові запису набору даних розміщуються в локальному буфері, розмір якого визначається властивістю property Cachesize: Integer;

Значення властивості є число записів, що поміщаються в локальний буфер, і воно не може бути менше 1. Вочевидь, що при чималому розмірі буфера компонент звертатиметься до джерела даних не так часто, але при цьому великий буфер помітно уповільнить відкриття набору даних. Окрім цього, при виборі розміру локального буфера необхідно враховувати доступну компоненту пам'ять. Це можна зробити шляхом нескладних обчислень:

"achesizelnmem := Adodataset.CacheSize * Adodataset.RecordSize;

де Recordsize — властивість

 property Recordsize: Word;

що повертає розмір одного запису в байтах.

Як бачите, компоненти ADO не уникнули загальної проблеми клієнтських даних — при поганій якості з'єднання робота додатка сповільнюється. Проте дещо все-таки зробити можна. Якщо при навігації по записах вам не потрібно відображувати дані у візуальних компонентах призначеного для користувача інтерфейсу, властивість property Blockreadsize: Integer; дозволяє організувати блокову пересилку даних. Воно задає число записів, що поміщаються в один блок. При цьому набір даних переходить в стан dsblockread. За умовчанням блокова пересилка не використовується і значення властивості дорівнює 0. Також можна обмежити максимальний розмір набору даних. Властивість property Maxrecords: Integer задає максимальне число записів набору даних. За умовчанням властивість має значення 0 і набір даних не обмежений.

Загальне число записів набору даних на цей момент повертає властивість лише для читання property Recordcount: Integer;

Досягши останнього запису набору даних викликається метод-обробник

Tendofrecordsetevent = procedure (Dataset: Tcustomadodataset;

var Moredata: Wordbool;

var Eventstatus: Teventstatus) of object;

property Onendofrecordset: Tendofrecordsetevent;

При цьому параметр Moredata показує, чи дійсно досягнутий кінець набору даних. Якщо Moredata = Trueто це означає, що в сховищі даних ще є записи, не передані клієнтові.

Стан запису

Клас Tcustomadodataset володіє додатковими можливостями, які дозволяють відстежувати стан кожного запису. Для поточного запису набору даних можна визначити її стан. Для цього призначена властивість

Trecordstatus = (rsok, rsnew, rsmodified, rsdeleted, rsunmodified, rslnvalid, rsmultiplechanges, rspendingchanges, rscanceled, rscantrelease, rsconcurrencyviolation, rsintegrityviolation, rsmaxchangesexceeded, rsobjectopen, rsoutofmemory, rspermissiondenied, rsschemaviolation, rsdbdeleted); property Recordstatus: Trecordstatusset;

де rsok — запис успішно збережений; rsnew — запис доданий; rsmodified — запис був змінений; rsdeleted — запис видалений; rsunmodified — запис без змін; rslnvalid — запис не може бути збережений із-за невірної закладки; rsmultiplechanges — запис не може бути збережений із-за множинних змін; rspendingchanges — запис не може бути збережений із-за заслання на незбережені зміни; rscanceled — операція із записом була скасована; rscantrelease — запис заблокований; rsconcurrencyviolation — запис не може бути збережений із-за типа блокування; rsintegrityvioiation — порушена посилальна цілісність; rsmaxchangesexceeded — надто багато змін; rsobjectopen — конфлікт з об'єктом бази даних; rsoutofmemory — недолік пам'яті rspermissiondenied — немає доступу; rsschemaviolation — порушення структури даних; rsdbdeleted — запис видалений в БД.

Як бачите, завдяки цій властивості стан окремого запису може бути визначений дуже точно.

Окрім цього, метод

type

Tupdatestatus = (usunmodified, usmodifled, uslnserted, usdeleted);

 function Updatestatus: Tupdatestatus; override;

повертає інформацію про стан поточного запису.

Відповідно до і після зміни запису викликаються методи-обробники

Twillchangerecordevent = procedure(Dataset: Tcustomadodataset; const Reason: Teventreason; 

const Recordcount: Integer; 

var Eventstatus: Teventstatus) of object;

 property Onwillchangerecord: Twillchangerecordevent;

і

Trecordchangecompleteevent = procedure(Dataset: Tcustomadodataset; const Reason: Teventreason;

const Recordcount: Integer; const Error: Error; 

var Eventstatus: Teventstatus) of object;

property Onrecordchangecomplete:

Trecordchangecompleteevent;

де параметр Reason дозволяє дізнатися, який метод змінив записи, а параметр Recordcount повертає число змінених записів.

Фільтрація

Окрім звичайної фільтрації, заснованої на властивостях Filter, Filtered і методі-обробнику onfilterrecordклас Tcustomadodataset надає розробникові додаткові можливості.

Властивість

Tfiltergroup = (fgunassigned, fgnone, fgpendingrecords, fgaffectedrecords, fgfetchedrecords, fgpredicate, fgconflictingrecords); 

property Filtergroup: Tfiltergroup;

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

Фільтрація можлива по наступних параметрах:

  •  fgunassigned.— фільтр не заданий;

  •  fgnone — всі обмеження, задані фільтром, знімаються, відображуються всі записи набору даних;

  •  fgpendingrecords — відображуються змінені записи, незбережені в сховищі даних при виклику методу updatebatch або cancelbatch;

  •  fgaffectedrecords — показуються записи, оброблені при останньому збереженні в сховищі даних;

  •  fgfetchedrecords — маємо записи, отримані при останньому оновленні з джерела даних;

  •  fgpredicate — видно лише видалені записи;

  •  fgconfiictingrecords — відображуються модифіковані записи, при збереженні яких в сховищі даних виникла помилка.

Для того, щоб групова фільтрація запрацювала, необхідно дві додаткові умови. По-перше, фільтрація має бути включена — властивість Filtered повинно мати Значення True. 

По- друге, властивість Locktype повинна мати значення Itbatchoptimistic.

with Adodataset do begin

Close;

Locktype := Itbatchoptimistic;

Filtered := True;

Filtergroup := fgfetchedrecords;

Open;   end;

Метод procedure Filteronbookmarks(Bookmarks: array of const); включає фільтрацію по існуючих закладках. Для цього заздалегідь необхідно за допомогою методу Getbookmark встановити закладки на записах, що цікавлять. При виклику методу Filteronbookmarks автоматично очищається властивість Filterа властивості Filtergroup привласнюється значення gunassigned.

Пошук

Швидкий і гнучкий пошук по полях поточного індексу набору даних забезпечує метод

Seekoption = (sofirsteq, solasteq, soaftereq, soafter, sobeforeeq, sobefore);

function Seek(const Keyvalues: Variant; Seekoption: Tseekoption = sofirsteq): Boolean;

У параметрі Keyvalues мають бути перераховані необхідні значення полів індексу. Параметр Seekoption керує процесом пошуку:

  •  sofirsteq — курсор встановлюється на перший знайдений запис;

  •  solasteq — курсор встановлюється на останній знайдений запис;

  •  soaftereq — курсор встановлюється на знайдений запис або, якщо запис не знайдений, відразу після того місця, де вона могла знаходитися;

  •  soafter — курсор встановлюється відразу після знайденого запису;

  •  sobeforeeq — курсор встановлюється на знайдений запис або, якщо запис не знайдений, перед тим местомом, де вона могла знаходитися;

  •  sobefore — курсор встановлюється перед знайденим записом.

Сортування

Властивість property Sort: Widestring; надає простий спосіб сортування по довільному поєднанню полів. Воно повинне включати через кому імена потрібних полів і ознаку прямого або зворотного порядку сортування:

Adodataset.Sort := 'Firstfield DESC';

Якщо порядок сортування не вказаний, за умовчанням задається прямий порядок.

Команда ADO

Для виконання запитів до джерела даних будь-який компонент ADO інкапсулює спеціальний об'єкт команди ADO. При використанні компонентів-нащадків класу Tcustomadodataset зазвичай немає необхідності застосовувати об'єкт команди безпосередньо. І хоча вся реальна взаємодія об'єкту набору даних ADO з джерелом даних здійснюється через об'єкт команди, налаштування і виконання команди приховані у властивостях і методах компонентів ADO. Проте в класі Tcustomadodataset доступ до об'єкту команди можна отримати за допомогою властивості  property Command: Tadocommand;

При необхідності виконати команду ADO, не пов'язану з конкретним набором даних, розробник може використовувати окремий компонент Tadocommandтакож розташований на сторінці ADO палітри компонентів.

Тип команди задається властивістю

type

Tcommandtype = (cmdunknown, cmdtext, cmdtable, cmdstoredproc, cmdfile

cmdtabledirect);

 property Commandtype: Tcommandtype;

cmdunknown — тип команди невідомий і буде визначений джерелом даних;

cmdtext — текстова команда, що інтерпретується джерелом даних (наприклад запит SQL); текст має бути складений з врахуванням правил для конкретного джерела даних;

cmdtable — команда на здобуття набору даних таблиці з сховища даних;

cmdstoredproc — команда на виконання процедури, що зберігається;

cmdfile — команда на здобуття набору даних, збереженого у файлі у форматі, використовуваним конкретним джерелом даних;

cmdtableoirect — команда на здобуття набору даних таблиці безпосередньо, наприклад з файлу таблиці.

Текст команди, представлений властивістю property Commandtext: Widestring; обов'язково має бути погоджений з її типом.

Для обмеження часу чекання виконання команди використовується властивість

property Commandtimeout: Integer;

У компонентах наборів даних ADO команди виконується при виконанні наступних операцій:

  •  відкриття і закриття набору даних;

  •  виконання запитів і процедур, що зберігаються;

  •  оновлення набору даних;

  •  збереження змін;

  •  групові операції.

Розробник може вплинути на спосіб виконання команди. Для цього він може змінити властивість

type

Texecuteoption = (eoasyncexecute, eoasyncfetch, eoasyncfetchnonblocking, eoexecutenorecords);

Texecuteoptions = set of Texecuteoption;

 property Executeoptions: Texecuteoptions;

eoasyncexecute — асинхронне виконання команди;

eoasyncfetch — асинхронне виконання команди на оновлення набору даних;

eoasyncfetchnonblocking — асинхронне виконання команди на оновлення набору даних без установки блокування;

eoexecutenorecords — виконання команди не вимагає повернення набору даних.

Групові операції

Як вже розповідалося вище, набори даних ADO використовують на клієнтській стороні локальний кеш для зберігання даних і зроблених змін. Завдяки наявності цього кеша і з'явилася можливість реалізувати групові операції. У цьому режимі всі зроблені зміни не передаються негайно джерелу даних, а накопичуються в локальному кеші. Це підвищує швидкість роботи і дозволяє зберігати відразу групу модифікованих записів. З негативних сторін цього методу варто відзначити, що доки зміни знаходяться на клієнтові, вони недоступні іншим користувачам. У даній ситуації можуть виникати втрати даних. Для перекладу набору даних в режим групових операцій необхідно виконати наступні умови.

  •  Набор даних повинен використовувати клієнтський курсор: Adodataset.CursorLocation := cluseclient;

  •  Курсор повинен мати тип ctstatic: Adodataset.CursorType := ctstatic;

  • Блокування повинне мати значення itbatchoptimistic: Adodataset.LockType := Itbatchoptimistic;

Для передачі зроблених змін в сховищі даних в компонентах ADO використовується метод

procedure Updatebatch(Affectrecords: Taffectrecords = arall);

Для відміни всіх зроблених, але не збережених методом Updatebatch змін застосовується метод

procedure Cancelbatch(Affectrecords: Taffectrecords = arall);

Використовуваний в методах тип Taffectrecords дозволяє задати типа записів, до яких застосовується дана операція:

Taffectrecords = (arcurrent, arfiltered, arall, arahchapters);

arcurrent — операція виконується лише для поточного запису;

 arfiltered — операція виконується для записів з працюючого фільтру;

rall — операція виконується для всіх записів;

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

Параметри

Багато компонент ADO, що інкапсулюють набір записів, повинні забезпечувати вживання параметрів запитів. Для цього в них використовується спеціальний клас Tparameters. Для кожного параметра з колекції класу Tparameters створюється окремий клас Tparameter. Цей клас є спадкоємцем класу колекції Tcollection і інкапсулює індексований список окремих параметрів. Методи цих двох класів збігаються, а властивості мають деякі відмінності. Для представлення параметрів команд в ADO є спеціальний об'єкт параметрів, який активно використовується в процесі роботи компонентів Аdo, що інкапсулюють набір даних. Тому для компонентів ADO в VCL був створений власний клас параметрів.

Клас Tparameters

Головне, для чого призначений клас Tparameters—це містити список параметрів. Індексований список параметрів представлений властивістю property Items[Index: Integer]: Tparameter; Поточних значень параметрів можна набути з індексованої властивості

property Paramvalues[const Paramname: String]: Variant;

При цьому доступ до конкретного значення здійснюється по імені параметра:

Editl.Text := Adodataset.Parameters.ParamValues['Paramone'];

Список параметрів можна оновлювати за допомогою методів function Addparameter: Tparameter; 

і function Createparameter(const Name: Widestring; Datatype: Tdatatype;

  Direction: Tparameterdirection; Size: Integer;

  Value: Olevariant): Tparameter;

Перший метод просто створює новий об'єкт параметра і додає його до списку. Потім необхідно задати всі властивості нового параметру:

var Newparam: Tparameter;

Newparam := Adodataset.Parameters.AddParameter; Newparam.Name := 'Paramtwo';

Newparam.DataType := ftlnteger; 

Newparam.Direction := pdlnput; Newparam.Value := 0;

Метод Createparameter створює новий параметр і визначає його властивості: 

  •  Name — ім'я параметра;

  •  Datatype — тип даних параметра, відповідний типові поля таблиці БД (тип Tfieldtype);

  •  Direction — тип параметра, на додаток до стандартних типів dunknown, pdlnput, pdoutput, pdlnputoutput,тіп Tparameterdirection має додаткового типа pdreturnvalue, що визначає будь-яке повертане значення;

  •  size — максимальний розмір значення параметра; 

  •  value — значення параметра.

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

function Parambyname(const Value: Widestring): Tparameter;

Список параметрів завжди повинен відповідати запиту або процедурі, що зберігається. Для оновлення списку використовується метод procedure Refresh;

Також ви можете створити список параметрів для не пов'язаного з даним об'єктом параметрів запиту. Для цього використовується метод

function PARSESQL(SQL: String; Docreate: Boolean): String;

де Docreate визначає, чи видаляти перед аналізом існуючі параметри.

Клас Tparameter

Клас Tparameter інкапсулює окремий параметр. Ім'я параметра визначається властивістю

property Name: Widestring;

Тип даних, якому повинне відповідати його значення, задається властивістю

Tdatatype = Tfieldtype; property Datatype: Tdatatype;

І так як параметри взаємодіють з полями таблиць БД, то тип даних параметрів збігається з типами даних полів. Від типу даних залежить розмір параметра property Size: Integer; який може бути змінений для строкового або символьного типа даних і подібних до них. Саме значення параметра міститься у властивості property Value: Olevariant; 

А властивість

type

Tparameterattribute = (pasigned, panullable, palong);

Tparameterattributes = set of Tparameterattribute; property Attributes: Tparameterattributes;

контролює значення, що привласнюється параметру:

  •  pasigned — значення може бути символьним;

  •  panullable — значення параметра може бути порожнім;

  •  palong — значення може містити дані типа BLOB.

Тип параметра задається властивістю

type Tparameterdirection = (pdunknown, pdlnput, pdoutput, pdlnputoutput, pdreturnvalue);

property Direction: Tparameterdirection;

pdunknown — невідомий тип, джерело даних спробує визначити його самостійно;

pdinput — вхідний параметр, використовується в запитах і процедурах, що зберігаються;

pdoutput — вихідний параметр, використовується в процедурах, що зберігаються;

pdlnputoutput — вхідний і вихідний параметр одночасно, використовується в процедурах, що зберігаються;

pdreturnvalue — параметр для передачі значення.

Якщо параметр повинен передавати великі бінарні масиви (наприклад, зображення або файли), то значення параметра можна завантажити, використовуючи методи

procedure Loadfromfile(const Filename: String; Datatype: Tdatatype);

procedure Loadfromstream(Stream: Tstream; Datatype: Tdatatype);

Компонент Tadodataset

Компонент Tadodataset призначений для представлення набору даних з сховища даних ADO. Він простий у використанні, маючи лише декілька власних властивостей і методів, і застосовує функції свого предка —класса Tcustomadodataset.

Це єдиний компонент ADO, що інкапсулює набір даних, для якого опубліковані властивості, що дозволяють управляти командою ADO. Це властивості property Commandtext: Widestring; і property Commandtype: Tcommandtype;

В результаті компонент є гнучким інструментом, який дозволяє (залежно від типа команди і її тексту) отримувати дані з таблиць, запитів SQL, процедур, що зберігаються, файлів і так далі Наприклад, ви вибираєте потрібне значення властивості Commandtype = cmdtext і заносите у властивість Commandtext текст запиту SQL з редактора:

Adodataset,commandtype = cmdtext;

Adodataset. Commandtext := Memol.Lines.Text;

І запит SQL готовий до виконання.

Для запитів SQL можна застосовувати лише мову Data Manipulation Language (використовувати лише SELECT). З'єднання з базою даних задається властивістю Connectionstring або Connection (див. вищий). Набір даних відкривається і закривається властивістю Active або методами Open і Close.

У додатках компонент можна застосовувати як всі звичайні компоненти доступу до даних, пов'язуючи інкапсульований в нім набір даних з візуальними компонентамі відображення даних через компонент Tdatasource.

Компонент Tadotable

Компонент ТАdotаblе забезпечує використання в додатках Delphi таблиць БД, підключених через провайдери OLE DB. По своїх функціональних можливостях і вживанні він подібний до стандартного табличного компонента. Як ви вже знаєте, в основі компонента лежить використання команди ADO, але її властивості налагоджені заздалегідь і зміні не підлягають. Ім'я таблиці БД задається властивістю

property Tablename: Widestring;

Інші властивості і методи компонента забезпечують вживання індексів (цій можливості позбавлений будь-який компонент запиту). Оскільки не всі провайдери ADO забезпечують пряме використання таблиць БД, то для доступу до них може знадобитися запит SQL. Якщо властивість

property Tabledirect: Boolean;

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

Властивість

property Readonly: Boolean;

дозволяє включити або відключити для таблиці режим "лише для читання".

Компонент Tadoquery

Компонент Tadoquery забезпечує вживання запитів SQL при роботі з даними через ADO. По своїй функціональності він подібний до стандартного компонента запиту (див. гл. 11).

Текст запиту задається властивістю

property SQL: Tstrings;

Параметри запиту визначаються властивістю

property Parameters: Tparameters;

Якщо запит повинен повертати набір даних, для його відкриття використовується властивість

property Active: Boolean;

або метод

procedure Open;

Інакше досить використовувати метод function EXECSQL: Integer; EXECSQL

Число оброблених запитом записів повертає властивість property Rowsaffected: Integer;

Компонент Tadostoredproc

Компонент Tadostoredproc дозволяє використовувати в додатках Delphi, що звертаються до даних через ADO, процедури, що зберігаються. Він подібний до стандартного компонента процедури, що зберігається (див. гл. Л).

Ім'я процедури, що зберігається, визначається властивістю property Procedurename: Widestring;

Для визначення вхідних і вихідних параметрів використовується властивість property Parameters: Tparameters;

Якщо процедура застосовуватиметься без змін багато разів, має сенс заздалегідь підготувати її виконання на сервері. Для цього властивості property Prepared: Boolean; привласнюється значення True.

Команди ADO

Команді ADO, якою ми приділяли так багато уваги в цій главі в VCL Delphi, відповідає компонент Tadocormand. Методи цього компонента багато в чому збігаються з методами класу Tcustomadodatasetхоча цей клас не є предком компонента (мал. 7). Він призначений для виконання команд, які не повертають набори даних.

Мал. 7. Ієрархія класів компонента Tadocommand

Оскільки компоненту Tadocommand немає необхідності забезпечувати роботу набору записів, його безпосереднім предком є клас Tcomponent. До його функціональності просто доданий механізм з'єднання з БД через ADO і засоби представлення команди.

Команда передається в сховище даних ADO через власне з'єднання або через компонент Taoocormectionаналогічно іншим компонентам ADO.

Текстове представлення виконуваної команди повинне міститися у властивості property Commandtext: Widestring;

Проте команду можна задати і іншим способом. Пряме заслання на потрібний об'єкт команди ADO може бути задане властивістю property Commandobject: _command;

Тип команди визначається властивістю

type Tcommandtype = (cmdunknown, cmdtext, cmdtable, cmdstoredproc, cmdfile, cmdtabledirect);

property Commandtype: Tcommandtype;

Оскільки тип Tcommandtype також використовується в класі Tcustomadodatasetде необхідно представляти всі можливі види команд, по відношенню до компонента Tadocommand цей тип володіє надмірністю. Тут не можна встановити значення зmdtable, cmdfile, cmdtabledirect а тип cmdstoredproc повинен позначати лише ті процедури, що зберігаються, які не повертають набір даних.

Якщо команда повинна містити текст запиту SQL, властивість Commandtype повинно мати значення cmdtext. Для виклику процедури, що зберігається, необхідно задати типа cmdstoredprocа у властивості Commandtext ввести ім'я процедури.

Якщо для виконання команди необхідно задати параметри, використовується властивість

property Parameters: Tparameters;

Виконання команди здійснюється методом Execute:

function Execute: _recordset; overload;

function Execute(const Parameters: Olevariant): _recordset; 

overload;

 function Execute(var Recordsaffected: Integer; var Parameters: Olevariant; Executeoptions: Texecuteoptions = []): _recordset; overload;

Розробник може використовувати будь-яку з представлених нотацій перенавантажуваного методу:

  •  параметр Recordsaffected повертає число оброблених записів;

  •  параметр Parameters задає параметри команди;

  •  параметр Executeoptions визначає умови виконання команди:

Texecuteoption = (eoasyncexecute, eoasyncfetch, eoasyncfetchnonblocking, eoexecutenorecords); Texecuteoptions = set of Texecuteoption;

eoasyncexecute — асинхронне виконання команди; 

eoasyncfetch — асинхронна передача даних;

eoasyncfetchnonblocking — асинхронна передача даних без блокування потоку;

eoexecutenorecords — якщо команда повертає набір записів, то вони не передаються в компонент.

При роботі з компонентом Tadoconnection бажано використовувати опцію eoexecutenorecords.

Для переривання виконання команди використовується метод procedure Cancel;

Поточний стан команди можна визначити властивістю

type

Tobjectstate = (stclosed, stopen, stconnecting, stexecuting, stfetching);

Tobjectstates = set of Tobjectstate; property States: Tobjectstates;

Об'єкт помилок ADO

Ці об'єкти містять інформацію про помилку, що виникла при виконанні операції яким-небудь об'єктом ADO. У Delphi для об'єкту помилки не передбачений спеціальний тип, але розробник може використовувати його методи інтерфейсу Errorщо надається багатьма методами інших об'єктів ADO. Наприклад, тип

Trecordsetevent = procedure(Dataset: Tcustomadodataset; const Error: Error;

var Eventstatus: Teventstatus) of object;

використовуваний для методу-обробника, що викликається після оновлення набору даних, містить параметр Errorщо дає нам шукане заслання.

Розглянемо корисні властивості об'єкту помилок ADO.

Властивість property Description: Widestring read Get_description; повертає опис помилки, переданий з об'єкту, в якому помилка сталася.

Властивість property Sqlstate: Widestring read Get_sqlstate; містить текст команди, що викликала помилку.

Властивість property Nativeerror: Integer read Get_nativeerror; повертає код помилки, переданий з об'єкту, в якому помилка сталася.