Access і ODBC (частина 1), MS Office, Програмні керівництва, статті

Для початку

ODBC (Open DataBase Connectivity) – це відкритий інтерфейс доступу до баз даних, розроблений фірмою Microsoft. Він являє собою API досить низького рівня і призначений, в основному, для прямого використання в програмах, написаних на C, C + + або, в крайньому випадку, на VB. Незважаючи на своє походження, цей інтерфейс є кроссплатформним і з успіхом працює і в Windows, і в UNIX / Linux, і в MacOS.

Немає нічого неможливого і в тому, щоб скористатися функціями цього чудового інтерфейсу з VBA Access. Треба тільки чітко уявляти собі, що більша частина роботи вже й так пророблена розробниками MS Access. Для того, щоб зрозуміти, що ж залишилося на нашу долю, розглянемо більш докладно сам механізм ODBC.


Як це працює

За відносно довгу історію ODBC API про нього написано вже достатньо статей і навіть книг, в яких докладно описано з чого складається, як працює цей інтерфейс і як ним користуватися. Нам буде цілком достатньо лише загального уявлення про його структуру.

Отже, для нас ODBC – це, перш за все, Менеджер драйверів ODBC (для платформи Win32 це odbc32.dll). Драйвери безпосередньо взаємодіють з джерелами даних. Що це за драйвери і як здійснюється така взаємодія для нас не важливо. Просто, коли ми хочемо отримати доступ, наприклад, до MS SQL Server 7.0, то потрібно встановити драйвер MS SQL Server 7.0, коли до сервера MySQL – драйвер MySQL.

Робота з Менеджером драйверів ODBC (далі – просто Менеджер) полягає у виклику необхідних функцій з певними параметрами і в певній послідовності. У функції Менеджера входить:


Для виконання цих функцій Менеджер спочатку повинен підготувати деякі системні ресурси:


В кінці Менеджер повинен звільнити ці ресурси і повернути їх системі.

З точки зору програми на VBA, всі ці ідентифікатори – просто змінні типу Long, в яких зберігаються адреси відповідних областей пам’яті. При виділенні ресурсів ідентифікатором, його мінлива передається в спеціальну функцію по посиланню. При подальшому використанні – за значенням.

Dim HENV As Long
Dim HDBC As Long
Dim HSTMT As Long
Declare Function SQLAllocEnv Lib “odbc32.dll” (ByRef HENV As Long) As Integer
Declare Function SQLFreeEnv Lib “odbc32.dll” (ByVal HENV As Long) As Integer
Declare Function SQLAllocConnect Lib “odbc32.dll” (ByVal HENV As Long, _
ByRef HDBC As Long) As Integer
Declare Function SQLFreeConnect Lib “odbc32.dll” (ByVal HDBC As Long) As Integer
Declare Function SQLAllocStmt Lib “odbc32.dll” (ByVal HDBC As Long, _
ByRef HSTMT As Long) As Integer
Declare Function SQLFreeStmt Lib “odbc32.dll” (ByVal HSTMT As Long, _
ByVal EndOption As Integer) As Integer

Трохи практики

Насамперед, створимо окремий модуль, в якому будемо тримати всі оголошення констант, функцій, типів і змінних, так чи інакше пов’язаних з ODBC API. Нехитро назвемо його “ODBC_API” і, для початку, включимо такі рядки:

Option Compare Database
Option Explicit
“Константи ODBC
Global Const MAX_DATA_BUFFER = 2047
Global Const SQL_SUCCESS = 0
Global Const SQL_SUCCESS_WITH_INFO = 1
Global Const SQL_ERROR = -1
Global Const SQL_NO_DATA_FOUND = 100
Global Const SQL_FETCH_FIRST = 2
Global Const SQL_FETCH_NEXT = 1
“Декларації функцій ODBC
Declare Function SQLAllocEnv Lib “odbc32.dll” (ByRef HENV As Long) As Integer
Declare Function SQLFreeEnv Lib “odbc32.dll” (ByVal HENV As Long) As Integer
Declare Function SQLDrivers Lib “odbc32.dll” (ByVal HENV As Long, _
ByVal Direction As Long, _
ByVal Description As String, _
ByVal DescriptionMax As Integer, _
ByRef DescriptionLen As Integer, _
ByVal Attributes As String, _
ByVal AttributesMax As Integer, _
ByRef AttributesLen As Integer) As Integer

Declare Function SQLDataSources Lib “odbc32.dll” (ByVal HENV As Long, _
ByVal Direction As Long, _
ByVal DSN As String, _
ByVal DSNMax As Integer, _
ByRef DSNLen As Integer, _
ByVal Description As String, _
ByVal DescriptionMax As Integer, _
ByRef DescriptionLen As Integer) As Integer

Тут SQLDrivers і SQLDataSources вже не просто виконують сервісні функції, а дозволяють отримати конкретні дані про встановлені в операційній системі драйверах ODBC та іменах джерел даних (DSN – DataSource Name). Виглядають оголошення цих функцій досить громіздко, але далі я докладно їх опишу.

Так як ці функції отримують інформацію безпосередньо від Менеджера, потреба у виділенні ресурсів на з’єднання і оператори відсутня. Достатньо лише ініціалізувати ідентифікатор оточення HENV. Зробити це найкраще, створивши спеціальний модуль класу. Чому? Тому, що виділення і звільнення ресурсів можна здійснити, відповідно, в конструкторі (Class_Initialize) і деструкції (Class_Terminate) класу і, тим самим, виключити ситуацію, коли при скиданні програми функція звільнення ресурсів SQLFreeEnv не буде викликана. Отже, назвемо його ODBC_HENV:

Option Compare Database
Option Explicit
Dim lngHENV As Long “Змінна оточення (Environment Handle). Dim booValid As Boolean “Індикатор можливості використання змінної оточення.
Public Property Get HENV() As Long “Це властивість містить вже готовий ідентифікатор оточення.
On Error Resume Next
HENV = lngHENV
End Property
Public Property Get Valid() As Boolean “Це властивість є прапор, який показує можливість (True) або “Неможливість (False) використання ідентифікатора оточення. Воно необхідне, “Так як немає гарантії, що будь-яке ненульове значення ідентифікатора оточення є “Придатним для використання. Даний прапор встановлюється в True, тільки якщо функція “Ініціалізації оточення відрапортує про відсутність помилки.
On Error Resume Next
Valid = booValid
End Property
Private Sub Class_Initialize()
On Error Resume Next
Dim intStatus As Integer intStatus = SQLAllocEnv (lngHENV) “Ініціалізували ідентифікатор оточення.
If intStatus = SQL_SUCCESS Then
booValid = True
Else
booValid = False
MsgBox “Unable to Allocate ODBC Environment Handle!”, vbCritical, “Error”
End If
End Sub
Private Sub Class_Terminate()
On Error Resume Next
Dim intStatus As Integer intStatus = SQLFreeEnv (lngHENV) “Звільнимо ресурси оточення.
If intStatus = SQL_ERROR Then
MsgBox “Error Freeing ODBC Environment!”, vbCritical, “Error”
End If
End Sub

Тепер, при створенні екземпляра класу, буде відбуватися виділення ресурсів оточення, а при знищенні – їх звільнення. Це дуже схоже на роботу з сеансом (Workspace) MS Assess. На цьому підготовку можна вважати закінченою. Перейдемо до наступного етапу – отримання якої-небудь корисної інформації за допомогою ODBC API.

Наприклад, спробуємо отримати списки всіх зареєстрованих драйверів і джерел даних. Саме зареєстрованих, тому що ця інформація просто читається з реєстру Windows або з певних конфігураційних файлів. Якщо фізично видалити файл драйвера, то він все одно залишиться в списку, але при спробі звернення до нього Менеджер видаватиме помилку. Аналогічно, якщо новий драйвер просто скопіювати в системну папку Windows, він не з’явиться в списку встановлених драйверів і працювати з ним буде неможливо. Саме тому, драйвери ODBC зазвичай комплектуються спеціальною програмою установки.

Щоб отримати цікавлять нас списки, є пара оголошених раніше функцій: SQLDrivers і SQLDataSources. Вони настільки схожі, що розглядати я буду тільки першу з них, хоча використовуватися будуть обидві. Першим параметром в ній йде ідентифікатор оточення. Будемо вважати, що він у нас вже є:

Dim ODBC_ENV As New ODBC_HENV

Далі йде параметр Direction. Він визначає порядок перегляду результуючого безлічі. І треба сказати, що й інші функції ODBC, що працюють з наборами записів, влаштовані аналогічно. Коли ми хочемо отримати перший елемент набору, треба передати у функцію значення SQL_FETCH_FIRST, наступне – SQL_FETCH_NEXT, попереднє – SQL_FETCH_PRIOR і т.д.

Dim Direction As Long

Потім слідують два блоки з трьох параметрів кожен, які служать для отримання власне інформації про драйвери. Перший блок – назва драйвера, другий – список атрибутів. Не лякайтеся, для цього списку не знадобиться послідовний виклик ще який-небудь функції. Імена атрибутів і їх значення перераховані через стандартний для мови С (а саме на цю мову і розрахований інтерфейс ODBC в першу чергу) код завершення рядка – 0 (нуль). У першому параметрі кожного з двох блоків передається рядок певної довжини, спеціально виділена заздалегідь:

Dim Description As String * MAX_DATA_BUFFER
Dim Attributes As String * MAX_DATA_BUFFER

Другий параметр – довжина цього рядка. Він не дозволить функції сформувати занадто довгий рядок, зіпсувавши при цьому сусідні комірки пам’яті. У нашому випадку – це просто MAX_DATA_BUFFER. Третім йде покажчик на ціле число, в яке функція запише, скільки вона насправді використовувала символів у відведеній рядку:

Dim DescriptionLen As Integer
Dim AttributesLen As Integer

От і вся премудрість. Далі – справа техніки: у циклі заповнюємо пару таблиць даними про драйверах (назва та атрибути) і джерелах даних (ім’я та назву драйвера), а потім виводимо їх вміст за допомогою простенької форми.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*