Средства Delphi 7 для доступа к данным

Каждая из версий Delphi приносит какие-либо новшества в работу с базами данных. Так, в Delphi 5 ярким примером такой новации может являться поддержка техно­логии ADO. В Delphi 6 также были включены многие новые возможности, в том числе и для работы с базами данных. А именно:

  • в Delphi 6 добавлен принципиально новый механизм доступа к данным, назы­вающийся dbExpress. Он обеспечивает исключительно быстрый и простой до­ступ к серверам баз данных;
  • наборы данных в Delphi бегали поддерживать два новых типа полей::TFMTBCDFiefd и TSQLTimeStampField;
  • добавлено несколько новых компонентов для упрощения работы с клиентскими наборами данных, а также с двухъярусными и многоярусными приложениями баз данных.

Рассмотрим перечисленные выше особенности Delphi 6 более подробно.

 

dbExpress представляет собой совокупность небольших по размеру драйверов, ко­торые обеспечивают быстрый доступ к серверам баз данных, поддерживающих язык SQL. Список допустимых типов баз данных вы можете найти в табл. 3.1.Для каж­дой из баз данных dbExpress предоставляет определенный драйвер. Таким образом, если вы планируете распространять свое приложение, то в него нужно будет вклю­чить дополнительный файл драйвера, который представляет собой обычную биб­лиотеку динамической компоновки (DLL).

Разберемся, какой из файлов библиотек вы должны будете включить в комплект поставки вашей программы. В таблице3.1 перечислены типы баз данных и биб­лиотеки динамической компоновки, необходимые для работы с ними. 

Таблица 3.1. Типы поддерживаемых баз данных

 

Имя файла
InterBase
DBEXPINT.DLL
DB2
DBEXPDB2.DLL
Orade
DBEXPORA.DLL
DBEXPMYS.DLL

Новый тип поля TFMTBCDField обеспечивает истинный двоично-десятичный фор­мат поля. Напомним, что в Delphi 5использовался тип TBCDField, который хранил двоично-десятичные данные в формате Currency. Данный тип переводил данные формата Currency в BCD (Binary-Coded Decimal) инаоборот. 

 

ПРИМЕЧАНИЕ: Для поддержки нового типа поля процедуры СиггТоВСО и ВСОТоСигг были перемещены из модуля ОВ в модуль РМТВСО. 

Другой новый тип поля TSQLTimeStampReld предназначен для поддержки времени и даты в формате, требуемом драйверам dbExpress.

 

Были добавлены три новых клиентских набора данных: 

  1. TBDECIientDataSet;
  2. TSQLCIientDataSet;
  3. TIBCIientDataSet 

Эти компоненты предназначены для простых приложений и объединяют в себе поставщик данных и набор данных. Если создаваемое приложение требует много­кратного обновления данных с сервера или использует отношение «главный—под­чиненный» между таблицами, то лучше всего использовать вместо указанных кли­ентских наборов.данных внешний поставщик данных и отдельный клиентский набор данных.

Компонент TCIientDataSet в Delphi 6 обладает тремя новыми-свойствами:

  • ConnectionBroker — применяется в случае, когда у вас в приложении имеется не­сколько наборов данных, которые задействуют одно и то же соединение с сер­вером базы данных. Данное свойство позволяет централизованно, с помощью изменения только одного значения, изменять значения свойства у всех набо­ров данных, использующих данное соединение;
  • DisableStringTrim — позволяет контролировать ввод символов пробела в значе­ниях, которые заносят пользователи в поля таблиц. Данное свойство имеет буле-выйтип. Если значение свойства — true, то данные сохраняются в поле таблицы в том виде, как их вводит пользователь, в ином случае все пробелы, вводимые пользователем, будут отсечены;
  • XMLData — позволяет получить доступ из клиентского набора данных к XML-данным.

Новый набор компонентов позволяет вам работать с XML-документами. Мы их рассмотрим в последующем.

Кроме того, в Delphi 6 была реорганизована палитра компонентов. Компоненты, которые основаны на BDE (Borland Database Engine, процессор баз данных Borland), перемещены на отдельную закладку BDE. Добавлены новые закладки: InterBase Admin, dbExpress и DataSnap. Об этих закладках и их компонентах читайте далее в этой главе.

Среда Delphi 7 также привнесла изменения в работу с базами данных: 

  • Драйверы dbExpress теперь стали поддерживать Informix SE, Oracle 9i, DB2 7.2, InterBase 6.5 и MySQL 3.23.49. Кроме того, был добавлен новый драйвер для Microsoft SQL 2000.
  • Корпорация Borland решила отказаться от использования SQL Links. Начиная с 2002 года SQL Links не будет развиваться и включаться в состав Delphi. Для реализации доступа к серверам баз данных SQL корпорацияBorland рекомен­дует использовать механизм dbExpress.
  • Файл Borland Database Engine (BDEINST.CAB) больше не имеет цифровую подпись. Этот файл включается в поставку Delphi лишь для обеспечения со­вместимости программ, созданных в ранних версиях Delphi.
  • Произошли изменения в некоторых компонентах для работы с базами данных и были добавлены новые:
    • в свойстве DefauttRowsetSize компонентаTSQLDataSet (вкладка dbExpress) те­перь установлено значение по умолчанию, давное 20;
    • вместо компонента TSQLClientDataSet введен новый компонент TSimpteDataSet, находящийся на вкладкеdbExpress палитры компонентов

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

Набором данных называется совокупность записей, выделенных по определенным правилам из одной или нескольких физических таблиц базы данных.

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

Итак, из всего вышесказанного можно сделать вывод, что нам при создании при­ложений баз данных придется работать в основном с наборами данных (или логи­ческими таблицами).

 

ВНИМАНИЕ: Во многих других системах управления базами данных вместо термина набор данных ис­пользуются выборка или таблица

Среда Delphi имеет несколько стандартных компонентов для работы с наборами данных. К их числу относятся такие компоненты, как Table, Query, StoredProc и дру­гие. Работа со всеми этими компонентами будет подробно описана далее.

 

Доступ к данным в Delphi обеспечивает класс TDataSet, который представляет набо­ры данных в виде совокупности строк и столбцов. Строки являются записями, а столбцы — полями таблицы базы данных. Класс TDataSet обеспечивает возмож­ность редактирования набора данных, а также предоставляет средства для переме­щения (навигации) по записям. Многие из свойств, событии и методов класса TDataSet являются абстрактными. Они называются абстрактными, так как не могут быть использованы непосредственно классом TDataSet, а лишь в его классах-потомках.

 

Прямым потомком класса TDataSet является класс TBDEDataSet. Этот класс инкап­сулирует в себе функциональные возможности Borland Database Engine (BDE) — процессора баз данных фирмы Borland.

 

BDE — это совокупность файлов дина­мических библиотек (DLL) и драйверов, которые отвечают за доступ к данным. Для более подробного знакомства с BDE обратитесь к занятию 4.

 

Класс TBDEDataSet имеет класс-потомок TDBDataSet, в котором определены допол­нительные свойства и методы, обеспечивающие возможность связывания набора данных с физическими таблицами базы данных.

 

Далее мы рассмотрим два компонента Table и Query, которые являются потомками клас­са TDBDataSet Мы изучим их общие свойства на примерах операций с наборами дан­ных. Эти компоненты расположены на закладке BDE палитрыкомпонентов Delphi 7.


Свойство Active имеет тип Boolean и позволяет открывать или закрывать набор данных. Его можно установить в окне инспектора объектов, но чаще всего такие операции с наборами данных производят во время выполнения приложения, на­пример:


 

Более подробно о свойстве Active рассказывается ниже.

Свойство DatabaseName имеет тип String и задает полный путь к каталогу базы дан­ных, например: ADatabaseVMyDBF.В значении этого свойства можно указать вме­сто пути к каталогу базы данных ее псевдоним.

 

Псевдоним (alias) представляет собой специальное имя для обозначения каталога базы данных и применяется для указания местонахождения файлов базы данных.

Более подробно о работе с псевдонимами мы расскажем на четвертом занятии.

 

Все существующие псевдонимы для баз данных будут показаны в окне инспекто­ра объектов при щелчке левой кнопкой мыши на поле со списком напротив свой­ства DatabaseName.

СОВЕТ: Старайтесь всегда использовать псевдонимы, так как это позволит вам легко изменять мес­тоположение файлов базы данных, не меняя кода программы. После изменения местополо­жения файлов достаточно будет изменить название каталога, на который ссылается псев­доним базы данных

Для компонента Table допустимо применение только свойства DatabaseName при задании пути к базе данных. КомпонентQuery имеет дополнительную возможность: в запросе SQL можно задать путь доступа к любой из таблиц базы данных.

Рассмотрим, как задается путь к нужной базе данных во время работы приложения:

  1. необходимо установить свойство Active компонента Table или Query в false (закрыть набор данных);
  2. затем указываем путь к базе данных либо ее псевдоним;
  3. после чего можно открыть набор Данных, присвоив свойству Active значение true:

Свойство TableName компонента Table имеет тип String и содержит имя текущей табли­цы базы данных.

В терминах Delphi каталог — это база данных, а файлы каталога — таблицы.

 

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


 

Свойство RecordCount имеет тип Longint и содержит число записей, находящихся в текущий момент времени в наборе данных. Значение данного свойства не отобра­жается в окне инспектора объектов — оно доступно только для чтения во время выполнения приложения. Строка 

Edit1. Text:=IntToStr(Tablel.RecordCount); 

выводит в компонент Editi количество записей набора данных Table1.

Свойство RecNo имеет тип Longint и содержит номер текущей записи набора дан­ных. Это свойство также доступно только для чтения во время работы приложе­ния. Для перемещения по записям набора данных используются вызовы соответ­ствующих методов: First, Last, Next, Prior и MoveBy:

 


 

Если вы используете в своем приложении таблицы Paradox, то можно напрямую про­изводить ввод чисел в свойство RecNo для перехода на нужную запись набора данных: 

Table1.RecNo:=15:   // Переход на 15-ю запись набора данных
 

Как мы уже видели ранее, наборы данных могут принимать два состояния: откры­тое или закрытое. При установке свойства Active в true набор данных будет открыт. Для закрытия набора данных нужно присвоить свойству Active значение false.

 

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

 

ВНИМАНИЕ: При изменении свойств DatabaseName или TableName необходимо обязательно закрыть на­бор данных, чтобы избежать исключительной ситуации.

Кроме того, вы можете открыть набор данных с помощью вызова метода Open и закрыть с помощью методаClose:

 


 

Вызов этих методов имеет смысл, если вы хотите выполнить какие-либо действия перед открытием или после открытия набора данных, а также перед закрытием или после закрытия.

 

Итак, метод Open открывает набор данных. При вызове данного метода генерируются событияBeforeOpen и AfterOpen. Вы можете написать программы-обработчи¬ки этих событий. Это очень полезно, если вы хотите не открывать набор данных до тех пор, пока не выполнились какие-либо условия. Ниже представлен пример такого обработчика: 


В данном примере, если переменная а не имеет значение true, открытие набора данных Table1 будет прервано. Это достигается вызовом процедуры Abort, в результате работы которой генерируется исключительная ситуация и операция открытия данных отменяется.
При этом на экран не будет выведено никаких сведений об ошибках. Естественно, вы можете добавить команды вывода сведений для пользо¬вателя о том, что данные недоступны.

Примером использования события AfterOpen может служить приведенный ниже листинг:

Здесь после открытия набора данных выводится текстовое сообщение о готовно­сти таблицы к работе. Имя таблицы содержится в свойстве TableName.

Метод Close закрывает набор данных. При его вызове генерируются события Before-Close иAfterClose. 

ВНИМАНИЕ : При закрытии набора данных необходимо принудительно сохранять сделанные изменения в текущей записи с помощью вызова метода Post, так как метод Close автоматически не сохра¬няет данные текущей записи.

Можно использовать обработчик события BeforeClose для вызова метода Post:


 

В данном примере сначала осуществляется проверка, в каком режиме находится набор данных Table1, при помощи значения свойства State. Если он находится в режи­ме вставки новой записи (dslnsert) или редактирования текущей записи (dsEdit), то перед закрытием набора данных все внесенные изменения сохраняются. 

 

ВНИМАНИЕ:  При выходе из приложения несохраненные данные теряются, и обработчик события Before-Close не вызывается. 

К обработке события AfterClose можно прибегать для выдачи пользователю сооб­щения о закрытии набора данных.

 

В примере использования события BeforeClose мы упомянули о режиме набора дан­ных (свойствеState). Остановимся на этом немного подробнее. Наборы данных в разные моменты времени могут находиться в различных режимах, например неак­тивном, фильтрации данных, вставки, редактирования и т. д. Программист может читать значение свойства State, но изменять его напрямую нельзя. Для того чтобы перевести набор данных в один из режимов, нужно либо вызвать соответствую­щий метод, либо воспользоваться адекватными визуальными компонентами, речь о которых пойдет ниже.

 

Перечислим возможные режимы, в которых может находиться набор данных. Их всего тринадцать:

  • dslnactive — неактивный. В этом режиме набор данных является закрытым и доступ к данным невозможен;
  • dsBrowse — режим просмотра. Данный режим устанавливается по умолчанию для любого открытого набора данных. В этом режиме данные могут свободно просматриваться, но никаких изменений в них внести нельзя;
  • dsEdit — режим редактирования. В этом режиме возможно только редактирова­ние текущей (активной) записи набора данных;
  •  
  •  dslnsert — режим вставки. В данном состоянии активной является новая запись, которую можно редактировать, а затем либо принять изменения (post) либо от­менить их (discard);
  •  dsSetKey — режим поиска, который доступен только для компонентов Table и ClientDataSet. В этом режиме происходит отбор записей, которые соответству­ют некоторому критерию. Можно просматривать ограниченный набор данных (соответствующих критерию), но нельзя их редактировать или вставлять но­вые записи;
  •  dsCalcFнelds — расчет вычисляемых полей, в процессе которого невычисляемые поля таблицы не могут быть отредактированы и нельзя вставлять новые запи­си. Этот режим использует событие OnCalcFields;
  •  dsFilter — режим фильтра. В этом режиме показываются только те данные, кото­рые соответствуют фильтру, при этом невозможно редактировать или встав­лять записи. Режим использует событие OnFilterRecord;
  • dsNewValue — режим доступа к свойству Newvalue. Данный режим является вре­менным;
  • dsOldValue — режим доступа к свойству OldValue. Также является временным;
  • dsCurValue — режим доступа к свойству Curvalue. Как и предыдущие, временный режим;
  • dsBlockRead — режим чтения блока данных. В этом режиме при переходе на сле­дующую запись набора данных (при вызове метода Next) все визуальные ком­поненты, отображающие данные, не обновляются и не происходят никакие со­бытия;
  • dsIntemalCalc — режим внутренних вычислений. Временный режим, в нем значения полей, свойствоTFIeld.ReldKind которых установлено в fklnternalCalc, вычисля­ются;
  • dsOpening — режим открытия набора данных. Подразумевает состояние еще не завершенного открытия набора данных. Этот режим активируется, когда набор данных открывается для асинхронной выборки.

Поле набора данных представляет собой столбец таблицы. В среде Delphi преду­смотрен специальный объект Reнd для работы с полями. Данный объект имеет тип TField. Наследниками этого объекта являются TlntegerField, TFIoatField и т. д. Для того чтобы программист мог работать с отдельными полями набора данных, в Delphi определены специальные методы и свойства, которые мы и рассмотрим.
Свойство FieldCount имеет тип Integer и содержит число полей данного набора дан­ных. Свойство доступно только для чтения. Приведем пример чтения значения свойства FieldCount: 
a:=Table1.FieldCount; //а- переменная типа Integer
 

ВНИМАНИЕ: Количество полей набора данных может не быть равным числу полей физической таблицы базы данных, так как в набор данных могут быть не включены некоторые поля таблицы.

Свойство Fields имеет тип TFields и хранит список всех несоставных полей набора данных. Его можно представить себе в виде массива, который содержит поля набора данных, каждое под своим номером (индексом). Вы можете обращаться к конкрет­ному полю набора данных при помощи указания его индекса(Index). Нумерация индексов начинается с нуля и заканчивается значением FieldCount-1. Если прило­жению известен тип данных конкретного поля, то его значение можно прочитать с помощью свойства Fields:

Edit1.Text:=Таble1.Fields.Fields[l].AsString;

 

Кроме того, допускается запись значения в нужное поле набора данных:

 

Вы, вероятно, обратили внимание на то, что при вставке в поле значения мы при­менили такое свойство объекта Field, как AsString. Данное свойство позволяет обра­щаться к содержимому поля как к строковому значению. Кроме рассмотренного свойства, имеются еще несколько:

  • Aslnteger — обращение как к целой величине,
  • AsFloat — как к вещественной,
  • AsVariant — как к вариантной,
  • AsCurrency — как к де­нежной,
  • AsDateTime — как к «дате-времени» и
  • AsBoolean — обращение как к логи­ческому (булевому) значению. 
ВНИМАНИЕ: При доступе к полю набора данных нужно всегда четко представлять, какого оно типа. Так как, например, если вы обращаетесь к строковому полю с использованием свойства AsFloat, возникнет исключительная ситуация. 

Обращение к полям по их номеру не всегда эффективно, поскольку номер поля — величина не постоянная.

Номера полей зависят от многих факторов:

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

Поэтому доступ к полю по его номеру чреват ошибками. На практике для доступа к полям разработчики чаще всего используют методы FindField и FieldByName.

Метод

FindField (const FleldName: string): TField;

обнаруживает поле по его имени.

dle

Помоги проекту! Расскажи друзьям об этом сайте: