Изменение структуры таблицы и индексирование полей
Для быстрого поиска нужных записей в таблице часто применяют индексные файлы. В них содердится информация о значениях одного или нескольких полей, упорядоченная по значениям этих полей. Одновременно содержится и номер записи в основной таблице, где содержится соответствующее значение поля или полей. Такие файлы небольшие и автоматически сортируются для поддержки актуального состояния. Это избавляет от необходимости физически сортировать саму таблицу с данными. Зато можно создавать несколько индексных файлов для одной и той же таблицы, где записи будут упорядочены по нужному полю для быстрой их выборки из основного поля.
Если индекс создается по ключевому полю, то он называется первичным, индексы для других полей называются вторичными.
Создадим несколько индексных файлов для таблицы SCHOOL.dbf.
Индикатор Maintained обеспечивает режим автоматического изменения индекса при редактировании связанной таблицы.
После щелчка по кнопке OK появится окно с предложением определить имя индекса
-
Оставьте значение по умолчанию, равное имени индексируемого поля.
-
Аналогичным образом создайте индекс для поля BIRTHDAY
После создания двух индексов окно Database Desktop должно выглядеть так
-
Щелкните по кнопке Save и сохраните результаты редактирования.
-
Зайдите в каталог размещения базы и убедитесь, что появился новый файл для хранения созданных индексов
Обзор компонентов C++Builder 6, используемых для связи с локальными базами данных
Взаимодействие с базой данных обеспечивается рядом визуальных и невизуальных (неотображаемых во время выполнения программы) компонентов, размещенных во вкладках палитры компонентов оболочки C++Builder 6. Главным посредником, осуществляющим обмен информацией между компонентами визуализации данных и компонентами, непосредственно связанными с базой данных, является компонент DataSource (источник данных). Он находится во вкладке Data Access палитры компонентов
Другие компоненты, которые нам в дальнейшем понадобятся и которые обеспечивают непосредственную связь с данными при реализации механизма BDE, находятся во вкладке BDE палитры компонентов
Связь этих компонентов друг с другом и локальной базой данных можно представить схемой
Компоненты "Наборы данных" ( data set ) непосредственно связываются с базой, руководствуясь информацией псевдонима, в котором вместе с местом расположения таблиц указан тип используемого драйвера. К этой группе относятся такие компоненты как Table, Query, StoredProc, BDEClientDataSet. Они находятся во вкладке BDE.
Нам не потребуются компоненты Query или StoredProc до тех пор, пока мы не начнем писать свои собственные SQL -процедуры или обращаться к процедурам, хранимым на сервере. Можно и без SQL открывать таблицы баз данных в любом из локальных или удаленных форматов, поддерживаемых C++Builder, используя только компонент Table.
Компонент "Источник данных" ( data source ) осуществляет обмен информацией между компонентами "Наборы данных" и компонентами визуализации и управления данными. Этот компонент так и называется DataSource (вкладка Data Access ). С данными базы непосредственно работают компоненты набора данных, но они не могут передать данные непосредственно интерфейсным компонентам. Эта передача осуществляется через посредника - DataSource.
К интерфейсным компонентам визуализации и управления данными относятся DBGrid, DBText, DBEdit, DBListBox, DBComboBox, DBCheckBox и множество других. Все они находятся во вкладке Data Controls. Интерфейсные компоненты работают на стороне пользователя. Они отображают данные на экране в удобной форме и позволяют их изменять. Они представляют собой аналоги элементов управления, используемых в обычных приложениях. Интерфейсные компоненты также обращаются к данным через посредника DataSource.
Помимо указанных компонентов в приложении может размещаться компонент Database. Этот компонент в основном используется в сетевых приложениях, работающих на платформе клиент/сервер. Он обеспечивает некоторые дополнительные возможности, которые мы вольны использовать или неиспользовать, такие как: общение с удаленным сервером, реализацию транзакций и работу с паролями. Но в то же время он не является неотъемлемой частью приложения, работающего с базой данных. C++Builder автоматически создает экземпляр Database для каждой используемой в приложении базы данных, как и экземпляр компонента Session. Оба этих компонента находятся во вкладке BDE.
Нам не потребуется компонент Session до тех пор, пока мы не начнем разрабатывать многопоточные приложения для работы с базами данных. Многопоточные приложения открывают одновременно несколько каналов выполнения. Это означает, что несколько операций могут выполняться в одно и то же время. Обычно приложения, работающие с базами данных, не делают многопоточными, поэтому редко приходится создавать и использовать компонент Session явно.
Основные свойства компонента Table
Основным компонентом, непосредственно работающим с данными, является Table. Он устанавливает соединение между приложением и таблицей с данными, а также используется для добавления, изменения и удаления строк в таблице базы данных. Имеет свойства, часть из которых доступна в режиме проектирования, а часть - программно при выполнении приложения.
Основные свойства компонента Table |
Свойство |
Описание |
Active |
Открывает и закрывает соединение с таблицей.
Если в режиме проектирования значение свойства установить в true, то можно увидеть "живые данные" таблицы, что во многих случаях является удобным для разработчика приложения. Но в законченном приложении во всех таблицах это свойство нужно установить в false, а в событии OnCreate() формы приложения поместить код с установлением этого свойства в true, что откроет соединение с соответствующей таблицей.
В событии OnDestroy() формы приложения нужно установить значение свойства вновь в false, что обеспечит закрытие соответствующих файлов базы данных и предотвратить неоправданный расход ресурсов в системе, а при работе в сети - устранит преграду доступа к таблице со стороны других пользователей. |
AutoCalcFields |
Определяет способ вычислений с использованием полей |
Bof, Eof |
Bof - показывает, находится ли курсор таблицы перед первой записью, Eof - показывает, находится ли курсор таблицы после последней записи. Эти свойства принимают значение true только тогда, когда курсор выходит за пределы строк таблицы при вызове методов Prior() или Next(). При открытии таблицы свойство Bof также устанавливается в true автоматически. |
CachedUpdates |
Определяет, будут ли кэшироваться обновленные данные |
DatabaseName |
Определяет псевдоним BDE, используемый для соединения с базой данных. |
Exclusive |
Определяет, могут ли другие пользователи обращаться к данной таблице |
FieldCount |
Возвращает количество полей в таблице |
FieldDefs |
Содержит редактируемый список используемых в приложении полей таблицы |
Fields |
Возвращает указанное по индексу поле со всеми характеристиками |
Filter |
Определяет выражение, используемое для фильтрации записей |
Filtered |
Определяет, какой способ фильтрации используется: указанный в Filter или OnFilterRecord
|
FilterOptions |
Управляет работой фильтров |
IndexDefs |
Выдает информацию об индексах базы |
IndexFieldCount |
Возвращает число полей в текущем индексном ключе |
IndexFieldNames |
Указывает поля, используемые в качестве индексного ключа |
IndexName |
Указывает имя используемого индекса |
IndexFields |
Возвращает указанное по индексу массива поле индексного файла со всеми характеристиками |
KeyExclusive |
Инвертирует действие функций поиска и установки диапазона |
KeyFieldCount |
Указывает количество ключевых полей, используемых для поиска |
MasterFields |
Указывает главные поля в отношении "главный/подчиненный |
MasterSource |
Указывает главный источник в отношении "главный/подчиненный" |
Modified |
Показывает, была ли данная запись изменена с момента последнего обновления базы методами Post или Cancel
|
ReadOnly |
Устанавливает режим только чтения данных из источника |
RecordCount |
Возвращает количество записей в источнике данных |
SessionName |
Указывает, какой компонент используется для соединения с базой данных |
State |
Возвращает состояние источника данных |
TableName |
Указывает физическое имя файла сопоставленной таблицы |
TableType |
Указывает тип локальной таблицы |
UpdateMode |
Определяет тип SQL, используемый для изменения данных |
UpdateObject |
Определяет компонент UpdateSQL для использования совместно с кэшируемыми изменениями |
Основные методы компонента Table
Основные методы компонента Table |
Метод |
Описание |
AddIndex() |
Создает новый индекс |
Append() |
Добавляет пустую строку к источнику данных, и переводит его в режим редактирования |
AppendRecord() |
Добавляет строку, используя указанные значения |
ApplyRange() |
Активизирует диапазон, установленный методами Set() или EditRange()
|
ApplyUpdates() |
Сохраняет кэшированные изменения в базе данных |
BatchMove() |
Копирует группу строк из одного источника в другой |
Cancel() |
Отменяет ожидаемое изменение текущей строки |
CancelRange() |
Отменяет установки, сделанные методами Set() или EditRange()
|
CancelUpdates() |
Отменяет ждущие изменения, занесенные в кэш |
ClearFields() |
Устанавливает для полей текущей строки значения по умолчанию |
Close() |
Закрывает источник данных |
CommitUpdates() |
Уведомляет кэш о сохранении изменений |
CreateTable() |
Создает новую таблицу |
Delete() |
Удаляет в таблице текущую запись |
DeleteIndex() |
Удаляет вторичный индекс |
DeleteTable() |
Удаляет соответствующую физическую таблицу в базе данных |
Edit() |
Переводит источник данных в режим редактирования |
EditKey() |
Позволяет изменять значения ключа поиска |
EditRangeEnd() |
Позволяет изменять верхний ключевой предел диапазона |
EditRangeStart() |
Позволяет изменять нижний ключевой предел диапазона |
EmptyTable() |
Удаляет все строки в источнике данных, оставляя только заголовок |
EnableControls() |
Разрешает использование интерфейсных компонентов визуализации и управления |
FetchAll() |
Считывает все ожидающие своей очереди строки базы данных |
FieldByName() |
Возвращает объект типа TField, используя имя поля в базе данных |
FindFirst() |
Осуществляет поиск первой записи по условию фильтрации |
FindNext() |
Осуществляет поиск следующей записи, соответствующей заданному критерию. |
FindKey() |
Выполняет точный поиск в источнике данных |
FindNearest() |
Выполняет приближенный поиск с частичным совпадением в источнике данных |
GetFieldNames() |
Возвращает список полей в источнике данных |
GetIndexNames() |
Возвращает список открытых индексов |
GotoKey() |
Выполняет точный поиск в источнике данных по ключу |
GoteNearest() |
Выполняет приближенный поиск в источнике данных по ключу |
Insert() |
Вставляет пустую строку перед текущей и позволяет ее редактировать |
InsertRecord() |
Вставляет строку, используя заданные значения столбцов |
Locate() |
Осуществляет поиск записи последовательным перебором
|
LockTable() |
Блокирует локальную таблицу для монопольного использования |
Lookup() |
Осуществляет поиск записи в источнике и возвращает значения ее полей |
MoveBy() |
Перемещает логический курсор источника данных на заданное количество записей |
Open() |
Открывает источник данных |
Post() |
Сохраняет ждущие изменения текущей строки, очищая кэш |
RenameTable() |
Переименовывает локальную таблицу |
RevertRecord() |
Отменяет кэшированные изменения текущей строки |
SetKey() |
Переводит источник данных в режим поиска по ключу |
SetRange() |
Переводит источник данных в режим поиска по диапазону |
SetRangeEnd() |
Устанавливает верхний предел диапазона |
SetRangeStart() |
Устанавливает нижний предел диапазона |
UnlockTable() |
Разблокирует локальную таблицу от монопольного использования |
Основные события компонента Table
Основные события компонента Table |
Событие |
Условие возникновения |
AfterCancel |
После вызова Cancel
|
AfterClose |
После закрытия источника данных |
AfterDelete |
После вызова Delete
|
AfterEdit |
После вызова Edit
|
AfterInsert |
После вызова Insert
|
AfterOpen |
После открытия источника данных |
AfterPost |
После вызова Post
|
BeforeCancel |
Перед выполнением Cancel
|
BeforeClose |
Перед закрытием источника данных |
BeforeDelete |
Перед выполнением Delete
|
BeforeEdit |
Перед выполнением Edit
|
BeforeInsert |
Перед выполнением Insert и Append
|
BeforeOpen |
Перед открытием источника данных |
BeforePost |
Перед выполнением Post
|
OnCalcField |
При необходимости ввода значений в вычисляемые поля |
OnDeleteError |
При ошибке удаления записи |
OnEditError |
При ошибке редактирования записи |
OnFilterRecord |
В режиме фильтрации, когда источник данных требует строку |
OnNewRecord |
При добавлении новой записи в источник данных |
OnPostRecord |
При ошибке сохранения записи |
OnUpdateError |
При ошибке во время сохранения кэшированных изменений |
OnUpdateRecord |
При сохранении каждой строки с помощью ApplyUpdates
|
Создание заготовки приложения
Создадим приложение, в котором реализуем управление созданными ранее таблицами, входящими в состав базы данных.
-
Создайте новый проект и сразу сохраните его в своем каталоге выполнения лабораторной работы. Для этого имя файла user1.cpp измените на uAppBDE, а имя проекта Project1.bpr измените на AppBDE. Это имя в дальнейшем будет иметь исполнимый файл проекта приложения
-
Поместите на новую форму следующие компоненты
Компонент |
Вкладка палитры компонентов |
MainMenu |
Standard |
Table |
BDE |
DataSource |
Data Access |
DBGrid |
Data Controls |
-
Настройте свойства компонентов, как приведено в таблице
Таблица свойств главной формы приложения AppBDE |
Элемент управления |
Свойство |
Значение |
Главная форма |
Name |
MainForm |
|
Caption |
Приложение управления базой данных |
|
Width |
555 |
|
Height |
375 |
----------------------------------------------------------------------------------------------------- |
MainMenu |
Name |
MainMenu |
TMenuItem |
Name |
File |
|
Caption |
Файл |
----------------------------------------------------------------------------------------------------- |
Table |
Name |
School |
|
DatabaseName |
DBSchool |
|
TableName |
SCHOOL.DBF |
|
Active |
true |
----------------------------------------------------------------------------------------------------- |
DataSource |
Name |
School DataSource1
|
|
DataSet |
|
----------------------------------------------------------------------------------------------------- |
DBGrid |
Name |
DBGrid1 |
|
DataSource |
DataSource1 |
|
Align |
alClient |
-
Отредактируйте заголовки полей таблицы. Для этого через контекстное меню компонента Table или двойным щелчком на этом компоненте в форме вызовите редактор полей Fields Editor. Щелкните на нем правой кнопкой мыши и через контекстное меню выполните команду Add all fields
-
Редактор полей заполнится списком полей таблицы. Выделяя последовательно каждое поле в редакторе полей, измените свойство DisplayLabel в соответствии с таблицей. Это будут заголовки полей, отображаемые для пользователя на экране.
Заголовки полей в представлении таблицы SCHOOL |
Field |
DisplayLabel |
|
|
|
|
|
|
|
|
|
|
|
|