Ошибка: Failed to parse the Currency Converter XML document.
$11 291.08


Ошибка: Failed to parse the Currency Converter XML document.
$54 617.09


Ошибка: Failed to parse the Currency Converter XML document.
$27 393.60


Программное управление источниками данных ODBC

Введение
Тема нашего сегодняшнего разговора — ODBC. Если вы хоть раз писали СУБД (системы управления базами данных), то вам, наверное, знакома эта аббревиатура. Расшифровывается ODBC как Open DataBase Connectivity (вольный перевод — открытая система связи с базами данных). Open (открытая) в данном случае означает «расширяемая», «легко наращиваемая», «открытая для модификаций». Вы сами это поймете, если посмотрите на архитектуру построения ODBC:

Программное управление источниками данных ODBCКак легко заметить, она действительно легко наращиваемая. Для добавления нового типа БД нужно лишь написать драйвер и зарегистрировать его. Еще одно преимущество, вытекающее из такого построения ODBC — пользовательское приложение общается с физической БД через менеджер драйверов, фактически ничего не зная о типе используемой БД (общение менеджера драйверов и самих драйверов более менее стандартно, так что с точки зрения пользователя все источники данных обладают практически одинаковыми свойствами). Таким образом, вы легко можете поменять физический тип базы данных, а приложение даже не узнает об этом (конечно, существуют исключения из-за особенностей поддержки языка SQL различными типами БД, но они несущественны).



Физически ODBC представляет собой набор динамических библиотек DLL, которые обслуживают подключение и работу с конкретным типом базы данных.При запросе на подключение к определенной, заранее описанной базе «активизируется» определенная DLL — драйвер этого типа БД. Обращение к определенной базе данных происходит по имени так называемого источника данных ODBC (или DSN — data source name). Можно представить DSN как своего рода объявление БД на данном компьютере, причем DSN может быть пользовательским, т.е. находится в области видимости только одного польователя, в сеансе которого был создан этот DSN, и системным, т.е. видимым всеми пользователями данного компьютера.

Управление источниками данных ODBC (да и вообще настройкой всей системы ODBC) осуществляется с помощью специальной программы — ODBC-администратора. Давайте разберем, где его можно найти в различных версиях Windows:

- Windows 9х — сам исполняемый файл odbcad32.exe лежит в каталоге Windows\System. Запускать его можно напрямую либо через Панель управления (значок «Источники данных ODBC (32-бит)»). Если на компьютере установлен BDE, запустите администратор BDE и из меню Object выберите пункт ODBC Administrator.

- Windows 2000 - исполняемый файл odbcad32.exe лежит в каталоге WinNT\System32, а запускать его можно через Панель управления -> Администрирование -> Источники данных ODBC. К сожалению, у меня нет возможности проверить, как с ODBC в NT3.51 / 4 - не думаю, что там ребята из Microsoft сильно его спрятали.

Почему ODBC?

Ведь есть же BDE, скажете вы. Да, возможно вы правы. Однако здесь есть «но». У обоих движков есть свои преимущества и недостатки. ODBC намного лучше работает с «родными, от Microsoft» источниками данных продуктов Microsoft Office — типа Access, Excel, MS SQL Server (вообще-то из-за Access я и затеял всю эту писанину). Кроме того, в стандартный дистрибутив BDE, который можно на каждом шагу найти в Интернете, я что-то ни разу не встречал SQL Links, впрочем, как я ни разу не встречал и отдельного дистрибутива SQL Links. А именно после установки SQL Links в BDE появлется возможность создавать алиасы к Access, MS SQL Server, Oracle и др. типам баз данных. Устанавливать же полную версию C++Builder или Delphi на компьютер пользователя может не каждый. А ODBC на «голой» машине уже содержит драйверы Access, Excel, FoxPro и SQL Server. В общем, для общего развития не помешает освоить и ODBC, тем более что access«овские базы, с которыми мы будем работать через ODBC, очень надежны (не в пример стандартным BDE»шным paradox«овым, у которых то и дело сыпятся индексы, а про такое поле как счетчик я вообще молчу), практически на любом компьютере пользователя установлен Office, что позволяет вносить коррективы «на месте», да и удобство всей базы в одном файле тоже иногда сказывается.

Фнукции, с которыми нам придется работать

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

1. Функция SQLDataSources возвращает список всех источников данных ODBC.

RETCODE SQLDataSources(HENV hEnv, UWORD fDirection, UCHAR * szDSN,
SWORD cbDSNMax, SWORD *pcbDSN, UCHAR * szDescription,
SWORD cbDescriptionMax, SWORD * pcbDescription );
hEnv — хэндл, возвращаемый функцией SQLAllocEnv();
fDirection — задает режим работы. Может принимать значения SQL_FETCH_FIRST — вернуть первую запись и SQL_FETCH_NEXT — вернуть следующую запись. Логика работы аналогична функциям FindFirst и FindNext (помните DOS?);
szDSN — указатель на буфер длиной не менее cbDSNMax, куда будет записано имя источника данных;
cbDSNMax — длина буфера szDSN;
pcbDSN — указатель на целое, куда записывается реальная длина (не включая завершающий \0) принятого имени источника данных;
szDescription — указатель на буфер длиной как минимум 255 символов, куда запистывается описание принятого источника данных;
cbDescriptionMax — длина буфера szDescription;
pcbDescripton — указатель на целое, куда записывается реальная длина описания источника данных.

2. Функция SQLConfigDataSources добавляет, изменяет или удаляет указанный источник данных.

BOOL SQLConfigDataSources(HWND hwndParent, WORD fRequest,
LPCSTR lpszDriver, LPCSTR lpszAttributes)
hwndParent — хэндл родительского окна. Если не равен NULL, отображается стандартный для данного типа источника данных диалог настройки.
fRequest — тип запрашиваемой операции. Может принимать следующие значения:
ODBC_ADD_DSN (ODBC_ADD_SYS_DSN) — запрос на создание нового пользовательского (системного) источника данных;
ODBC_CONFIG_DSN (ODBC_CONFIG_SYS_DSN) — запрос на изменение существующего пользовательского (системного) источника данных;
ODBC_REMOVE_DSN (ODBC_REMOVE_SYS_DSN) — удаление пользовательского (системного) источника данных.
lpszDriver — указатель на строку, содержащую имя драйвера, ассоциированного с конкретным типом БД;
lpszAttributes — указатель на строку атрибутов в форме ключевое слово — значение. Каждая такая пара должна заканчиваться символом \0, в конце строки атрибутов должен стоять двойной символ \0.

Приведем несколько примеров строки атрибутов, чтобы вам было понятно, что это такое:

«DSN=MySource\0UID=MyLogin\0PWD=MyPass» — источник данных с именем MySource, логин — MyLogin, пароль — MyPass

Каждый драйвер «понимает» свои ключевые слова, чаще всего применяются:
PWD — пароль
UID — логин
DSN — имя источника данных
DATABASE — имя базы данных
SERVER — имя сервера, на котором находится база данных

Для баз данных Microsoft Access для указания имени БД вместо DATABASE используется ключевое слово DBQ.

3. Функция SQLAllocEnv создает новый хэндл для использования в других функциях и инициализирует интерфейс для работы с ODBC
RETCODE SQLAlocEnv(HENV * hEnv)

hEnv — указатель на переменную, которая будет хранить созданный хэндл в случае удачного выполнения функции

4. Функция SQLFreeEnv удаляет заданный хэндл и освобождает всю память, ассоциированную с ним.

RETCODE SQLFreeEnv(HENV hEnv)
hEnv — хэндл, который нужно удалить
Исходный код

Сначала несколько замечаний. В C++Builder есть заголовочные файлы для работы с ODBC. Нам нужно два из них — odbcinst.h и sql.h. Добавьте строки
#include
#include

в начало вашего файла. Реализация функций, описанных в этих файлах, находится в нескольких DLL, лежащих в каталоге Windows\System (или WinNT\System32). В наших примерах будут использоваться две такие DLL, а именно odbc32.dll и odbccp32.dll. Чтобы подключить их к проекту, нужно проделать следующие шаги:

1. Запускаем любой досовский файл-менеджер или командную строку Windows и переходим в каталог Windows\System (WinNT\System32) и находим эти две библиотеки.

2. Если каталог BIN С++Builder»а прописан в переменной окружения PATH, просто набираем
c:\[b]windows[/b]\system\> implib odbc32.lib odbc32.dll

иначе набираем полностью путь к файлу implib.exe, либо копируем его в каталог, прописанный в PATH.

3. То же самое проделываем с odbccp32.dll:
c:\[b]windows[/b]\system\> implib odbccp32.lib odbccp32.dll

4. Полученные .lib — файлы копируем в каталог с проектом

5. Из меню Project выбираем пункт Add to Project... и поочередно добавляем odbc32.lib и odbccp32.lib.

Все, теперь система сама загрузит эти DLL во время запуска программы.

Пример 1: Получаем список уже созданных источников данных ODBC.
const short SQL_MAX_DSN_LENGTH=255;

UCHAR szDSN[ SQL_MAX_DSN_LENGTH+1 ];
UCHAR szDescription[ 256 ];
short wDSNLen;
short wDesLen;
int retCode;
SQLHENV hEnv=NULL;
AnsiString DSNName;

SQLAllocEnv( &hEnv );
retCode = SQLDataSources( hEnv, SQL_FETCH_FIRST,
szDSN, SQL_MAX_DSN_LENGTH+1, &wDSNLen,
szDescription, 256, &wDesLen );
while( retCode == SQL_SUCCESS || retCode == SQL_SUCCESS_WITH_INFO )
{
DSNName = (AnsiString)((char *)szDSN);
// -- получили имя DSN в переменной DSNName
retCode = SQLDataSources( hEnv, SQL_FETCH_NEXT,
szDSN, SQL_MAX_DSN_LENGTH+1, &wDSNLen,
szDescription, 256, &wDesLen );
}
SQLFreeEnv( hEnv );

Этот фрагмент кода просто перебирает все уже созданные источники данных. В первой строке фрагмента после объявления переменных создается хэндл текущего сеанса работы с ODBC, затем выбирается первое имя DSN. Если первое имя успешно прочитано (retCode содержит константу SQL_SUCCESS), то в цикле выбирается следующий DSN и т.д. до тех пор, пока не будет прочитан последний DSN. Если на место комментария вставить код (ListBox1 -> Items -> Add(DSNName)), добавляющий прочитанное имя в ListBox, например, то вы сможете просмотреть весь этот список. А если на место комментария вставить что-нибудь типа
if (DSNName==«OurDSN») ...

то мы проверим, сможет ли наша программа работать нормально.

Пример 2: Создаем новый источник данных.

В этом примере вы узнаете, как создать системный DSN для базы данных Access. Предположим, файл с БД лежит в том же каталоге, что и программа, а его имя — db1.mdb.
#include

WORD fRequest = ODBC_ADD_SYS_DSN;
UCHAR lpszDriver[] = «Microsoft Access Driver (*.mdb)»;
UCHAR lpszAttributes[255] = «DSN=c2a;DBQ=»;
bool retCode;
AnsiString CurDir;

CurDir = GetCurrentDir();
StrCat(lpszAttributes, CurDir.c_str());
StrCat(lpszAttributes, «\\db1.mdb»);
retCode = SQLConfigDataSource(NULL, fRequest, lpszDriver, lpszAttributes);
if (retCode == true)
Application -> MessageBox(«DSN успешно создан», «Сообщение», MB_OK);
else
{
Application -> MessageBox(«Произошла ошибка во время создания DSN»,
«Ошибка», MB_OK);
}

Как видите, здесь уже не нужны хэндлы и код достаточно ясный. В первых трех строках — дописываем в строку атрибутов путь к файлу БД. Затем собственно создаем источник. Обработка ошибок тривиальна.

Важное замечание: При создании DSN если такое имя уже есть, то не возвращается ошибка, а создается DSN с текущими параметрами.

Пример 3: Как все это собрать воедино и использовать в программе

Здесь кода не будет, здесь будет описание. Итак, у нас есть программа, которой нужно «присоединиться» к базе Microsoft Access, лежащей совсем рядом, в текущем каталоге. На машине пользователя нам не нужно ничего, кроме стандартного набора bpl и BDE. Но — теперь не нужны SQL Links, можно использовать, например, Install Shield, можно взять отдельный дистрибутив BDE. Поехали:

1. На основную форму проекта кидаем компоненту TDatabase. Устанавливаем ее свойства: LoginPrompt — false, DatabaseName — dbMain, AliasName — c2a (имя источника данных ODBC). Во всех компонентах TQuery или TTable свойство Database Name будет равно dbMain. Конечно, можно не использовать компоненту TDatabase, а в TQuery или TTable прямо указывать имя источника данных ODBC, но представьте, если вы написаи проект формочек на двадцать-тридцать, а потом решили, что имя источника «MySuperDSN» не в полной мере отражает всю вашу крутость :-) Изменять свойство у полусотни компонент — очень муторное занятие, поверьте.

2. В конструкторе основной формы прописываем код примера №1, вставляя на место комментария следующий код:
if (t == «c2a»)
{
Exists = true;
break;
}

а после цикла — такой фрагмент:
if (!Exists)
{
NewDSN();
}

3. Функция NewDSN() полностью повторяет код примера №2.

Теперь при первом запуске программы будет создан источник данных ODBC Microsoft Access с именем c2a, ссылающийся на файл db1.mdb, лежащий в том же каталоге, что и программа.

4. На всякий непредвиденный случай (если вы переместили программу в другой каталог, поменялась буква диска или сетевое имя, где лежит база данных) можно в программе предусмотреть немедленное перезаписывание DSN по горячей клавише, что-то типа такого:
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if (Shift.Contains(ssAlt) && Shift.Contains(ssCtrl))
if (Key==VK_F1)
{
if (Application -> MessageBox(«Перезаписать DSN?»,
«Вопрос»,MB_YESNO)==IDYES)
{
NewDSN();
}
}
}

Здесь для перезаписи DSN используется комбинация Alt-Ctrl-F1

 

Интересное

Использование программы...
Данная статья содержит сведения о бета-версии программного продукта корпорации Майкрософт. Информация в данной статье не является официальной и может быть изменена без предварительного...
Подробнее...
Разработка эффективной...
Саму идею интернет-торговли нельзя назвать новой. Первые российские интернет-магазины появились еще в конце 90-х годов прошлого века. Многие из них работают по сей день. Многих, к сожалению, давно...
Подробнее...
Реализация сети в...
Рассмотрим подробнее что происходит с пакетом при попадании в нашумашину. Сначала он обрабатывается драйвером аппаратуры(сетевой карты и т.д) если пакет предназначен нам то он посылается на выше...
Подробнее...
Я живу в FreeBSD
Нередко приходится слышать рассуждения типа: «FreeBSD — прекрасная серверная платформа, но ей не место на рабочем компьютере. Повседневные задачи среднему пользователю проще выполнять на...
Подробнее...
chmod - изменение режима...
Все чаще обнаруживается, что некоторые начинающие сайтостроители, увлеченные скриптованием (на perl/cgi, php и т.д.) не знают, что такое chmod и как его использовать. В этом кратком руководстве вы...
Подробнее...
Откат обновлений драйверов...
Обновляя драйвер, чтобы решить существующие проблемы или улучшить работу устройства, не стоит забывать, что установка нового драйвера может привести к неожиданным результатам или воспрепятствовать...
Подробнее...
Как сохранить зрение:...
Искусственный свет, светящиеся экраны телевизора и компьютера, электронные игры грубо и бесцеремонно воздействуют на органы зрения, которые постоянно перенапрягаются. Как защитить глаза и помочь...
Подробнее...
Windows PowerShell: Отчет...
Недавно мне пришлось писать довольно длинный и замысловатый сценарий Windows PowerShell, который в ходе работы начал довольно плохо отвечать на запросы. Я написал его для выполнения в качестве...
Подробнее...
Введение в протокол UDP
UDP (User Datagram Protocol, Протокол дейтаграмм пользователя) предназначен для обмена дейтаграммами между процессами компьютеров, входящих в единую сеть с коммутацией пакетов. В качестве...
Подробнее...
Визуальный редактор для...
Наверно мой уважаемый читатель не раз сталкивался с ситуацией, когда конечный веб-проект ориентировался не на узкий круг веб-программистов или людей «введенных» в систему, а...
Подробнее...