- •Введение
- •Содержание
- •1. Файловые системы
- •История развития
- •Файловые системы, принципы построения
- •Работа с типизированным файлом
- •Недостатки файловых систем
- •Задание
- •Реляционная таблица
- •Определение домена
- •Создание таблиц в среде Microsoft Access
- •Задание
- •Реляционные ключи
- •Связь между таблицами
- •Обеспечение целостности данных
- •Построение схемы данных средствами Microsoft Access
- •Мастер подстановок
- •Задание
- •Концепция ER-модели
- •Задание
- •Первая нормальная форма (1NF)
- •Вторая нормальная форма (2NF)
- •Третья нормальная форма (3NF)
- •Нормальная форма Бойса-Кодда (BCNF)
- •Четвёртая нормальная форма (4NF)
- •Пятая нормальная форма (5NF)
- •Задание
- •Выборка значений из таблиц – SELECT
- •Порядок сортировки – ORDER BY
- •Ограничение набора данных – WHERE
- •Предикат существования EXISTS
- •Агрегатные функции
- •Группировка данных – Group By
- •Псевдонимы столбцов
- •Псевдонимы таблиц
- •Объединение нескольких таблиц
- •Построение запросов в среде Microsoft Access
- •Задание
- •Вставка новой записи – INSERT
- •Редактирование данных – UPDATE
- •Удаление записей – DELETE
- •Задание
- •Основные типы данных SQL-92
- •Язык определения данных – DDL
- •Задание
- •Подготовка отчёта в среде Access
- •Задание
- •3-х уровневая архитектура ANSI-SPARC
- •Создание форм для ввода данных в Microsoft Access
- •Задание
- •Строка соединения ADO
- •Соединение с хранилищем данных, компонент TADOConnection
- •Установка соединения
- •Пример соединения без регистрации пользователя
- •Информирование о БД
- •Задание
- •Базовый класс доступа к данным TDataSet
- •Открытие и закрытие набора данных
- •Обновление набора данных
- •Перемещение по набору данных
- •Создание закладок и переход к закладке
- •Редактирование записей в наборе
- •Фильтрация набора данных
- •Организация поиска данных
- •Взаимодействие с элементами управления данными
- •Задание
- •Поле таблицы – класс TField
- •Классификация полей по функциональному назначению
- •Классификация полей по типу обслуживаемых данных
- •Обращение к отдельному объекту-полю
- •Задание
- •Поля подстановки
- •Вычисляемые поля
- •Организация отношения главная-подчинённая таблица
- •Задание
- •Поля BLOB
- •Задание
- •Источник данных – компонент TDataSource
- •Общие черты компонентов отображения данных
- •Сетка базы данных – компонент TDBGrid
- •Статический текст – компонент TDBText
- •Строка ввода БД – компонент TDBEdit
- •Многострочный текстовый редактор БД – TDBMemo
- •Изображение БД – компонент TDBImage
- •Список БД – TDBListBox
- •Комбинированный список БД – TDBComboBox
- •Флажок БД – TDBCheckBox
- •Радиогруппа БД – TDBRadioGroup
- •Компонент – TDBCtrlGrid
- •Навигатор – TDBNavigator
- •Задание
- •Создание базы данных
- •Удаление базы данных
- •Создание таблиц
- •Пример создания таблиц средствами Transact SQL
- •Создание представлений
- •Задание
- •Определение и использование переменных
- •Операторы управления Transact-SQL
- •Базовые функции Transact-SQL
- •Хранимые процедуры
- •Триггеры
- •Задание
- •Запрос TADOQuery
- •Хранимая процедура TADOStoredProc
- •Транзакции и их изоляция
- •Управление транзакциями и компонент TADOConnection
- •Задание
- •Построение простейшего документа XML
- •Атрибуты
- •Определение документа DTD
- •Задание
73
ровать его, для этого устанавливаем свойство компонента Active в состояние true.
В заключении настроим оставшиеся три компонента.
1. В свойство DataSet компонента DataSource1 передаём имя компонента ADOTable1.
2. В свойство DataSource компонента DBGrid1 передаём имя источника данных
DataSource1.
3.В свойство DataSource компонента DBNavigator1 передаём имя источника дан-
ных DataSource1.
Работа над проектом завершена.
Базовый класс доступа к данным TDataSet
В распоряжение разрабатывающего приложения БД программиста средой Delphi предоставляется более десятка компонентов, позволяющих получить доступ к данным. Однако эта лабораторная работа посвящена изучению ни какого-то отдельного элемента управления, мы рассмотрим предтечу всех компонентов доступа к данным – абстрактный класс TDataSet. Класс нацелен на решение следующих основных задач:
1.Открытие и закрытие набора данных.
2.Перемещение по набору данных.
3.Редактирование записей в наборе.
4.Организация доступа к полям таблиц.
5.Фильтрация набора данных.
6.Обеспечение поиска данных.
Из-за того, что TDataSet возглавляет иерархию классов, предназначенных для доступа к данным, и служит в своём роде первопроходцем в этом направлении, значительная часть объявленных в нём методов не наполнена содержанием – они являются абстрактными.
Открытие и закрытие набора данных
Простейшей проверкой на то, в каком состоянии находится набор данных, может стать контроль свойства:
property Active: Boolean;
Если оно вернёт значение true, то это признак того, что набор данных активен и, как минимум доступен для просмотра. Совместно со свойством работают методы:
procedure Open; // открытие набора procedure Close; // закрытие набора
Перевод в true свойства Active последовательно вызовет события: property BeforeOpen: TDataSetNotifyEvent; //перед открытием property AfterOpen: TDataSetNotifyEvent; //после открытия
Вызов метода Close() (присвоение значения false свойству Active) также вызовет два события
property BeforeClose: TDataSetNotifyEvent;//перед закрытием property AfterClose: TDataSetNotifyEvent; //после закрытия
Обновление набора данных
При необходимости обновления строк в ранее открытом наборе данных программист обращается за помощью к процедуре:
procedure Refresh;
Вызов метода гарантирует, что с этого момента приложение работает с самыми свежими данными. Процедура инициирует два события:
© 2011 г. Д.Л. Осипов
74
property BeforeRefresh: TDataSetNotifyEvent;{генерируется перед началом обновления}
property AfterRefresh: TDataSetNotifyEvent;{генерируется по завершению обновления}
Перемещение по набору данных
Мы уже знаем, что открытый непустой набор данных обеспечивает доступ к своим записям. Текущая запись набора обычно называется активной записью, именно на ней установлен курсор набора. Перемещение курсора приводит к смене активной (текущей) записи. Естественно в классе TDataSet реализован целый ряд методов, обеспечивающих перемещение курсора по набору. К наиболее часто используемым процедурам такого рода стоит отнести:
procedure First; //переход на первую запись procedure Prior; //возврат к предыдущей записи procedure Next; //переход на следующую запись procedure Last; //переход на последнюю запись
Для прыжка сразу на несколько записей понадобится помощь метода: function MoveBy(Distance: Integer): Integer;
В параметр Distance передаётся дистанция, на которую мы хотим переместиться по набору, от текущей записи. Если значение отрицательное, то перемещение осуществляется к началу набора, положительное – к концу. За отправную точку принимается текущая запись набора. Функция возвращает реальное число записей, на которое удалось переместить курсор.
Вызов методов перемещения имеет смысл только в том случае, если набор не пуст. Узнать об этом поможет метод:
function IsEmpty : Boolean;
Если в наборе нет ни одной строки, то функция возвратит true. Если в наборе есть записи, то общее количество доступных строк нам поведает свойство:
property RecordCount : Integer;
Порядковый номер текущей записи храниться в свойстве: property RecNo : Integer;
Это свойство доступно только в компоненте TTable.
Два специальных свойства сигнализируют о местонахождении курсора. Если курсор находится на самой первой записи в наборе, то в True установится свойство:
property Bof : Boolean;//сокр. от англ. “begin of file”
Если курсор окажется на самой последней записи, то в состояние True установится свойство:
property Eof : Boolean;//сокр. от англ. “end of file”
С помощью перечисленных выше свойств часто реализуют циклы, перебирающие все записи внутри набора:
With ADOTable1 Do
Begin
DisableControls; //отключение визуальных элементов управления от набора данных
First;
While EOF<>TRUE Do
Begin
Memo1.Lines.Add(FieldByName(‘Field1’).AsString); Next;
End;
EnableControls; //подключение элементов управления
End;
С перемещением курсора по набору данных связано два события:
property |
BeforeScroll: TDataSetNotifyEvent; |
//перед |
перемещением |
property |
AfterScroll: TDataSetNotifyEvent; |
//после |
перемещения |
© 2011 г. Д.Л. Осипов
75
Создание закладок и переход к закладке
В Delphi реализован простой, но очень эффективный способ запоминания текущего положения курсора (создание закладки) с возможностью последующего перемещения к данной записи. Со сменами версий языка программирования менялось программное решение. В самой первой версии Delphi закладки представляли собой обыкновенные 4-х байтовые указатели. Начиная с 3 версии Delphi, от указателей отказались, и закладка стала описываться строковым типом данных. В современных версиях строковый тип данных сменил массив байт.
type TBookmark = TBytes;
Для того, чтобы запомнить позицию текущей строки набора данных мы вызываем метод:
function GetBookmark: TBookmark;
Функция возвращает данные в переменную-закладку. Для перехода к закладке следует воспользоваться услугами процедуры:
procedure GotoBookmark(Bookmark: TBookmark);
Вместо функций GetBookmak() и GotoBookmark() допускается использовать свойство:
property Bookmark: TBookmark;
Когда необходимость в услугах закладки отпадает, распределённый ресурс освободит метод:
procedure FreeBookmark(Bookmark: TBookmark);
private
BM:TBookmark; //переменная для запоминания закладки
//…
procedure TForm1.btnGetBookmarkClick(Sender: TObject); begin
BM:=ADOTable1.GetBookmark; //помечаем запись закладкой end;
procedure TForm1.btnGoToBookmarkClick(Sender: TObject); begin
if ADOTable1.BookmarkValid(BM)=true then //проверка закладки begin
ADOTable1.GotoBookmark(BM); //возвращаемся к закладке ADOTable1.FreeBookmark(BM); //удаляем закладку btnGoToBookmark.Enabled:=False;
end;
end;
Редактирование записей в наборе
Модификация данных в наборе данных возможна только в ситуации, когда свойство: property CanModify: Boolean; //только для чтения
возвращает значение false. Это признак того, что набор данных возражает против редактирования своих строк.
Получив потенциальное согласие набора данных на внесение изменений, можно добавить в конец набора новую, пустую запись. Для этого используйте метод:
procedure Append;
Если требуется, чтобы новая запись оказалась в месте положения курсора, то применяйте: procedure Insert;
Вызов методов Append и Insert подготовит набор данных к приёму новой записи. Если, например, средством визуализации избрана сетка (TDBGrid), то после вызова функции на экране компьютера пользователь увидит новую пустую строку, готовую к получению данных. Ему останется ввести информацию с клавиатуры. Если Вы не доверяете
© 2011 г. Д.Л. Осипов
76
пользователю, то одновременно с операцией добавления (или вставки) новой строки можно заполнить запись данными. Для этого используют методы:
procedure AppendRecord(const Values: array of const); procedure InsertRecord(const Values: array of const);
Здесь в качестве параметров передаётся массив значений, непосредственно вносимых в таблицу. Будьте внимательны – последовательность значений передаваемых в массиве должна совпадать с физической последовательностью полей в таблице.
Table1.InsertRecord([‘Петров’, ‘Пётр’, ‘Петрович’, Null]);
С процессом вставки новой записи связаны три последовательно возникающие события.
Таблица 12.2
Описание
Вызывается перед вставкой записи.
Вызывается в момент вставки новой записи.
Вызывается по окончанию вставки записи.
Для перевода текущей записи в режим редактирования предназначена процедура: procedure Edit;
С операцией редактирования взаимодействуют события:
property BeforeEdit: TDataSetNotifyEvent; //перед редактированием property AfterEdit: TDataSetNotifyEvent; // после редактирования
Для того, чтобы сохранить внесённые изменения вызывают метод: procedure Post;
with ADOTable1 do begin
Append;
FieldByName('City').Value:= 'Ставрополь'; Post;
end;
Соответствующие процессу сохранения обработчики событий: property BeforePost: TDataSetNotifyEvent; //перед сохранением property AfterPost: TDataSetNotifyEvent; //после сохранения
Метод Post() следует вызывать только в случае, когда в результате редактирования в наборе данных возникли изменения. Узнать об этом поможет свойство:
property Modified: Boolean;//только для чтения
Свойство возвратит True, если набор нуждается в сохранении. И наоборот значение False свидетельствует о том, что набор данных не изменялся.
Для удаления текущей записи используйте метод: procedure Delete;
Процедуру обслуживают события:
property BeforeDelete: TDataSetNotifyEvent; //вызывается перед удалением property AfterDelete: TDataSetNotifyEvent; //после удаления
Для отмены последних изменений в тексте используйте метод: procedure Cancel;
Учтите, что метод Cancel сохраняет работоспособность только до вызова метода Post(). Соответствующие обработчики событий:
property BeforeCancel: TDataSetNotifyEvent; //вызывается перед отменой property AfterCancel: TDataSetNotifyEvent; //после отмены
© 2011 г. Д.Л. Осипов