Задание соединения компонентов ADO с базой данных

Формирование строки соединения

В отличие от компонентов BDE — Table, Query и других, в компонентах ADO нет свойства DatabaseName, указывающего базу данных. Доступ к базе данных осуществляется или с помощью строки соединения — свойства ConnectionString, или с помощью отдельного компонента ADOConnection, имя которого задается в свойстве Connection других компонентов.

Рассмотрим соединение с базой данных с помощью свойства ConnectionString на примере компонента ADOTable. Свойство ConnectionString представляет собой строку, содержащую параметры соединения. Отдельные параметры отделяются друг от друга точками с запятой. ADO поддерживает четыре параметра:

Provider

Имя провайдера, используемое для соединения

File паше

Имя файла, содержащего информацию о соединении

Remote Provider

Имя провайдера, используемое со стороны клиента Remote

Server

Путь и имя сервера

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

Перенесите на форму компонент ADOTable и в Инспекторе Объектов нажмите кнопку с многоточием около свойства СоnnесtionString. Перед вами откроется окно, показанное на рис. 6.1. Верхняя радиокнопка Use Data link File позволяет использовать файл связи .udl. Нижняя радиокнопка Use Connection String, применение которой мы сейчас рассмотрим, позволяет в режиме диалога сформировать строку соединения. Включите эту радиокнопку и нажмите кнопку Build (Сформировать).

НЕ нашли? Не то? Что вы ищете?


Перед вами откроется многостраничное окно задания свойств соединения. Его первая страница Provider показана на рис. 6.2. На этой странице вы должны указать провайдер OLE DB, который собираетесь использовать для доступа к данным. Во многих случаях вас устроит выделенный на рис. 6.2 Microsoft OLE DB Provider for ODBC Drivers. Однако, например, для работы с Microsoft SQL Server или Oracle надо выбрать другие разделы списка.


Выбрав провайдер, вы должны перейти на страницу Connection (рис. 6.3). При нажатии на кнопке Next на странице Provider этот переход свершится автоматически.

На странице Connection вы должны указать, как вы будете соединяться с ODBC. Выбрав кнопку Use data source name, вы можете задать из выпадающего списка имя источника данных (data source name — DSN), зарегистрированного в ODBC. Кнопка Use connection string позволяет вам задать строку соединения самостоятельно, не прибегая к зарегистрированным DSN. Рассмотрим сначала этот путь.

Выберите кнопку Use connection string и нажмите Build. Перед вами откроется окно, представленное на рис. 6.4. В нем вы можете выбрать один из зарегистрированных в ODBC файлов источников данных. Если нужного вам файла источника нет в списке, вы можете добавить его, используя кнопку New. Например, первоначально на вашем компьютере может не быть источников данных ib, Interbase, Paradox, показанных на рис. 6.4. Тогда, чтобы создать новый файл источника, нажмите кнопку New.

Перед вами откроется первое окно создания нового файла источника данных (рис. 6.5). В его списке имеются, в частности, драйверы InterBase и Paradox.

Рис. 6.4

Выбор источника данных

 

Рис. 6.5

Первое окно создания нового файла источника данных

 

Если вы создаете источник данных InterBase, выберите драйвер INTERSWOLV InterBase ODBC Driver (*.gdb). При создании источника данных Paradox выберите драйвер Microsoft Paradox Driver (*.dbf). После того, как выбрали драйвер, нажмите кнопку Далее, и попадете в следующее окно, показанное на рис. 6.6. В этом окне вы можете задать произвольное имя нового источника данных. В примере рис. 6.6 задается имя ib. Нажав кнопку Далее, вы попадете в следующее окно, в котором можете посмотреть и проверить введенные данные. Если что-то вас не устраивает, можете нажать кнопку Назад и вернуться к одному из предыдущих окон. Если все нормально, нажмите кнопку Готово.

Дальнейшее зависит от того, файл какого источник данных вы создаете. Если вы создаете файл источника InterBase, то попадете в окно, показанное на рис. 6.7. В нем вы должны в окошке Database указать файл базы данных, а в окошках User Name и Password указать соответственно имя пользователя и пароль. После того, как вы щелкнете на ОК, будет проведена проверка введенных данных и, если все нормально, то вы опять увидите окно рис. 6.4, но в нем уже будет созданный вами источник данных.

Если вы создаете источник данных Paradox, то после завершения работы с окном рис. 6.6. вы вместо окна рис. 6.7 увидите окно, показанное на рис. 6.8. В нем вы можете уточнить версию драйвера, выбрав ее из выпадающего списка Version. По умолчанию в окне включен индикатор Use Current Directory — использовать текущий каталог. Если его не выключить, то в качестве базы данных будет использоваться текущий каталог. Если же вы выключите этот индикатор, то станет доступна кнопка Select Directory, с помощью которой вы можете указать каталог базы данных. После щелчка на ОК вы вернетесь в окно рис. 6.4, в котором появится созданный вами источник данных.

В окна вида 6.7 и 6.8 вы попадете, если не создавали никакого нового источника данных, а просто выбрали в окне рис. 6.4 один из ранее установленных источников. Отличие только в том, что при этом по умолчанию вам будет предложена информация, которую вы занесли ранее при создании соответствующего файла источника данных.

После того, как в окне рис. 6.4 вы выбрали существовавший ранее или созданный новый файл источника данных, вы вернетесь в основное окно задания свойств соединения на страницу Connection (рис. 6.3). Если вы щелкнете на ОК, то вернетесь в окно рис. 6.1, в котором в нижнем окошке будет записана сформированная вами строка соединения. Для InterBase она может иметь вид:

Provider=MSDASQL. l;Password=l;Persist Security

Info=True;User ID=a;Mode=Read|Write;Connect

Timeout=15;Extended Properties="DRIVER=(INTERSOLV

InterBase ODBC Driver (*.gdb));

UID=A;DB=D:\Database\dbIbase\Ib. gdb;PWD=l";Locale

Identifier=1049;Initial Catalog=D:\Database\dbIbase

Для Paradox сформированная строка соединения может иметь вид

Provider=MSDASQL. l; Persist Security Info=False;

Extended Properties="CollatingSequence=ASCII;

DBQ=D:\DATABASE\DBPAR; DefaultDir-D:\DATABASE\DBPAR;

Driver=1Microsoft Paradox Driver (*.db )}; Driverld=538;

FIL=Paradox 5.X; FILEDSN=C:\Program Files\Common

Files\ODBC\Data Sources\Paradox. dsn; MaxBufferSize=2048;

MaxScanRows=8;PageTimeout=5;

ParadoxNetPath=C:\WINDOWS\SYSTEM; ParadoxNetStyle=3.x;

ParadoxUserName=admin; SafeTransactions=0; Threads=3;

UID=admin; UserCommitSync=Yes;"

Как видите, в результате не слишком сложного диалога сформировались строки, которые иным способом записать было бы весьма трудно.

В окне рис. 6.3 вы можете также занести дополнительную информацию: имя пользователя (User name), пароль доступа (Password), ввести начальный каталог (Enter the initial catalog to use). Введенное вами имя пользователя занесется в строку соединения в виде параметра, например:

User ID=a;

В дальнейшем это имя (в данном примере — «а») будет отображаться в окне запроса пароля при соединении с базой данных. Но пароль сам по себе в строку соединения не занесется, если только вы не включите индикатор Allow saving password. Тогда в строку соединения занесется соответствующий параметр, например:

Password=1;

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

Включение индикатора Blank password также разрешит пользователю при запросе пароля во время соединения с базой данных не вводить пароль. Но при этом, если пароль не запомнен в строке соединения, то с базой данных, защищенной этим паролем, соединение установить не удастся.

Кнопка Test Connection позволяет вам проверить правильность всей информации. При нажатии на эту кнопку происходит соединение с базой данных. Если все нормально, будет показано окно с надписью: «Test connection succeeded», свидетельствующей о нормально произведенном тестировании соединения. Если в сформированной строке соединения что-то неправильно, вам будут выданы сообщения об ошибках.


После завершения формирования строки соединения, вы можете перейти в окне на страницу Advanced (рис. 6.9). Верхние окна (Network setting) позволяют задать режимы работы с сетью. Окно Connection timeout устанавливает в секундах время ожидания завершения соединения. Список Access permissions позволяет установить варианты доступа к базе данных, помечая в индикаторах те операции, которые будут допустимы.

Страница Аll сообщает итоговую информацию о соединении и позволяет ее отредактировать.

После того, как вы завершили все операций по формированию строки соединения, нажмите ОК и сформированная строка появится в свойстве ConnectionString компонента.

Связь друг с другом компонентов ADOTable, работающих с разными таблицами, одна из которых главная, а другая — вспомогательная, осуществляется так же, как в компонентах Table, с помощью свойств MasterSource и MasterFields. Рассмотрим это подробнее.

Две таблицы могут быть связаны друг с другом по ключу. Одна из этих связанных таблиц является головной (master), a другая – вспомогательной, детализирующей (detail). Например, мы хотим построить приложение, в котором имеется таблица Dep, содержащая список подразделений учреждения (поле Dep). И хотим, чтобы пользователь, перемещаясь по этой таблице, видел не только характеристику подразделения, но и список сотрудников этого подразделения, то есть записи из таблицы Pers, в которой значение поля Dep совпадает со значением поля Dep в текущей записи первой таблицы.

В этом случае головной является таблица Dep, вспомогательной – таблица Pers, а ключом, определяющим их связь, являются поля Dep из обоих таблиц.

Пример установки связи между таблицами

Откройте новое приложение. Перенесите на форму компонент ADOTable. Его имя будет ADOTable1. Установите в его свойстве ConnectionString соединение с базой данных ib. В свойстве TableName установите таблицу Dep, с которой должен быть связан этот набор данных. Установите в true значение свойства Active, чтобы проверить правильность соединения. Сделайте двойной щелчок на ADOTable1, чтобы перейти в редактор полей . Щелкните в Редакторе полей правой кнопкой мыши, выберите в контекстном меню пункт Add fileds и добавьте в список полей поле Dep. Перенесите на форму компонент DataSource. Его имя будет DataSource1. Свяжите его с ADOTable1 c помощью свойства DataSet. Перенесите на форму компонент DBComboBox. Назовите его CBDep. Этот компонент будет отображать выпадающий список подразделений. Свяжите его с DataSource1 с помощью свойства DataSource. Свяжите его с полем Dep с помощью свойства DataFiels. Таким образом сформирована обычная цепочка «набор данных – источник данных – компонент отображения данных». Перенесите на форму еще один компонент ADOTable. Его имя будет ADOTable2. Установите в его свойстве ConnectionString соединение с базой данных ib. В свойстве TableName установите таблицу Pers, с которой должен быть связан этот набор данных. Установите в true значение свойства Active, чтобы проверить правильность соединения. Перенесите на форму второй компонент DataSource. Его имя будет DataSource2. Свяжите его с ADOTable2 c помощью свойства DataSet. Перенесите на форму компонент DBGrid. Его имя будет DBGrid1. Этот компонент будет отображать списоксотрудников. Свяжите его с DataSource2 с помощью свойства DataSource. Сделайте двойной щелчок на ADOTable2, чтобы перейти в Редактор полей. Щелкните в окне редактора полей правой кнопкой мыши и выберите в контекстном меню пункт Add fileds. Выберите все поля, кроме поля Num. Для каждого поля установите в окне Инспектора объектов русский заголовок в свойстве DisplayLabel. Для полей Charact, Photo, Dep установите в false свойство Visible, поскольку эти поля не должны отображаться в таблице. Для остальных полей установите удобное значение ширины каждой колонки таблицы в свойстве DisplayWidth. Перенесите на форму компонент DBRichEdit, в котором будет отображаться характеристика сотрудника. Свяжите его с DataSource2 с помощью свойства DataSource. Свяжите его с полем Charact с помощью свойства DataField. Перенесите на форму компонент DBImige, в котором будет отображаться фотография сотрудника. Свяжите его с DataSource2 с помощью свойства DataSource. Свяжите его с полем Photo с помощью свойства DataField. Перенесите на форму навигатор DBNavigator. Свяжите его с DataSource2 с помощью свойства DataSource. Сделайте в навигаторе невидимыми все кнопки, кроме навигационных. Перенесите на форму обычное окно редактирования Edit, которое будет использоваться для ускоренного поиска сотрудника по его фамилии. Удалите текст в его свойстве Text. Перенесите на форму метки и задайте в них требуемые поясняющие надписи. Задайте в компоненте ADOTable2 упорядочивание данных. Это можно сделать, задав в свойстве IndexFieldNames строку DEP;Fam;Nam;Par.
Теперь нужно связать друг с другом два набора данных. Из этих двух наборов головным должен быть ADOTable1, отображающий таблицу Dep. Вспомогательным будет ADOTable2, который должен отображать список сотрудников того подразделения, которое выбрал пользователь в наборе ADOTable1. Разорвите связь набора ADOTable2 с базой данных, установив в false свойство Active, так как устанавливать связь наборов данных можно устанавливать только при неактивном вспомогательном наборе. Установите в ADOTable2 в свойстве MasterSource значение DataSource1. Тем самым указывается, что головным является набор, с которым связан DataSource1. Теперь надо установить ключ связи. Нажмите в окне Инспектора объектов кнопку с многоточием около свойства MasterFields. В результате откроется окно редактора связей полей (Data Link Designer). В этом окне слева в списке Detail Fields расположены имена полей вспомогательного набора данных. Справа в списке Master Fileds расположены поля головной таблицы. В обоих списках нужно выделить ключевое поле (Dep). При этом активизируется кнопка Add, и после щелчка на ней ключевые поля переносятся в окно Joined Fields – соединяемые поля. Если бы ключ состоял из нескольких полей, эту операцию нужно было бы повторить для других полей ключа. В конце формирования связей щелкните на OK и в свойстве MasterFields компонента ADOTable2 появится текст – связанные поля. Записать в этом свойстве соответствующее значение можно сразу, не прибегая к редактору связей полей. Разорвите связь набора ADOTable1 с базой данных, установив в false свойство Active.

Проектирование формы на этом закончено. Теперь надо написать обработчики ряда событий. В момент начала выполнения приложения надо обеспечить связь наборов данных с базой данных и заполнить строки списка CBDep именами подразделений, содержащихся в таблице Dep. Кроме того, в этот список надо добавить строку «все отделы».

18.  В обработчик события формы OnCreate нужно добавить код:
AdoTable1.Open;
AdoTable1.First;
CBDep. Clear;
while not AdoTable1.EOF do begin
CBDep. Items. Add(AdoTable1Dep. AsString);
AdoTable1.Next;
end;
CBDep. Items. Add(‘Все отделы’);
CBDep. ItemIndex:=0;
AdoTable1.First;
AdoTable2.Open;
Этот код устанавливает соединение с базой данных и заносит в цикле в свойство Items компонента CBDep значения полей, содержащиеся в объекте поля ADOTable1Dep (значение поля Dep в таблице Dep). Окончание цикла определяется функцией EOF – конец таблицы. В заключение в список добавляется строка «все отделы». Индекс списка устанавливается в 0, чтобы первоначально в окне отображалась первая строка.

19.  В обработчик события формы OnDestroy добавьте операторы:
ADOTable1.Close;
ADOTable2.Close;
Эти операторы по окончании работы приложения разрывают связь с базой данных.

20.  В обработчик события OnChange списка CBDep добавьте код:
with ADOTable2 do
if CBDep. ItemIndex=CBDep. Items. Count-1 then begin
MasterFields:=’’;
IndexFieldNames:=’Fam;Nam;Par’;
ADOTable2Dep. Visible:=true;
end else begin
MasterFields:=’Dep’;
IndexFieldNames:=’Dep;Fam;Nam;Par’;
ADOTable2Dep. Visible:=False;
end;
// передача фокуса, чтобы отобразились изменения
DBGrid1.SetFocus;

В начале этого кода проверяется текущее значение индекса ItemIndex выпадающего списка CBDep. Если он соответствует последней строке списка («все отделы»), то связь вспомогательного набора данных с головным разрывается (очищается свойство MasterFields компонента ADOTable2), набор данных ADOTable2 индексируется по алфавиту и делается видимым поле Dep, отображающее отделы, в которых работают сотрудники. Если индекс списка CBDep не соответствует строке «все отделы», то связь вспомогательной и головной таблиц восстанавливается (свойство 1MasterFields в компоненте ADOTable2 становится равным Dep), в индекс добавляется поле, необходимое для связи, и это поле делается невидимым, чтобы в этом режиме оно не отображалось в таблице. В заключение фокус передается таблице, чтобы в ней немедленно отобразились изменения в наборе данных.

В обработчик события OnChange компонента Edit1 добавьте код:
if Edit1.Text<>’’ then
if CBDep. Text = ‘все отделы’then ADOTable2.Locate
(‘Fam’,Edit1.Text,[loCaseInsensitive, loPartialKey])
else ADOTable2.Locate
(‘Dep;Fam’,VarArrayOf([CBDep. Text, Edit1.Text]),
[loCaseInsensitive, loPartialKey]);

Этот код проверяет, занесены ли в поле редактирования какие-нибудь символы. Если занесены и в списке CBDep выделена строка «все отделы», то методом Locate производится поиск записи, в которой поле Fam’хотя бы частично совпадает с введенными символами. Если в списке выделена другая строка, то тем же методом ведется поиск записи по двум полям: Dep и Fam.