А-ля, А-си, ADO
АрхивПрограммазм (архив)ActiveX Data Objects. Сегодня вы уже не помните, в каком формате хранятся ваши данные.
Интро
Речь сегодня пойдет о совсем другой музыке. Скажите мне, как вы подступаетесь к своим данным, и я скажу, совместимы ли вы с современными технологиями. Помните, были такие технологии, как ODBC, DAO, BDE ? Если уже забыли, то, надеюсь, эта статья поможет вам пополнить свои знания об ADO. Если же сегодня вы планируете свое ультрасовременное приложение с подступом к данным по ODBC, лучше остановитесь и прочтите новое название: ActiveX Data Objects.
"Ну вот, еще одно API для доступа!", - скажете вы, - "Сколько можно?". Вот я говорю, что нельзя больше. Технология ADO призвана к тому, чтобы унифицировать доступ к данным средствами единых объектов и интерфейсов. Теперь можно дружно забыть про DAO, ODBC и прочих. Все это теперь доступно новыми средствами, построенными на базе автоматизации. Более того, выходящие в свет продукты Microsoft все больше и больше ориентируются на такой механизм доступа. Сегодня содержимое Active Directory из состава Windows 2000 или содержимое папки "Входящие" на Microsoft Exchange 2000 может быть без проблем обработано каким-нибудь VBScript, ловко манипулирующим несколькими объектами, при этом не нужно подключать громадные библиотек - автоматизация работает.
А как оно работает
ADO базируется на технологии более низкого уровня - OLE DB. Эта технология позволяет манипулировать с данными независимо от их формата, типа или расположения. OLE DB поддерживает SQL запросы, транзакции и "курсоры" и множество других мощных техник для работы с базами данных. Курсор представляет собой указатель на текущую запись в массиве записей (record set). Существуют различные способы позиционирования курсора. Например, forward-only, когда курсор может двигаться по массиву данных только от первой записи к последней. Это позволяет увеличить скорость доступа к данным, когда нужно быстро прочитать или перебрать все их содержимое.
Рис 1. Схема доступа к данным
Роль посредника между программой и данными выполняет OLE DB provider. Он реализует все техники, декларируемые OLE DB для работы со своим типом массива данных. Используя ADO/OLE DB, необходимо лишь указать имя провайдера, а затем работать с данными в общем виде.
Объектная модель
Объектная модель ADO стала гораздо проще, чем у DAO.
Рис.2 Объектная модель
Основой всему является объект Connection. Этот объект отвечает за создание соединения с OLE DB provider, который указывается в параметрах по имени.
Объект Command указывает на строки SQL, хранимые процедуры а также различные команды, понятные провайдеру.
Объект Recordset содержит и позволяет манипулировать группой записей, собранной по запросу. Поля каждой отдельной записи хранятся в объекте Fields.
Объект Errors содержит коллекцию ошибок, которые могут возникать при работе с данными.
ADO для доступа к базам Access
Теория закончилась, теперь займемся кодированием. В примерах этой статьи я буду пользоваться Visual Basic (VBScript), хотя в конце статьи укажу на шаги, необходимые для подключения ADO к проектам на Visual C++.
Итак, положим, у нас есть база прайс-листа компании, который должен выкладываться на интернет сайт и позволять производить выборки по различным типам товаров, цене, названию и чему угодно еще.
Рис.3 Поля базы данных goodsdata.mdb
Для того, чтобы получить доступ к этой базе, нужно создать объект connection, открыть связь с необходимым провайдером при помощи метода Open и запросить необходимые данные, используя SQL.
Чтобы приведенный ниже пример нормально запустился, нужно поставить ссылку на библиотеку ADO из пункта References, меню Projects. В списке надо найти строку "Microsoft ActiveX Data Objects 2.x Library", где x - 0, 1 или 5.
Dim cnn As New ADODB.Connection Dim rst As New ADODB.Recordset cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=C:\goodsdata.mdb; " rst.Open "SELECT * FROM Goods", cnn rst.Close cnn.Close
Если вы хотите получить доступ к ADO из скрипта, где, как известно, никакого пункта References нет, нужно создать объект connection из его progid.
Dim oConn ' Создать соединение до базы данных Set oConn = CreateObject("ADODB.Connection") ' Открываем при помощи connection string, ' определяющей тип провайдера и путь до базы oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=c:\goodsdata.mdb;" ...
К слову, ADO версии 2.5 на сегодняшний день - the cutting edge, что означает "на острие технологий". Эта версия позволяет манипулировать не только с данными, но и выводить наборы иерархических (tree-structured) данных в XML. Также реализован механизм разноразмерных записей, дающий возможность сохранения в одном recordset записей с различным количеством и типами полей.
rst.Open "select * from Goods", cnn ' Сохранить в файл в XML формате. ' Для VBScript/JScript вместо adPersistXML ' используйте 1 rs.Save "goods.xml", adPersistXML
Об иерархических данных и о некоторых изменениях в объектной модели ADO 2.5 я расскажу в одной из следующих статей.
Очевидно, что теперь, манипулируя языком SQL можно создавать совершенно невообразимые запросы на выборку из базы. Осталось только эти данные прочитать.
Перемещаться по рекордсету можно при помощи курсора. Основные методы и свойства для этого в рекордсете :
- MoveFirst
передвигает курсор на первую запись - MoveNext
передвигает курсор на следующую запись - MoveLast
передвигает курсор на последнюю запись - RecordCount
возвращает количество записей - BOF
возвращает true, если курсор находится в начале рекордсета - EOF
возращает true, если курсор находится в конце рекордсета - Find
находит запись по определенному критерию, начиная от положения курсора.
... Category = "VIDEO_CARD" ' Выбрать только видеокарты из ' всего множества товаров rst.Open "SELECT * FROM Goods WHERE Class='" & _ Category & "' ORDER BY Title", cnn rst.MoveFirst Do while (Not rst.eof) List1.AddItem rst.Fields("Title") & " : " & _ rst.Fields("Price") rst.MoveNext Loop Rst.Close
Добавление и обновление записей в recordset можно осуществлять запросами SQL UPDATE и INSERT INTO.
' Записи, подвергшиеся изменению Dim AffectedRecords AS ADODB.Recordset ' Мы больше не работаем с компанией BadBoy: Set AffectedRecords = cnn.Execute("UPDATE Goods SET Available=0 " & _ "WHERE Vendor='BadBoy'")
Visual C++
Здесь не на много все сложнее. В заголовочном файле программы нужно указать путь до библиотеки типов ADO и включить заголовочный файл oledb.h:
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename("EOF", "EndOfFile") #include <oledb.h> ... // Определить указатели на recordset // и соединение _RecordsetPtr pRstGoods = NULL; _ConnectionPtr pConnection = NULL; // Определить connection string _bstr_t strCnn("Provider=Microsoft.Jet.OLEDB.4.0;" "Data Source=c:\goodsdata.mdb;"); try { pConnection.CreateInstance(__uuidof(Connection))); pConnection->Open(strCnn,"","",NULL); pRstGoods->Open("SELECT * FROM Goods", _variant_t((IDispatch *)pConnection,true), adOpenKeyset, adLockOptimistic, adCmdTable); // а дальше, вперед, на борьбу с таблицами, // методами, описанными выше. ...
На самом деле, для программ на C++, ADO RecordSet экспортирует интерфейс под названием IADORecordBinding, который позволяет при помощи метода BindToRecordset сделать mapping от записи ADO на структуру Visual C++. Очень удобно, знаете ли ;-). За подробными разъяснениями милости прошу в MSDN документацию.
На этом краткий экскурс в основы ADO завершим. Несколько следующих статей будут посвящены технологиям, использующим ADO для доступа к данным, так что можно считать полученные сегодня знания фундаментальными.
Обсуждение статьи - в форуме "Обсудим "СофтТерру"