Автор работы: Пользователь скрыл имя, 26 Января 2013 в 14:13, лекция
Программирование баз данных - очень большой и серьезный раздел самого что ни на есть практического программирования. На предыдущем курсе "Введение в программирование на Delphi" мы лишь коснулись этой темы, затронули даже не верхушку айсберга под названием Базы Данных, а только его макушку. Между тем, многие программисты большую часть своего времени тратят именно на проектирование баз данных и разработку приложений, работающих с ними. Это неудивительно - в настоящее время каждая государственная организация, каждая фирма или крупная корпорация имеют рабочие места с к
Да
Нет
В свойстве DataSource компонента выберите таблицу FoodT, а в свойстве DataField - поле FVeget. Сохраните проект, скомпилируйте и посмотрите, как он работает. Теперь пользователю не нужно вписывать значение - он может выбрать его из списка.
Для полей других типов свойство DisplayValues недоступно. Вместо него предлагается использовать свойство DispalyFormat, которое доступно только для числовых полей и полей типа TDataTime. При этом формат задается так же, как в функциях формата, например, FormatFloat() и FormatDateTime(), применение которых подробно рассматривалось на курсе "Введение в программирование на Delphi". Например, для поля типа Дата формат:
dddd dd mmm yyyy
выведет дату в формате "Понедельник 04 Янв 2010"
Aligment - Определяет выравнивание выводимого значения. Может иметь следующие значения:
AsXXXX - Группа свойств этого типа преобразует значение поля к нужному типу. Вместо XXXX могут быть использованы:
Пример:
DBText1.Field.AsString := 'Santa Cruz Wharf';
Calculated - Содержит True, если значение поля вычисляется в обработчике OnCalcFields набора данных, и False в противном случае.
CanModify - Содержит True, если значение поля можно изменить, и False в противном случае.
Currency - Свойство доступно у вещественных полей. Если свойству при проектировании приложения присвоить True, то значения будут выходить в денежном формате.
DataSize - Содержит размер данных.
DataType - Содержит тип данных, определяемый перечислением TFieldType, например, ftString - строка, ftBoolean - логический тип, ftFloat - вещественный тип, и так далее. Класс TFieldType содержит достаточно большой список типов полей, более подробные данные вы можете посмотреть в справочной системе Delphi.
DisplayLabel - Позволяет ввести строку - заголовок отображаемого столбца. Если заголовок не задан, по умолчанию будет использоваться имя поля.
EditMask - Позволяет указать строку - маску для ввода данных.
FieldName - Имя поля.
Lookup - Содержит True, если поле подстановочное.
Origin - Содержит имя поля в физической таблице.
ReadOnly - Если содержит True, значение поля нельзя менять.
Required - Если содержит True, значение поля не может быть пустым.
Size - Если поле имеет запись переменной длины, свойство указывает текущий размер данных.
Value - Содержит значение поля.
Visible - Если содержит True (по умолчанию), поле отображается в таких компонентах, как DBGrid.
AssignValue() - Преобразует вариантное значение поля Value с помощью метода AsXXXX и помещает результат в переменную Value, переданную в метод как параметр.
Create() - Создает поле-объект и инициализирует его.
Destroy() - Уничтожает поле-объект.
OnChange - возникает после изменения данных поля и их успешной записи.
OnGetText - в обработчике этого события можно подготовить текст для свойств DisplayText и Text.
OnSetText - возникает при записи данных из параметра Text в свойство Text.
OnValidate - возникает после изменения значения но до записи в буфер. Этот обработчик удобно использовать для проверки на правильность введенных данных.
К значению поля можно обратиться через свойства Value или AsXXXX, например:
Edit1.Text := FoodTFName.Value;
Edit1.Text := FoodTFName.AsString;
Применение свойства AsXXXX приводит к преобразованию значения в нужный тип. Разумеется, типы должны быть совместимыми. Например, целое число можно преобразовать в вещественное, но не наоборот.
Если вы не вызывали редактор полей и не создавали для набора данных ни одного объекта-поля, то значение поля можно получить через свойство FieldByName, например:
FoodT.FieldByName('FName').
Кроме того, доступ к значению поля можно получить через свойства набора данных Fields или FieldValues:
FoodT.Fields[1].AsString := Edit1.Text;
FoodT.FieldValues['FName'] := Edit1.Text;
Как уже упоминалось, свойство FieldValues в наборах данных применяется по умолчанию, так что последний пример можно записать и так:
FoodT['FName'] := Edit1.Text;
Если для доступа к полю вы используете свойство Fields, имейте в виду, что индексация полей начинается с 0, то есть индекс 1 соответствует второму полю набора данных.
Свойство FieldValues обладает еще одной особенностью: оно имеет вариантный тип и позволяет использование списка полей, таким образом, единственным оператором можно записать сразу несколько полей:
var
v : Variant;
begin
//создаем вариантный массив:
v := VarArrayCreate([0, 2], varVariant);
//читаем значения полей:
v := FoodT['FName;FType;FCena'];
Edit1.Text := v[0];
Edit2.Text := v[1];
Edit3.Text := v[2];
7.
Лекция: Запросы: версия для печати и PDA
На этой лекции вы познакомитесь с компонентом-запросом
TADOQuery, напишите приложение SQL-монитор
и испытаете несколько операторов SQL, формируя
различные наборы данных. Кроме того, вы
изучите свойства и методы компонентов-запросов,
отличные от других наборов данных.
Запросы (TQuery, TADOQuery) - это такие же наборы данных, как и таблицы (TTable, TADOTable). Запросы, как и таблицы, происходят от общего предка - TDBDataSet, в связи с этим они имеют схожие свойства, методы и события. Но имеются и существенные различия. Прежде всего, если табличный набор данных TTable (TADOTable) получает точную копию данных из таблицы базы данных, то запрос TQuery (TADOQuery) получает этот набор, основываясь на запросе, сделанном на специальном языке SQL (Structured Query Language - Язык Структурированных Запросов). С помощью этого языка программист создает запрос, который передается параметру TQuery.SQL (TADOQuery.SQL). При открытии набора данных этот запрос обрабатывается используемым механизмом BDE, ADO или др. и в набор данных передаются запрошенные данные. Заметили разницу? Не копия таблицы, а именно запрошенные данные, причем в указанном порядке!
Используя запросы, в одном наборе данных можно получить взаимосвязанные данные из разных физических таблиц. Отпадает надобность в подстановочных полях. Имеется два варианта работы с SQL-запросами. В первом случае, SQL-запрос запрашивает нужные данные из таблицы (таблиц) базы данных. При этом формируется временная таблица, созданная в каталоге запуска программы, и компонент-запрос становится ее владельцем. Работа с такими данными очень быстрая, но пользователь при этом не может изменять данные, он лишь просматривает их. Такой подход идеален для составления отчетности.
Если же пользователю требуется вносить изменения в таблицу (таблицы), то с помощью специальных операторов SQL (INSERT, UPDATE, DELETE) формируется запрос, уведомляющий механизм доступа к данным изменить данные БД. В этом случае никаких временных таблиц не создается. Запрос передается механизму доступа, обрабатывается им, выполняются изменения, и механизм доступа уведомляет программу о благополучном (или нет) изменении данных.
Сравним табличные наборы данных с запросами. При работе с локальными или файл-серверными БД, табличные наборы данных имеют преимущество в скорости доступа к данным, поскольку запросы создают и используют для этого временные таблицы, а табличные НД напрямую обращаются к физическим таблицам БД. Однако при этом, запросы позволяют формировать гибкие наборы данных, которые невозможно было бы получить с помощью табличных НД.
При работе в архитектуре клиент-сервер, всякое преимущество табличных наборов данных пропадает. Ведь они должны получить точную копию запрошенной таблицы, в которой могут быть десятки и сотни тысяч записей. Если учесть, что все эти данные передаются по сети, и передаются не одному, а множеству клиентов, то мы получим очень медленную систему, постоянно перегружающую сеть.
Для демонстрации работы компонента TADOQuery создадим совсем маленькое приложение - простейший SQL-монитор (у Delphi имеется встроенный SQL-монитор, но ведь всегда приятно сделать что-то своими руками!).
Итак, создайте папку для нового приложения. В эту папку скопируйте базу данных ok.mdb, с которой мы работали в четвертой лекции. Если вы еще помните, там у нас имеется четыре таблицы, предназначенные для программы отдела кадров. Создайте новый проект в Delphi, форму переименуйте в fMain, сохраните ее модуль под именем Main, а проект в целом как SQLMon. В свойстве Caption формы пропишите "Простой SQL-монитор".
Далее на форму установите панель. В свойстве Align панели выберите alTop, чтобы панель заняла весь верх, а ее высоту растяните примерно на полформы. Очистите свойство Caption. На эту панель установите компонент Memo, именно в нем мы будем писать наши SQL-запросы. Дважды щелкните по свойству Lines этого компонента, чтобы вызвать редактор текста, и очистите весь текст. Также не помешает дважды щелкнуть по свойству Font и изменить размер шрифта на 12 для лучшего восприятия текста. В свойстве Align выберите alLeft, чтобы компонент Memo занял всю левую часть панели.
В правой части панели установите две простые кнопки и компонент TDBNavigator с вкладки Data Controls панели инструментов. Для улучшения внешнего вида интерфейса ширину кнопок сделайте такой же, как у навигатора базы данных. В свойстве Caption первой кнопки напишите "Выполнить SQL-запрос", на второй кнопке напишите "Очистить компонент Memo". Собственно, мы могли бы очищать Memo сразу при выполнении SQL-запроса, и обойтись без второй кнопки. Но многие запросы похожи, и проще изменить часть текста запроса, чем писать весь запрос заново.
На нижнюю, свободную половину формы установите компонент TDBGrid с вкладки Data Controls для отображения данных. В свойстве Align сетки выберите alClient, чтобы сетка заняла все оставшееся место. У вас должна получиться такая картина:
Рис. 7.1. Внешний вид приложения
Еще нам потребуются три
Дважды щелкните по ADOConnection1, чтобы вызвать редактор подключений. Нажмите кнопку "Build", выберите поставщика Microsoft Jet 4.0 OLE DB Provider, и нажмите "Далее". В поле "Выберите или введите имя базы данных" укажите нашу БД ok.mdb и нажмите "ОК". И еще раз "ОК", чтобы закрыть окно редактора подключений. Сразу же свойство LoginPrompt переводим в False, чтобы при каждом запуске программы у нас не запрашивался логин и пароль, а Connected в True. Подключение к базе данных произошло.
В свойстве Connection компонента TADOQuery выберем ADOConnection1, а в свойстве DataSet компонента DataSource1 выберем наш НД ADOQuery1. Теперь набор данных ADOQuery1 соединен с базой данных, а DataSource1 - с этим набором данных.
В свойстве DataSource компонентов DBGrid1 и DBNavigator1 выберем DataSource1, чтобы они могли взаимодействовать с набором данных.
Нам осталось лишь запрограммировать обработчик события onClick для обеих кнопок. Щелкните дважды по кнопке "Выполнить SQL-запрос", чтобы сгенерировать это событие, и пропишите в нем такой код:
//проверим - есть ли текст в Memo. Если нет, выходим:
if Memo1.Text = '' then begin
ShowMessage('Вначале введите запрос!');
Memo1.SetFocus;
Exit;
end;
//текст есть. Очистим предыдущий запрос в наборе данных:
ADOQuery1.SQL.Clear;
//добавим новый запрос из Memo:
ADOQuery1.SQL.Add(Memo1.Text);
//открываем набор данных, т.е. выполняем запрос:
ADOQuery1.Open;
Комментарии здесь достаточно подробны,
чтобы разобраться в
Можно также заполнить свойство SQL, дважды щелкнув по нему и открыв редактор запросов, и сделать активным во время проектирования программы. Тогда данные становятся доступны сразу. Такой подход удобен, когда программист не собирается в дальнейшем менять SQL-запрос этого набора данных. Однако чаще бывает наоборот - в зависимости от ситуации, используется то один, то другой запрос в одном и том же наборе данных. Так мы поступаем и в нашем примере - передача SQL-запроса и открытие набора данных мы будем делать программно.
Еще мы можем заметить, что свойство SQL набора данных TADOQuery имеет тип TStrings, так же, как свойство Lines компонента Memo или свойство Items компонента ListBox. То есть, в свойстве SQL мы можем использовать все преимущества, которые нам дает тип TStrings, например, загрузка SQL-запроса из внешнего файла:
ADOQuery1.SQL.LoadFromFile('c:
Подобный прием нередко
ADOQuery1.SQL.Add(Memo1.Text);
ADOQuery1.SQL := Memo1.Lines;
Сгенерируйте событие нажатия на вторую кнопку, здесь мы должны просто очистить поле текста Memo1, и код совсем прост:
Memo1.Clear;
Вот и вся программа! Сохраните ее, скомпилируйте и запустите программу на выполнение. В поле Memo впишите следующие строки:
SELECT *
FROM LichData;
После этого нажмите кнопку "Выполнить SQL-запрос". В сетке DBGrid отобразятся данные, которые представляют собой точную копию таблицы LichData из базы данных ok.mdb.