Доступ через ODBC из Delpi7.

В создаваемом клиентском приложении необходимо связать с созданным источником данных объекты доступа и объекты отражения. Например, программируя в среде Delphi, вы можете найти на вкладке DataAccess элемент управления DataSource На вкладке DataControl объекты отражения данных из внешних источников. Это – специализированные элементы управления: DBGrid, DBNavigator, DBCombobox и т.п. Их можно поместить на форму. Разберем последовательность необходимых действий.

Итак, создайте новый проект с формой. В этой форме нам надо показать какую-нибудь таблицу из одной базы данных. Сначала надо установить связь с базой данных. Это делается в два этапа. Сначала следует полностью определить, где берутся данные, а затем - как они отображаются. Где брать данные тоже задается в два этапа: сначала на форму помещается элемент управления «таблица», а затем элемент управления «источник данных». Итак, поместите на форму элемент управления Table (DBTable) - таблица базы данных. Этот элемент управления вы найдете во вкладке BDE. Сообщите, что вы связываетесь с таблицей через ODBC - соединение. Для этого в свойствах укажите DataBaseName, то есть выберите имя заданного вами ранее ODBC - соединения. А затем найдите в свойствах TableName и задайте это свойство. Если вы установили верно соединение, то при высвечивании доступных значений для DataBaseName вы обязательно увидите имя вашего соединения. А после его задания в списке имен таблиц при задании TableName вы увидите имена всех таблиц и запросов вашей базы данных. Это еще не все. Рекомендуется дать осмысленное имя вашему элементу управления (а не Table1). Не используйте русские буквы при этом.

Теперь надо задать источник данных для объектов отображения. Для этого во вкладке DataAccess найдите элемент управления DataSource и тоже поместите его на форму. Свяжите его с элементом управления «таблица», задав свойство DataSet. Измените имя элемента управления на некоторое осмысленное.

Для показа строк таблицы следует выбрать элемент управления DBGrid. Его вы найдете во вкладке DataControls. Свяжите этот элемент управления с источником данных (свойство DataSource), дайте ему хорошее имя. Проверьте, все ли правильно связалось. Для этого свойству Active в таблице (Table) задайте значение True. Если все хорошо, вы сразу увидите в Grid строки вашей таблицы. Затем лучше вернуть прежнее значение этого свойства, т.е. False.

Запустите программу. Что вы видите? Свойство Active таблицы делало видимыми строки таблицы. Программным путем лучше всего не прямо изменять это свойство, а выполнить метод Open таблицы. Очевидно, в нашем случае открытие таблицы надо сделать при показе формы, то есть при обработке события OnActivate формы. Напишите этот текст. При закрытии формы закрывайте таблицу.

Возможно, вам покажется удобным расположить под Grid панель стандартных элементов управления с кнопочками «вперед», «назад», «в начало» и т.п. Найдите соответствующий элемент управления DBNavigator во вкладке DataControls, приклейте его к нижнему краю своей формы. Свяжите этот элемент управления с вашим источником данных, т.е. укажите свойство DataSource. Проверьте работу. Попробуйте добавлять и удалять строки, посмотрите на результат в Access.

Доступ к базам данных с помощью технологий ADO.

Соединение, курсор

Рассмотрим задачу: из базы данных, созданной в MS Access извлечь данные и поместить часть из них на форме, а часть – на листе MS Excel. Для решения этой задачи можно воспользоваться объектами ADO.

Важно! Этими объектами можно пользоваться и для управления текущей базой данных, т.е. в модулях базы данных.

Объекты ADO не связаны в иерархическую схему. Между ними, скорее сеть. Тем не менее, выделяется один главный объект – Connection – соединение. Его метод Open выполняет действия по организации связи с базой данных. Для того чтобы его применить, сначала необходимо создать объект, внести в его свойства параметры соединения, наконец, выполнить метод Open.

Dim adoConn As ADODB.Connection

Set adoConn = CreateObject("ADODB.Connection")

objConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\111.mdb;Mode=ReadWrite|Share Deny None;Persist Security Info=False"

adoConn.ConnectionTimeout = 15

adoConn.CommandTimeout = 30

adoconn.CursorLocation = ADODB.adUseClient

'Подключаемся к базе данных (т.е. открываем БД)

adoConn.Open

В приведенном фрагменте самое утомительное – написать строку соединения. Можно несколько облегчить этот процесс и даже сделать его немного осмысленнее. Для этого сначала создайте пустой текстовый файл с произвольным именем и расширением udl (User Data Link), например, «try.udl». Затем дважды щелкните по этому файлу в проводнике (или Total Commander). Операционная система покажет вам окно с несколькими вкладками «Поставщик», «Подключение», «Дополнительно», «Все». Перейдите сначала на вкладку «Поставщик» и выберите требуемое программное средство. Достаточно часто можно по наименованию догадаться, кого выбрать, т.к. в имени обычно присутствует имя сервера базы данных. Если это не так, ищите в документации и справочных пособиях. Например, если вам необходимо подключиться к базе данных в формате MS SQL Server, выберите Microsoft OLE DB Provider for SQL Server). Для подключения к базе данных Oracle выберите Microsoft OLE DB Provider for Oracle. Для подключения к базе данных Access нужно выбрать Microsoft JET 4.0 OLE DB Provider. Затем переходим на вкладку «Подключение». Вид этой вкладки для разных поставщиков (провайдеров) разный. В случае подключения к базе MS Access вас попросят выбрать файл с базой данных при помощи кнопки «Обзор». Здесь же вы можете задать имя пользователя, от которого будет устанавливаться соединение, пароль. На вкладке «Дополнительно» можно задать некоторые параметры сетевого соединения, тип соединения (только для чтения или с возможностью изменения). На вкладке «Все» приведен весь перечень параметров, даже не указанных на предыдущих вкладках. Скорее всего, вам не потребуются две последние вкладки. Проверить правильность задания параметров можно, нажав на кнопку «Проверить подключение», расположенную на вкладке «Подключение». Если не выдано сообщение об ошибке, вы все сделали разумно. Разобравшись с файлом try.udl, откройте его в блокноте (или другом текстовом редакторе), скопируйте третью строку (она длинная, до конца файла!) и вставьте скопированное в программу, присвоив ее objConn.ConnectionString.

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

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

Параметр CommandTimeout задает максимальное время ожидания выполнения команды. Будьте осторожны, если вы зададите слишком маленькое время, его может не хватить для выполнения некоторого сложного и объемного запроса. Если же вы зададите слишком большое время, то система в случае ошибки долго не будет выдавать сообщение.

Далее в программе должны следовать операторы работы с установленным соединением. Мы их пока пропустим. В конце программы (всей программы, например, по закрытию формы) следует корректно закрыть соединение. Это выполняется следующим образом: закрываем соединение методом Close, освобождаем объектную переменную, присвоив ей значение Nothing.

adoConn.Close

Set adoConn = Nothing

Пользуясь открытым соединением, можно получить набор записей, который содержится в объекте RecordSet. Сначала необходимо объявить объектную переменную, создать экземпляр объекта. Затем надо установить параметры получаемого набора и открыть его.

Dim adors As New ADODB.Recordset

adors.ActiveConnection = objConn

adors.CursorType = ADODB.adOpenForwardOnly

adors.LockType = ADODB.adLockReadOnly

Сначала надо сообщить, по какому соединению будут отыскиваться наборы записей.

Тип курсора CursorType задает возможные направления перемещения по набору записей, а также определяет, будут ли в данном наборе отражаться изменения, сделанные другими пользователями. С этим параметром дело обстоит весьма непросто. В документации содержатся некоторые описания возможностей набора заданного типа, но в действительности все обстоит не так, как описано.

Во-первых, складывается впечатление, что типы Dynamic и Forward Only просто не реализованы! Причем не только для удаленного доступа, то есть для клиентского приложения, реализованного в некотором стороннем приложении, но и для локального, то есть из программы, встроенной в базу данных! В этом можно убедиться, написав программу, в которой делаются попытки создать курсор того или иного типа (задается значение параметра CursorType перед методом Open), потом набор открывается (метод Open), а затем анализируются возможности набора.

На основе проведенных вышеописанным способом экспериментов выяснено следующее. Если задается значение CursorLocation равным adUseClient, всегда после открытия набора тип курсора становится равным Static, независимо от того, какое было задано значение типа курсора перед открытием набора. Если задается значение adUseServer, всегда после открытия набора тип курсора становится равным KeySet. Но следует помнить, что при расположении курсора на стороне клиента мы получаем курсор, в котором верно показывается количество записей, доступны операции добавления, сортировки, фильтрации, поиска, возможно использование закладок. Если же расположение курсора задано adUseServer, то сортировка по данному курсору невозможна никогда. Добавление записей, поиск и фильтрация всегда доступны. А свойство recordCount и возможность работы с закладками Bookmark доступны, если перед методом Open мы задавали тип курсора равным KeySet или Static и недоступны, если задавали Dynamic или ForwardOnly.

В результате проведенных сообществом разработчиков экспериментов было выяснено, что заявленного повышения производительности при использовании курсора типа ForwardOnly не происходит.

Неполная и неясная реализация характерна не только для свойства CursorType. Особенно неприятно то, что в ADO изменены некоторые правила, привычные для программистов, ранее пользовавшихся технологией DAO.

Одно из таких отличий: разное определение метода Close для объекта Recordset. В технологии DAO метод Close аналогичен присваиванию объектной переменной класса RecordSet значения Nothing. В ADO этот метод не уничтожает объект. С закрытым объектом невозможно работать обычным образом, для него неприменимы методы перемещения по записям, выборка значений полей и т.п. Но многие свойства набора остаются сохраненными, например, условие фильтрации, сортировки. С таким подходом можно было бы согласиться, если бы, во-первых, существовал бы метод Clear – очистка этих свойств. Но главное, если бы при открытии набора по другой таблице свойства разумным образом изменялись. Реально вы можете неожиданно для себя, открыв набор, увидеть не все ожидаемые записи. Но хуже всего то, что при попытке открыть набор по другой таблице генерируются разные странные сообщения об ошибках. С другой стороны можно отнестись к этому, как к преимуществу. Если вы хотите одинаково отобрать записи из разных таблиц (или разными командами Select), то вам предлагается механизм, экономящий программный код. Тем не менее, если вы не собираетесь пользоваться свойствами набора, то закрытие его необходимо выполнять в два этапа: сначала вызвать метод close, а затем присвоить переменной типа RecordSet значение Nothing.

Если полагаться на рекомендации, даваемые сообществом разработчиков, «нет никаких весомых причин, по которым вам необходимо отказываться от технологии DAO и переходить на ADO».

Далее приводятся возможные значения параметров соединения по документации:

adOpenForwardOnly – движение только вперед, изменения не видны. Самый быстрый тип, но и самый ограниченный. Многие свойства объекта при этом значении параметра CursorType недоступны, например RecordCount (количество записей).

adOpenStatic – движение и вперед и назад, изменения других пользователей не видны.

adOpenKeyset – движение в произвольном направлении, видны изменения полей, произведенные другими пользователями, но не видны добавления и удаления записей.

adOpenDynamic – движение в произвольном направлении, видны изменения полей, произведенные другими пользователями, также видны добавления и удаления записей.

Тип блокировки – свойство LockType – дает возможность изменять набор, определяя, когда эти изменения будут переданы другим пользователям.

adLockReadOnly – не изменяемый набор.

adLockPessimistic – набор изменяемый, причем запись блокируется (становится недоступной для изменения других пользователей) как только текущий пользователь начинает ее редактировать.

adLockOptimistic – набор изменяемый, запись блокируется только при вызове метода Update.

adLockBatchOptimistic – набор изменяемый, запись блокируется только при вызове метода Update для обновления пакета записей.

Расположение курсора CursorLocation – параметр, указывающий, на чьей стороне будет расположен (буферизован) курсор. Возможные значения – на стороне клиента adUseClient или на стороне сервера adUseServer

Важно! Параметры объекта RecordSet могут противоречить параметрам объекта Connection. Очевидно, что если соединение вы установили только для чтения, то создать изменяемый набор записей не удастся.

Наконец, можно выполнить метод Open. Параметр метода – либо имя таблицы (хранимого запроса), либо строка с текстом SQL-запроса.

adors.Open "вид_доставки"

Или так:

adors.Open "Select * from вид_доставки"

Можно задавать свойства получаемого набора записей и параметрами метода Open. Есть одна характеристика, которую можно задавать только параметром метода Open, это – Option. Этот параметр характеризует источник записей для набора. Можно задать adCmdText, что означает, что первый параметр метода Open - строка с SQL-запросом. adCmdTable – утверждение, что первый параметр – имя таблицы, и провайдер генерирует SQL-запрос, выбирающий строки таблицы. adCmdTableDirect – означает, что устанавливается связь или ссылки прямо на записи таблицы. adCmdStoredProc – обращение к хранимой процедуре.