ODBC: подробностиДавно тому назад я на страницах "Компьютерных вестей" о технологиях доступа к данным, предлагаемых программистам и пользователям корпорацией Microsoft. Но общих сведений для работы с конкретной технологией не хватит даже самому талантливому программисту, а потому я решил рассказать подробнее о той из них, которая лучше всего себя зарекомендовала, так сказать, на поле боя. И для начала напомню, что же такое, собственно говоря, ODBC.
ODBC расшифровывается как Open Database Connectivity. На русский язык это словосочетание традиционно переводится как "открытый интерфейс взаимодействия с базой данных". Фактически, это программные интерфейсы, которые обеспечивают универсальное для всех СУБД взаимодействие между ними и пользовательским приложением. ODBC - программный интерфейс (API - Application Programming Interface), независимый от языка программирования и даже операционной системы. В общем-то, это всё действительно так, поскольку доступ к библиотекам, реализующим ODBC, например, под Windows, можно осуществлять и на Delphi, и на C++, и вообще практически на чём угодно. Есть даже реализация ODBC под UNIX-подобные платформы - UnixODBC. Интересно, что хотя сейчас многие связывают возникновение ODBC с корпорацией Microsoft, это не совсем так. Изначально технологию разработала компания X/Open. Сейчас ODBC API - международный стандарт, который основан на спецификациях CLI от X/Open и ISO/IEC. Каким образом реализуется поддержка множества СУБД, весьма, порой, разных по своему внутреннему устройству и "родному" интерфейсу доступа? Идея, как и всё гениальное, проста: для этого используется промежуточная прослойка в виде программы-посредника, которая транслирует запросы приложения системе управления базами данных. Такая программа называется ODBC-драйвером. Для каждой СУБД нужен свой драйвер, но программисту, если он нашёл себе нужный, должно быть всё равно, кто и когда его сделал и как при этом мучился - с его точки зрения, интерфейс всех ODBC-драйверов одинаков. Хотя, в общем-то, ODBC - технология гибкая, поэтому вовсе не все возможности в данном конкретном драйвере могут быть реализованы. Для работы с данными приложение использует структурированный язык запросов - Structured Query Language, или, сокращённо, SQL. Такова спецификация ODBC API, и именно в этом состоит секрет её популярности. SQL - самый удобный из придуманных на сегодняшний день способов манипуляции данными. Если диалект, который использует СУБД, отличается от стандартного SQL, то драйвер преобразует запрос "на лету", и программисту не придётся вникать в тонкости запросов для каждой новой версии каждой СУБД. Драйверы могут поддерживать три уровня грамматики SQL. Минимальная грамматика поддерживается всеми драйверами - это запросы Create Table, Drop Dtable Select, Insert, Update Dearch, Delete, Search; типы данных Char,VarChar или Long VarChar. Основная грамматика состоит из минимальной и запросов Alter Table, Create Index, Drop Index, Create View, Drop View, Grant, Revoke Select, а также типов данных Decimal, Numeric, SmallInt, Integer, Real, Float, Double Precision. Третий уровень грамматики - расширенная. Это основная плюс внешние соединения, типы Bit, TinyInt, BigInt, Binary, VarVariant, Long, VarBinary, Date, Time, TimeStamp, а также пакетные операторы SQL и вызов хранимых процедур. Помимо задачи унификации доступа к данным, ODBC попутно решает ещё одну: одновременный доступ к нескольким базам данных. Для этого, помимо самих драйверов, в архитектуре ODBC предусмотрен специальный менеджер драйверов (Driver Manager), который по-русски также называют администратором или диспетчером драйверов. Он позволяет вызывать функции драйверов из прикладного приложения таким образом, что сохраняется возможность одинаково работать с разными СУБД и при этом не волноваться по поводу таблицы указателей на функции. Общую схему архитектуры ODBC можно увидеть на иллюстрации к статье.
Конечно, найти информацию по использованию ODBC легко - например, её полно в MSDN Library. Но эта статья задумывалась как нечто, имеющее практическую пользу, поэтому, думаю, будет совсем не лишним рассказать о практических основах работы с ODBC. Поскольку ODBC для Windows реализована корпорацией Microsoft, она включила поддержку этой технологии в свои библиотеки для разработчиков. Поэтому сейчас мы с вами воспользуемся библиотекой MFC, которая, мягко говоря, знакома всем разработчикам, имевшим дело с Visual C++. Хотя она инкапсулирует и не все функции ODBC API, её для большинства проектов будет вполне достаточно. Для работы с ODBC понадобится включить в приложение заголовочный файл afxdb.h. Класс, который используется для работы с БД через ODBC и имеет название CDatabase. Установка соединения вызывается методом Open, который имеет великое множество параметров: virtual BOOL Open(LPCTSTR lpszDSN, BOOL bExclusive = FALSE, BOOL bReadOnly = FALSE, LPCTSTR lpszConnect = "ODBC;", BOOL bUseCursorLib = TRUE); throw(CDBException, CMemoryException);Однако большую их часть задавать зачастую не обязательно, поскольку значения по умолчанию подходят львиной доле всех ODBC-драйверов. Задать нужно самый главный параметр - первый, lpszDSN. Это строка, которая указывает имя используемого DSN. Сейчас нужно сделать небольшое отступление и объяснить, что скрывается за этими тремя английскими буквами. В данном случае под DSN понимается вовсе не система доменных имён, которая имеет похожую аббревиатуру - DNS, а Data Source Name - имя источника данных. Фактически, DSN - это строка, по которой ODBC определяет местонахождение драйвера, его тип, а также дополнительные параметры, нужные для установки соединения. Использование строковых DSN намного удобнее, чем, например, могло бы быть использование их в виде чисел - думаю, это очевидно. В принципе, источник данных можно и не указывать - тогда при попытке установления соединения у пользователя спросят, какой DSN использовать. И не факт, что он будет знать, как ответить на этот вопрос. Кроме того, если у вас многопользовательская база данных, то ODBC сама спросит у него логин и пароль. Но при желании можно и не перекладывать эту задачу на ODBC, а опрашивать пользователя самостоятельно, меняя параметр lpszConnect на строку вида ""ODBC;UID=ADMIN;PWD=123"", где, естественно, вместо "ADMIN" и "123" должны быть соответствующие имя пользователя и пароль. Для того, чтобы определить, активно ли соединение с базой данных, нужно воспользоваться методом IsOpen всё того же класса CDatabase. Метод этот никаких параметров не имеет, а возвращает значение булевского типа. Для закрытия соединения используется точно метод Close, который также не имеет параметров. Таким образом, минимальный код для работы с БД (в качестве источника данных возьмём, например, навевающий ностальгию Microsoft Access 97) будет иметь следующий вид: cdbMyDB.Open("MS Access 97 Database"); cdbMyDB.Close();В классе CDatabase есть метод, позволяющий узнать параметры уже установленного соединения. Называется он GetConnect, параметров не имеет и возвращает все параметры соединения в том же виде, в каком они устанавливаются методом Open (т.е. на выходе этого метода будем иметь строку вида "параметр1=значение1; параметр2=значение2; параметр3=значение3"). Аналогичным образом получается имя базы данных, с которой установил соединение драйвер, только для этого используется метод GetDatabaseName. Для проверки прав данного пользователя на внесение изменений в базу данных используется булевский метод CanUpdate. Отдельно стоит упомянуть о транзакциях. Они, конечно же, в ODBC имеются, но только не все драйверы их могут поддерживать. Для того, чтобы узнать данную возможность конкретного драйвера, нужно воспользоваться методом CanTransact, который не имеет параметров и возвращает значение булевского типа. В случае, если драйвер признался, что транзакции он всё же поддерживает, то, чтобы их реализовать, перед внесением изменений в БД нужно вызывать метод BeginTrans, а после - CommitTrans для подтверждения транзакции, либо Rollback для её отмены. Все эти методы параметров не имеют и выдают после своей работы булевское значение, которое характеризует успешность их выполнения. Обо всём мы с вами уже успели поговорить, кроме самого важного - то есть, непосредственной работы с данными. Для неё нам понадобится класс CRecordset, который и занимается выполнением SQL-запросов. При создании экземпляра этого класса конструктору в качестве параметра нужно передать экземпляр класса CDatabase. Далее для создания таблицы на основе SQL-запроса нужно воспользоваться методом Open. Однако, углубившись в практику, я забыл, что хотел подробнее рассказать об одном аспекте, который уже упоминал выше.
Глядя на примеры с MFC и на периодические упоминания корпорации Microsoft, можно и забыть о том, что ODBC - технология, вообще-то, кросс-платформенная. Вот потому и хочу я чуть подробнее рассказать о проекте UnixODBC. Цель проекта unixODBC, по словам самих его участников, состоит в том, чтобы разрабатывать и поддерживать unixODBC - API, который призван стать стандартом для ODBC на не-Windows системах. Задача осложняется тем, что реализация ODBC для Windows содержит множество расширений, не предусмотренных стандартом, и их тоже нужно реализовывать. Наилучшие результаты пока что достигнуты в написании UnixODBC под Linux. Библиотеки unixODBC распространяются согласно лицензиям GPL и LGPL, и последняя лицензия для библиотек позволяет применять их в коммерческом программном обеспечении с закрытыми исходными текстами. В настоящий момент, помимо непосредственно библиотек, в рамках проекта написана масса полезных для разработчика утилит и драйверов. Найти всё это можно по адресу . Русскоязычная документация по UnixODBC в Интернете практически отсутствует, если не учитывать некоторое число обзорных статей. Но англоязычной документации много, и, кроме того, для программиста UnixODBC схож с ODBC для Windows. А вот администраторам, конечно, придётся покорпеть над английскими "мануалами". Однако, если unixODBC очень похожа на ODBC из Windows, то другая технология, очень созвучная по названию той, которую мы с вами сейчас рассматриваем, внутри отличается кардинально.
Есть у компании Sun Microsystems торговая марка JDBC. Согласитесь, звучит похоже на ODBC. И есть соблазн считать JDBC реализацией ODBC для языка Java. Однако это совсем не так на самом-то деле. Хотя JDBC очень похожа на ODBC идейно, это совсем другая технология. JDBC, как и ODBC, основана на концепции драйверов, позволяющих получать соединение с базой данных по специально описанному URL. Загрузившись, драйвер сам регистрирует себя и вызывается автоматически, когда программа требует URL, содержащий протокол, за который драйвер "отвечает". Соединение с базой данных описывается классом, реализующим интерфейс java.sql.Connection. Имея соединение с базой данных, можно создавать объекты типа Statement, служащие для исполнения запросов к базе данных на языке SQL. Однако драйверы для ODBC в общем случае не подходят для JDBC, хотя есть и такие драйверы, которые совмещают в себе функции для обеих технологий. Адепты Java говорят, что JDBC позволяет писать приложения быстрее, чем ODBC из-за того, что сам интерфейс объектно-ориентирован. Однако если использовать MFC и другие оо-библиотеки, то можно так же быстро писать приложения и на других языках программирования.
Кто-то может сказать, что ODBC, созданная ещё в 1991 году, уже устарела морально. Однако востребованность этой технологии опровергает все доводы её противников. До сих пор продолжают разрабатываться приложения, которые поддерживают работу с СУБД через ODBC. И их появляется гораздо больше, чем, скажем, для ADO.NET. На мой взгляд, использовать в своих программах такой проверенный временем интерфейс доступа к данным вполне разумно. Объектно-ориентированные библиотеки-обёртки, которых для ODBC написано немало, делают скорость разработки совсем не маленькой. Так что изучайте ODBC, и удачи вам в этом не таком уж и простом деле. Вадим СТАНКЕВИЧ,
Чтобы разместить новость на сайте или в блоге скопируйте код:
На вашем ресурсе это будет выглядеть так
ODBC - это программный интерфейс, который обеспечивает универсальное для всех СУБД взаимодействие между ними и пользовательским приложением |
|