Соединение с источником данных
Для непосредственного подключения к базе данных ODBC API предоставляет следующие три функции:
- SQLConnect - соединение с источником данных по DSN, имени и паролю пользователя
- SQLDriverConnect - соединение с источником данных по указанной строке соединения или при помощи отображаемого диалога для интерактивного ввода параметров соединения;
- SQLBrowseConnect - соединение с источником данных с предварительным последовательным запросом атрибутов соединения.
Функция SQLConnect имеет следующее формальное описание:
SQLRETURN SQLConnect( SQLHDBC ConnectionHandle, SQLCHAR * ServerName, SQLSMALLINT NameLength1, SQLCHAR * UserName, SQLSMALLINT NameLength2, SQLCHAR * Authentication, SQLSMALLINT NameLength3);
Параметр ConnectionHandle ([Input]) указывает используемый дескриптор соединения, параметр ServerName ([Input]) - имя источника данных. Параметры UserName ([Input]) и Authentication ([Input]) описывают имя пользователя и пароль, а параметры NameLength1 ([Input]), NameLength2 ([Input]) и NameLength3 ([Input]) определяют длину параметров *ServerName, *UserName и *Authentication соответственно.
Например:
SQLConnect(hdbc, (SQLCHAR*) "MySQLDB", SQL_NTS, (SQLCHAR*) "", SQL_NTS, (SQLCHAR*) "", SQL_NTS);
Для выполнения соединения с источкиком данных, требующим для подключения дополнительной информации, или отображения перед подключением диалога с уточнением значения параметров используется функция SQLDriverConnect, которая имеет следующее формальное описание:
SQLRETURN SQLDriverConnect( SQLHDBC ConnectionHandle, SQLHWND WindowHandle, SQLCHAR * InConnectionString, SQLSMALLINT StringLength1, SQLCHAR * OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength2Ptr, SQLUSMALLINT DriverCompletion);
Параметр ConnectionHandle ([Input]) указывает дескриптор соединения; параметр WindowHandle ([Input]) - это указатель родительского окна или NULL.
Параметр InConnectionString ([Input]) задает полностью или частично строку соединения или пустую строку, а параметр StringLength1 ([Input]) - длину в байтах строки *InConnectionString.
Строка соединения позволяет описывать атрибуты соединения в текстовом формате. Пары атрибут=значение разделяются между собой символом "точка с запятой".
Параметр OutConnectionString ([Output]) - это указатель на буфер, в котором после успешного подключения к источнику данных возвращается полная строка соединения. Размер этого буфера задается параметром BufferLength ([Input]) и должен быть не менее 1024 байт. Если вызывается функция SQLDriverConnectW и строка соединения указывается в символах Unicode, то размер буфера должен содержать четное число байтов.
Параметр StringLength2Ptr ([Output]) возвращает указатель на буфер, в котором размещается общее число символов полной строки соединения. Если размер буфера *OutConnectionString, указанный параметром BufferLength, меньше, чем требуется, то возвращаемая строка соединения усекается до размера буфера минус длина null-символа.
Параметр DriverCompletion ([Input]) - это флажок, указывающий, будет ли менеджер драйверов и драйвер предлагать диалоги для формирования завершенной строки соединения. Этот параметр определяется следующими значениями:
- SQL_DRIVER_PROMPT - подсказка предлагается и учитывается даже в том случае, если значение атрибута уже задано в строке соединения. Первоначально отображается окно с доступными источниками данных (для атрибута DSN);
- SQL_DRIVER_COMPLETE - подсказка предлагается только в том случае, если требуемый для подключения атрибут не задан в строке соединения;
- SQL_DRIVER_COMPLETE_REQUIRED - подсказка предлагается только в том случае, если требуемый для подключения атрибут не задан в строке соединения и при этом запрашиваются только необходимые значения атрибутов;
- SQL_DRIVER_NOPROMPT - подсказки не предлагаются.
Строка соединения, передаваемая в качестве параметра, имеет следующее формальное описание:
строка_соединения ::= пустая_строка[;] | атрибут[;] | атрибут; строка_соединения атрибут ::= ключевое_слово =значение | DRIVER=[{]значение [}] ключевое слово ::= DSN | UID | PWD | идентификатор_используемый_драйвером
Набор ключевых слов, указываемых в строке соединения, частично зависит от используемого драйвера. К общепринятым ключевым словам относятся следующие:
- DSN - имя источника данных (функция SQLDataSources возвращает список доступных источников данных);
- FILEDSN - имя .dsn файла, из которого будет прочитана строка соединения;
- DRIVER - описание драйвера (список доступных драйверов возвращается функцией SQLDrivers);
- UID - идентификатор пользователя;
- PWD - для указанного идентификатора пользователя или при отсутствии пароля пустая строка (PWD=;);
- SAVEFILE - имя .dsn файла, в который будет записана строка соединения, используемая для данного успешного подключения к источнику данных.
Ключевые слова DSN и FILEDSN являются в строке соединения взаимоисключающими: будет использовано первое из указанных. С остальными ключевыми словами FILEDSN не является взаимоисключающим: приоритет имеет значение, указанное непосредственно в строке состояния. Очевидно, что значение ключевого слова PWD не сохраняется в .dsn файле.
По умолчанию, каталогом для сохранения и загрузки .dsn файла будет комбинация пути, указанного как CommonFileDir в разделе реестра Windows HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ Windows\CurrentVersion, и пути ODBC\DataSources.
На рис. 3.1 отображен соответствующий раздел реестра Windows (в данном примере .dsn файлы будут сохраняться в каталоге C:\Program Files\Common Files\ODBC\Data Sources).
Рис. 3.1. Параметр CommonFileDir из реестра Windows
Функция SQLBrowseConnect реализует итерационный метод запроса значений атрибутов, требуемых для подключения к базе данных, возвращая каждый раз код ответа SQL_NEED_DATA и идентификатор очередного запрашиваемого атрибута. После определения значений всех необходимых атрибутов функция устанавливает соединение с базой данных и при успешном завершении операции возвращает код ответа, равный SQL_SUCCESS или SQL_SUCCESS_WITH_INFO.
Функция SQLBrowseConnect имеет следующее формальное описание:
SQLRETURN SQLBrowseConnect( SQLHDBC ConnectionHandle, SQLCHAR * InConnectionString, SQLSMALLINT StringLength1, SQLCHAR * OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength2Ptr);
Параметр ConnectionHandle ([Input]) определяет дескриптор соединения, параметр InConnectionString ([Input]) описывает строку подключения или ее часть, указанную при предыдущем вызове функции.
Параметр StringLength1 ([Input]) задает длину буфера*InConnectionString.
Параметр OutConnectionString ([Output]) определяет указатель на буфер, содержащий информацию о недостающем атрибуте строки соединения (например, в буфере может быть возвращено следующее значение: "HOST:Server={MySR1,S2,S3};UID:ID=?;PWD:Password=?").
Параметр BufferLength ([Input]) задает длину буфера*OutConnectionString.
Параметр StringLength2Ptr ([Output]) указывает общее число байтов, которое должно быть возвращено в буфере *OutConnectionString. Если размер этого буфера меньше, чем требуется, то возвращаемое значение будет усечено.
Например:
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv) if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3, 0); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { /* Создание дескриптора соединения */ retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { /* Вызов SQLBrowseConnect до тех пор пока*/ /*код ответа будет SQL_NEED_DATA */
lstrcpy(szConnStrIn, "DSN=MeDB"); do { retcode = SQLBrowseConnect(hdbc, szConnStrIn, SQL_NTS, szConnStrOut, BRWS_LEN, &cbConnStrOut); if (retcode == SQL_NEED_DATA) /* Вызов функции пользователя, возвращающей запрашиваемое значение атрибута*/ GetValueAttr(szConnStrOut, szConnStrIn); } while (retcode == SQL_NEED_DATA);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){
/* Соединение установлено и можно формировать дескриптор оператора. */ retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); } // ... SQLFreeHandle(SQL_HANDLE_STMT, hstmt); } SQLDisconnect(hdbc); } } SQLFreeHandle(SQL_HANDLE_DBC, hdbc); } } SQLFreeHandle(SQL_HANDLE_ENV, henv);