(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Access и ODBC (часть 2)

Источник: Mccinet

Уровни функциональных возможностей ODBC API

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

Первый уровень расширения функциональных возможностей ODBC включает в себя функцию SQLDriverConnect (она будет рассмотрена далее), которая позволяет запрашивать у пользователя более подробную информацию о подготавливаемом соединении, а также задавать степень обязательности этого запроса.

Второй уровень ODBC API включает в себя функцию SQLBrowseConnect, поддерживающую пошаговый метод ввода данных, которые необходимы для установления соединения с источником данных.

В реальности, соответствие ODBC драйвера некоторому уровню означает то, что он поддерживает все функции данного уровня. При этом в нём, как правило, реализованы ещё и некоторые из функций более высокого уровня. Существуют специальные функции, которые позволяют точно определить возможности драйвера.

Уровни соответствия SQL

Уровень соответствия SQL - это показатель того, какие возможности языка SQL и типы данных поддерживает драйвер. Грамматика ODBC SQL может быть базовой (она соответствует стандартным требованиям), минимальной (более низкий уроверь по сравнению с базовым) и расширенной (обеспечивает некоторые общепринятые расширения SQL).

Как и в случае уровней ODBC API, существуют функции, позволяющие определить, какие операторы и типы данных поддерживает драйвер.

Более сложная задача

В предыдущей части я описал лишь основы использования интерфейса доступа к данным ODBC. Создание полнофункциональных приложений, основанных непосредственно на этом API, по сравнению с разработкой на MS Access, представляет собой исключительно трудную задачу.

Чтобы не быть голословным, я приведу здесь небольшой пример, который иллюстрирует, насколько много нужно написать кода, для того, чтобы всего лишь получить список пользовательских таблиц с выбранного сервера БД.

Перво-наперво, откажемся от использования классов для «обёртывания» функций, отвечающих за выделение и возврат ресурсов. Это не прибавит нашей программе надёжности, но зато значительно сократит её объём и улучшит читаемость кода. А функций таких будет много - полный комплект для всех трёх уровней структуры API (окружение-соединение-оператор).

Далее, дополним модуль ODBC_API новыми объявлениями констант и функций:

'Константы ODBC
'Константы для SQLDriverConnect
Global Const SQL_DRIVER_NOPROMPT = 0
Global Const SQL_DRIVER_COMPLETE = 1
Global Const SQL_DRIVER_PROMPT = 2
Global Const SQL_DRIVER_COMPLETE_REQUIRED = 3

'Константы для FreeStmt
Global Const SQL_CLOSE = 0
Global Const SQL_DROP = 1
Global Const SQL_UNBIND = 2
Global Const SQL_RESET_PARAMS = 3

'Типы данных
Global Const SQL_C_CHAR = 1

'Декларации функций ODBC
Declare Function SQLDriverConnect Lib "odbc32.dll" (ByVal HDBC As Long, _
                                                    ByVal hWnd As Long, _
                                                    ByVal ConStrIn As String, _
                                                    ByVal ConStrInMax As Integer, _
                                                    ByVal ConStrOut As String, _
                                                    ByVal ConStrOutMax As Integer, _
                                                    ByRef ConStrOutLen As Long, _
                                                    ByVal DriverCompleation As Integer) As Integer
                                                    
Declare Function SQLDisconnect Lib "odbc32.dll" (ByVal HDBC As Long) As Integer

Declare Function SQLTables Lib "odbc32.dll" (ByVal HSTMT As Long, _
                                             ByVal TableQualifier As String, _
                                             ByVal TableQualifierLen As Integer, _
                                             ByVal TableOwner As String, _
                                             ByVal TableOwnerLen As Integer, _
                                             ByVal TableName As String, _
                                             ByVal TableNameLen As Integer, _
                                             ByVal TableType As String, _
                                             ByVal TableTypeLen As Integer) As Integer

Declare Function SQLFetch Lib "odbc32.dll" (ByVal HSTMT As Long) As Integer

Declare Function SQLGetData Lib "odbc32.dll" (ByVal HSTMT As Long, _
                                              ByVal ColNumber As Long, _
                                              ByVal DataType As Integer, _
                                              ByVal DataValue As String, _
                                              ByVal DataValueMax As Integer, _
                                              ByRef DataValueLen As Long) As Integer

Для непосредственной работы создадим форму, в которой разместим список драйверов ODBC, поля для ввода параметров подключения к серверу (имя сервера, имя базы данных на нем, логин и пароль пользователя), а также список таблиц, который и будем пытаться заполнить. Ещё предусмотрим пару кнопок для придания большей наглядности нашим опытам (хотя, можно обойтись и обработкой событий списков).

Список драйверов заполним по аналогии с предыдущим примером, только не будем создавать и наполнять таблицу. Вместо этого, в качестве типа источника строк выберем список значений, а при загрузке формы запишем в переменную наименования всех найденных драйверов и присвоим её свойству «Источник строк» списка.

Следующий важный шаг - установить соединение с сервером. Информация, которая должна понадобиться - это, кроме имени драйвера, имена сервера и БД, а также логин и пароль пользователя, от лица которого будет осуществляться подключение. Вся вместе она образует так называемую строку подключения (Connection String), где перечисляются соответствующие ключи и их значения:

  strConStr = "DRIVER=" & Me.lbxDrivers & _
              ";SERVER=" & Me.txtServer & _
              ";DATABASE=" & Me.txtDataBase & _
              ";UID=" & Me.txtLogin & _
              ";PWD=" & Me.txtPassword & ";"

Нетрудно заметить, что в качестве значений мы указываем как раз содержимое элементов управления нашей тестовой формы. Теперь передадим эту строку вместе с уже имеющимся идентификатором окружения в предварительно заготовленную функцию, которая выполнит всю работу и, в случае успеха, вернёт ненулевой идентификатор соединения. Или нулевой - в случае ошибки. Вот она:

Public Function OpenConnection(HENV As Long, ConnectionString As String) As Long
Dim intStatus As Integer                      'Для кодов возврата функций ODBC.
Dim lngHDBC As Long                           'Идентификатор соединения.
Dim strConStrIn As String * MAX_DATA_BUFFER   'Строковый буфер для передачи данных.
Dim strConStrOut As String * MAX_DATA_BUFFER  'Строковый буфер для получения данных.
Dim lngConStrOutLen As Long                   'Реальная длина данных в буфере.

  OpenConnection = 0

  If Len(ConnectionString) < MAX_DATA_BUFFER Then 'Строка не должна быть слишком длинной.
    strConStrIn = ConnectionString & Chr(0) 'Добавим нулевой символ как знак завершения строки.
    intStatus = SQLAllocConnect(HENV, lngHDBC)  'Получим идентификатор соединения.
    If intStatus = SQL_SUCCESS Then  'Если соединение успешно создано, пытаемся открыть его.
      intStatus = SQLDriverConnect(lngHDBC, _
                                   0, _
                                   strConStrIn, _
                                   MAX_DATA_BUFFER, _
                                   strConStrOut, _
                                   MAX_DATA_BUFFER, _
                                   lngConStrOutLen, _
                                   SQL_DRIVER_NOPROMPT)
      If intStatus = SQL_SUCCESS Then  'Если соединение успешно открыто, возвращаем его идентификатор.
        OpenConnection = lngHDBC
      Else 'Иначе - освободим ресурсы, выделенные соединению, а функция вернёт 0.
        intStatus = SQLFreeConnect(lngHDBC)
      End If
    End If
  End If

End Function

Основа нашей функции - функция ODBC API SQLDriverConnect. Первым параметром в ней идёт уже знакомый нам идентификатор соединения, который надо предварительно получить с помощью функции SQLAllocConnect. Второй параметр - идентификатор окна, которое будет являться родительским для окна диалога ввода параметров соединения. Этот диалог обеспечивается используемым драйвером ODBC, если мы того захотим и укажем в последнем параметре вызова функции соответствующий режим. В нашем случае диалог не требуется и поэтому мы передаём нулевой идентификатор окна (в противном случае можно передать, например, hWndAccessApp) и SQL_DRIVER_NOPROMPT соответственно.

Третьим и четвёртым парамертами идут строка подключения и размер текстового буфера, отведенного этой строке. Последующие три параметра функции предназначены для возврата строки подключения, сформированной самой функцией и, в нашем случае, не используются.

После того, как соединение установлено, подготовим идентификатор оператора с помощью функции SQLAllocStmt и вызовем функцию SQLTables. Эта функция возвращает набор сведений о таблицах (TABLE), представлениях (VIEW) и других аналогичных объектах базы данных. Использовать её нужно также, как и все функции, работающие с результирующим множеством, каким является, например, результат выполнения запроса на выборку.

В двух словах, порядок действий такой: сначала нужно определить количество столбцов в результирующем множестве (SQLNumResultCols), затем их имена (SQLColumns) и типы данных (SQLDescribeCol). Для нашего примера всё это не нужно, так как точно известно, что имена таблиц содержатся в третьем столбце, имеют символьный тип данных, а название столбца не имеет значения. Теперь можно выделить буферы для данных каждого из столбцов с помощью функции SQLBindCol. Мы этого делать не будем, а воспользуемся другим способом извлечения данных (SQLGetData). Далее необходимо, устанавливая указатель на нужную запись с помощью функции SQLFetch или SQLExtendedFetch (последняя поддерживается не всеми драйверами), считывать данные столбца в подготовленную для них переменную.

Как видите, всё это очень сложно и громоздко. Поэтому, многими фирмами разработаны различные программные компоненты более высокого уровня, существенно облегчающие использование таких интерфейсов, как ODBC. В MS Access для этого можно использовать механизмы присоединённых таблиц и запросов к серверу. В программах на VBA удобно использовать объекты доступа к данным DAO. Все перечисленные механизмы имеют ряд особенностей, которые необходимо знать, учитывать и использовать при работе с данными через интерфейс ODBC. Однако, это уже тема для отдельного разговора.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 13.11.2007 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Microsoft Office 365 для Дома 32-bit/x64. 5 ПК/Mac + 5 Планшетов + 5 Телефонов. Подписка на 1 год.
Microsoft Office для дома и учебы 2019 (лицензия ESD)
Microsoft 365 Business Standard (corporate)
Microsoft 365 Business Basic (corporate)
Microsoft 365 Apps for business (corporate)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
Программирование в AutoCAD
Delphi - проблемы и решения
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100