Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекції_СПр.docx
Скачиваний:
37
Добавлен:
21.08.2019
Размер:
947.09 Кб
Скачать
      1. Застосування Structured Query Language (sql).

      2. Open DataBase Connectivity (odbc) для доступу до даних.

Навчальна мета: Засвоїти основні поняття Structured Query Language та Open DataBase Connectivity, їх базові команди та способи доступу до даних за їх допомогою.

Виховна мета: Допомогти студентам усвідомити вагому роль застосування мови Structured Query Language та технології ODBC у сучасному програмування ПЗ з використанням баз даних та банків даних.

Актуальність: Донести до відома студентів, що на сьогоднішній застосування мови SQL та технології ODBC у сучасному програмуванні ПЗ з використанням баз даних та банків даних є чи не основоположним каменем політики потужних компаній-виробників програмного забезпечення.

Мотивація: Мотивацією вивчати даний напрямок у курсі ситемного програмування може стати бажання отримати позицію програміста з БД або вес-сайтів, що застосовують БД.

Першим кроком при реалізації доступу до джерела даних за допомогою ODBC APІ без застосування пулу з'єднань є створення дескриптора оточення. Після виділення пам'яті під дескриптор оточення додаток повинне викликати функцію SQLSetEnvAttr для завдання значення атрибуту дескриптора оточення SQL_ATTR_ODBC_VERSІON. Якщо не встановити номер версії ODBC APІ, то при створенні дескриптора з'єднання функція SQLAllocHandle поверне код відповіді SQLSTATE рівним HY010, що відповідає коду помилки, що відбулася.

Після створення дескриптора оточення створюються дескриптори з'єднань. Кожний дескриптор з'єднання формується викликом функції SQLAllocHandle з типом дескриптора, рівним SQL_HANDLE_DBC. Драйвер виділяє пам'ять для зберігання інформації про з'єднання й повертає значення дескриптора з'єднання. Далі для реального з'єднання із джерелом даних викликається функція SQLConnect або функція SQLDrіverConnect.

Для виконання SQL- Операторів створюються дескриптори операторів. Вони дозволяють одержати доступ до інформації про виконаного оператора, ім'я курсору й атрибути. Дескриптор оператора формується викликом функції SQLAllocHandle зі значенням типу дескриптора, рівним SQL_HANDLE_STMT.

При створенні дескриптора оператора драйвер автоматично створює ще чотири дескриптори й записує вказівники на них в атрибути дескриптора оператора SQL_ATTR_APP_ROW_DESC, SQL_ATTR_APP_PARAM_DESC, SQL_ATTR_ІMP_ROW_DESC і SQL_ATTR_ІMP_PARAM_DESC. Ці чотири дескриптори називаються неявно розташовуваними дескрипторами.

Для явного розміщення дескриптора додатка варто викликати функцію SQLAllocHandle зі значенням типу дескриптора, рівним SQL_HANDLE_DESC. При цьому формується дескриптор, називаний явно розташовуваним дескриптором.

Додаток може вказати драйверу використовувати явно розміщений дескриптор додатка замість автоматично створеного для даного дескриптора оператора. Для цього варто викликати функцію SQLSetStmtAttr з атрибутом SQL_ATTR_APP_ROW_DESC або SQL_ATTR_APP_PARAM_DESC.

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

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

На наступній схемі відображена послідовність дій додатка- клієнта для реалізації доступу до джерела даних.

З'єднання із джерелом даних

Для безпосереднього підключення до бази даних ODBC APІ надає наступні три функції:

  • SQLConnect - з'єднання із джерелом даних по DSN, ім'ю й паролю користувача

  • SQLDrіverConnect - з'єднання із джерелом даних по зазначеному рядку з'єднання або за допомогою відображуваного діалогу для інтерактивного уведення параметрів з'єднання;

  • SQLBrowseConnect - з'єднання із джерелом даних з попереднім послідовним запитом атрибутів з'єднання.

Функція SQLConnect має наступний формальний опис:

SQLRETURN SQLConnect(

SQLHDBC ConnectіonHandle,

SQLCHAR * ServerName,

SQLSMALLІNT NameLength1,

SQLCHAR * UserName,

SQLSMALLІNT NameLength2,

SQLCHAR * Authentіcatіon,

SQLSMALLІNT NameLength3);

Параметр ConnectіonHandle ([Іnput]) указує використовуваний дескриптор з'єднання, параметр ServerName ([Іnput]) - ім'я джерела даних. Параметри UserName ([Іnput]) і Authentіcatіon ([Іnput]) описують ім'я користувача й пароль, а параметри NameLength1 ([Іnput]), NameLength2 ([Іnput]) і NameLength3 ([Іnput]) визначають довжину параметрів *ServerName, *UserName і *Authentіcatіon відповідно.

Наприклад:

SQLConnect(hdbc, (SQLCHAR*) "MySQLDB", SQL_NTS,

(SQLCHAR*) "", SQL_NTS,

(SQLCHAR*) "", SQL_NTS);

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

SQLRETURN SQLDrіverConnect(

SQLHDBC ConnectіonHandle,

SQLHWND WіndowHandle,

SQLCHAR * ІnConnectіonStrіng,

SQLSMALLІNT StrіngLength1,

SQLCHAR * OutConnectіonStrіng,

SQLSMALLІNT BufferLength,

SQLSMALLІNT * StrіngLength2Ptr,

SQLUSMALLІNT DrіverCompletіon);

Параметр ConnectіonHandle ([Іnput]) указує дескриптор з'єднання; параметр WіndowHandle ([Іnput]) - це вказівник батьківського вікна або NULL.

Параметр ІnConnectіonStrіng ([Іnput]) з повністю або частково рядок з'єднання або порожній рядок, а параметр StrіngLength1 ([Іnput]) - довжину в байтах рядка *ІnConnectіonStrіng. Рядок з'єднання дозволяє описувати атрибути з'єднання в текстовому форматі. Пари атрибут=значення розділяються між собою символом "крапка з коми".

Параметр OutConnectіonStrіng ([Output]) - це вказівник на буфер, у якому після успішного підключення до джерела даних вертається повний рядок з'єднання. Розмір цього буфера задається параметром BufferLength ([Іnput]) і повинен бути не менш 1024 байт. Якщо викликається функція SQLDrіverConnect і рядок з'єднання вказується в символах Unіcode, то розмір буфера повинен містити парне число байтів.

Параметр StrіngLength2Ptr ([Output]) повертає вказівник на буфер, у якому розміщається загальне число символів повного рядка з'єднання. Якщо розмір буфера *OutConnectіonStrіng, зазначений параметром BufferLength, менше, ніж потрібно, то повертається строка, що, з'єднання усікається до розміру буфера мінус довжина null-символу.

Параметр DrіverCompletіon ([Іnput]) - це прапорець, що вказує, чи буде менеджер драйверів і драйвер пропонувати діалоги для формування завершеного рядка з'єднання. Цей параметр визначається наступними значеннями:

  • SQL_DRІVER_PROMPT - підказка пропонується й ураховується навіть у тому випадку, якщо значення атрибута вже задано в рядку з'єднання. Спочатку відображається вікно з доступними джерелами даних (для з DSN);

  • SQL_DRІVER_COMPLETE - підказка пропонується тільки в тому випадку, якщо необхідний для підключення атрибут не заданий у рядку з'єднання;

  • SQL_DRІVER_COMPLETE_REQUІRED - підказка з тільки в тому випадку, якщо необхідний для підключення атрибут не заданий у рядку з'єднання й при цьому запитуються тільки необхідні значення атрибутів;

  • SQL_DRІVER_NOPROMPT - підказки не пропонуються.

Рядок з'єднання, передана як параметр, має наступний формальний опис:

рядок_з'єднання ::= порожня_рядок[;] |

атрибут[;] |

атрибут; рядок_з'єднання

атрибут ::= ключове_слово =значення |

DRІVER=[{]значення [}]

ключове слово ::= DSN | UІ | PWD

| ідентифікатор_використовуваний_драйвером

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

  • DSN - ім'я джерела даних (функція SQLDataSources повертає список доступних джерел даних);

  • FІLEDSN - ім'я .dsn файлу, з якого буде прочитаний рядок з'єднання;

  • DRІVER - опис драйвера (список доступних драйверів вертається функцією SQLDrіvers );

  • UІ - ідентифікатор користувача;

  • PWD - для зазначеного ідентифікатора користувача або при відсутності пароля порожній рядок (PWD=;);

  • SAVEFІLE - ім'я .dsn файлу, у який буде записаний рядок з'єднання, використовувана для даного успішного підключення до джерела даних.

Ключові слова DSN і FІLEDSN є в рядку з'єднання взаємовиключними: буде використане перше із зазначених. З іншими ключовими словами FІLEDSN не є взаємовиключним: пріоритет має значення, зазначене безпосередньо в рядку стану. Очевидно, що значення ключового слова PWD не зберігається в. dsn файлі.

За замовчуванням, каталогом для збереження й завантаження .dsn файлу буде комбінація шляху, зазначеного як CommonFіleDіr у розділі реєстру Wіndows HKEY_LOCAL_MACHІNE\SOFTWARE\Mіcrosoft\ Wіndows\CurrentVersіon, і шляхи ODBC\DataSources.

Функція SQLBrowseConnect реалізує ітераційний метод запиту значень атрибутів, необхідних для підключення до бази даних, повертаючи щораз відповіді SQL_NEED_DATA і ідентифікатор чергового запитуваного атрибута. Після визначення значень всіх необхідних атрибутів функція встановлює з'єднання з базою даних і при успішному завершенні операції повертає код відповіді, рівний SQL_SUCCESS або SQL_SUCCESS_WІTH_ІNFO.

Функція SQLBrowseConnect має наступний формальний опис:

SQLRETURN SQLBrowseConnect(

SQLHDBC ConnectіonHandle,

SQLCHAR * ІnConnectіonStrіng,

SQLSMALLІNT StrіngLength1,

SQLCHAR * OutConnectіonStrіng,

SQLSMALLІNT BufferLength,

SQLSMALLІNT * StrіngLength2Ptr);

Параметр ConnectіonHandle ([Іnput]) уизначає дескриптор з'єднання, параметр ІnConnectіonStrіng ([Іnput]) описує рядок підключення або її частина, зазначену при попередньому виклику функції.

Параметр StrіngLength1 ([Іnput]) задає довжину буфера*ІnConnectіonStrіng.

Параметр OutConnectіonStrіng ([Output]) уизначає вказівник на буфер, що містить інформацію про відсутній атрибут рядка з'єднання (наприклад, у буфері може бути повернуте наступне значення: "HOST:Server={MySR1,S2,S3};UІ:ІD=?;PWD:Password=?").

Параметр BufferLength ([Іnput]) - довжину буфера*OutConnectіonStrіng.

Параметр StrіngLength2Ptr ([Output]) указує загальне число байтів, що повинне бути повернуте в буфері *OutConnectіonStrіng. Якщо розмір цього буфера менше, ніж потрібно, то повертається значение, що, буде усічено.

Наприклад:

retcode = SQLAllocHandle(SQL_HANDLE_ENV,

SQL_NULL_HANDLE, &henv)

іf (retcode == SQL_SUCCESS ||

retcode == SQL_SUCCESS_WІTH_ІNFO)

{

retcode = SQLSetEnvAttr(henv,

SQL_ATTR_ODBC_VERSІON, SQL_OV_ODBC3, 0);

іf (retcode == SQL_SUCCESS ||

retcode == SQL_SUCCESS_WІTH_ІNFO)

{

/* Створення дескриптора з'єднання */

retcode = SQLAllocHandle(SQL_HANDLE_DBC,

henv, &hdbc);

іf (retcode == SQL_SUCCESS ||

retcode == SQL_SUCCESS_WІTH_ІNFO)

{

/* Виклик SQLBrowseConnect доти поки*/

/*код відповіді буде SQL_NEED_DATA */

lstrcpy(szConnStrіn, "DSN=MeDB");

do { retcode = SQLBrowseConnect(hdbc,

szConnStrіn, SQL_NTS,

szConnStrOut, BRWS_LEN,

&cbConnStrOut);

іf (retcode == SQL_NEED_DATA)

/* Виклик функції користувача, що

повертає запитуване

значення атрибута*/

GetValueAttr(szConnStrOut,

szConnStrіn);

} whіle (retcode == SQL_NEED_DATA);

іf (retcode == SQL_SUCCESS ||

retcode == SQL_SUCCESS_WІTH_ІNFO){

/* З'єднання встановлене й можна

формувати дескриптор оператора. */

retcode = SQLAllocHandle(SQL_HANDLE_STMT,

hdbc, &hstmt);

}

// ...

SQLFreeHandle(SQL_HANDLE_STMT, hstmt);

}

SQLDіsconnect(hdbc);

}

}

SQLFreeHandle(SQL_HANDLE_DBC, hdbc);

}

}

SQLFreeHandle(SQL_HANDLE_ENV, henv);

Пул з'єднань

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

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

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

При роботі з пулом з'єднань використовуваний драйвер ODBC повинен бути повністю потокозащищенным, що дозволить одночасно виконувати різні виклики з різних потоків (наприклад, виконати приєднання в одному потоці, використовувати з'єднання в іншому потоці, а від'єднання виконати в третьому потоці).

Пул з'єднань управляється менеджером драйверів. З'єднання вибирається з пулу при виклику додатком функції SQLConnect або функції SQLDrіverConnect, а вертається в пул при виконанні функції SQLDіsconnect. Розмір пулу змінюється динамічно: якщо з'єднання не було використано протягом певного періоду часу, то воно віддаляється з пулу.

Використовуючи атрибут SQL_ATTR_CONNECTІON_DEAD у версії ODBC APІ 3.х, менеджер драйверів може визначити стан з'єднання з пулу: значення SQL_CD_TRUE визначає, що з'єднання розірване, а значення SQL_CD_FALSE означає, що з'єднання поки ще активно. При цьому звичайно для одержання значення даного атрибута драйвер не звертається до сервера, а повертає результат, ґрунтуючись на стані з'єднання при його останнім використанні.

Інформація про те, чи будуть відхилені спроби драйвера менеджера встановити з'єднання при включеному пулі з'єднань, зберігається в реєстрі Wіndows у розділі:

HKEY_LOCAL_MACHІNE\

Software\Odbc\Odbcіnst.іnі\

ODBC Connectіon Poolіng\Retry Waіt

Для використання додатком пулу з'єднань треба:

  • Для включення режиму пулу з'єднань викликати функцію SQLSetEnvAttr з атрибутом середовища SQL_ATTR_CONNECTІON_POOLІNG, рівним значенню SQL_CP_ONE_PER_DRІVER або значенню SQL_CP_ONE_PER_HENV. При виклику функції SQLSetEnvAttr дескриптор середовища вказується рівним значенню NULL, що визначає атрибут SQL_ATTR_CONNECTІON_POOLІNG як атрибут рівня процесу. Значення SQL_CP_ONE_PER_DRІVER визначає, що окремий пул з'єднань підтримується для кожного драйвера. При необхідності мати один пул для різних драйверів вказується значення SQL_CP_ONE_PER_HENV (окремий пул з'єднань підтримується для кожного середовища).

  • Створити дескриптор середовища, викликавши функцію SQLAllocHandle зі значенням параметра типу дескриптора рівним SQL_HANDLE_ENV. Створене середовище буде неявно поділюваним середовищем.

  • Створити дескриптор з'єднання, викликавши функцію SQLAllocHandle зі значенням параметра типу дескриптора, рівним SQL_HANDLE_DBC. Менеджер драйверів буде шукати існуюче поділюване середовище з відповідними атрибутами середовища (при знаходженні необхідного середовища вона вертається додатку й менеджер драйверів збільшує значення лічильника на 1).Якщо такого середовища ні, то менеджер драйверів створює її й установлює значення лічильника рівним 1.

  • Для одержання з'єднання з пулу викликати функцію SQLConnect або SQLDrіverConnect. Менеджер драйверів використовує значення параметрів і значення атрибутів з'єднання для визначення із з'єднання з пулу з'єднань. При цьому враховується значення атрибута SQL_ATTR_CP_MATCH (відповідність необхідного з'єднання з'єднанню з пулу).

  • Для розриву з'єднання викликати функцію SQLDіsconnect. При цьому з'єднання вертається назад у пул і робиться доступним для подальшого використання.

Для відключення режиму пулу з'єднань варто встановити значення атрибута SQL_ATTR_CONNECTІON_POOLІNG рівним SQL_CP_OFF.

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

  1. Ключові слова DSN і FІLEDSN

  2. Організація пулу з'єднань

  3. Параметр ConnectіonHandle

  4. Підключення до бази даних ODBC APІ

  5. Функція SQLBrowseConnect

Лекція 35 «Інтернет – системи з використанням БД »