Добавил:
Меня зовут Катунин Виктор, на данный момент являюсь абитуриентом в СГЭУ, пытаюсь рассортировать все файлы СГЭУ, преобразовать, улучшить и добавить что-то от себя Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика / Теория / подготовка к ит.doc
Скачиваний:
27
Добавлен:
10.08.2023
Размер:
685.06 Кб
Скачать

39. Разработка приложений баз данных

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

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

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

  • компоненты визуализации и управления данными.

Подключение таблицы базы данных с помощью компонента Table.

Если Вы используете Table для доступа к таблице, то при открытии данной таблицы автоматически заполняются некоторые свойства TTable (количество записей, описание структуры таблицы и т.д.).

Последовательность установки свойств следующая:

  • В выпадающем списке свойства DatabaseName показываются все доступные BDE псевдонимы баз данных. Если задан Алиас (см. выше), выбрать его в списке.

  • Заполнить свойство TableName (ОБЯЗАТЕЛЬНО!). Для этого:

  • если задан Алиас, в выпадающем списке свойства TableName появятся таблицы, доступные в данной базе данных. Выбрать имя необходимой Вам таблицы в списке;

  • если необходимая Вам таблица расположена в той же папке, что и проект, выбрать её в списке TableName без задания Алиаса;

  • если Алиас не задан, указать полный путь доступа к необходимой Вам таблице в свойстве TableName.

  • При необходимости уточнить категорию таблицы в свойстве TableType.

  • Установить свойство Active в значение True. Обратите внимание, что, если Delphi распознал указанный Вами файл как базу данных, он позволит Вам установить свойство Active в значение True, иначе это свойство останется False.

Заранее выставлять для таблиц Active = true допустимо только в процессе настройки и отладки приложения, работающего с локальными базами данных.

Если обращение к БД идет непосредственно в программном коде, ее открытие выполняется с помощью одной из команд:

Table1.Active := True; Table1.Open;

Для закрытия таблицы в программном коде следует записать одну из команд:

Table1.Close; Table1.Active := False;

В законченном приложении во всех таблицах сначала должно быть установлено Active = false, затем при событии формы эти свойства могут быть установлены в true, а при событии формы onDestroy эти свойства опять должны быть установлены в false. Это исключит неоправданное поддержание связи с базой данных, которое занимает ресурсы, а при работе в сети мешает доступу к базе данных других пользователей.

У компонента Table есть булево свойство Exclusive, определяющее доступ к используемой таблице при одновременном обращении к ней нескольких приложений (например, при работе в сети или в многозадачном режиме). Exclusive=true - таблица будет закрыта для других приложений, это свойство можно менять только при Active=false.

Запустив приложение, можно просматривать данные, редактировать их (отредактированные данные будут помещаться в базу данных в момент перехода от редактируемой записи к любой другой).

Если работа с БД ведется программно без визуализации процесса обработки, Table может оказаться единственным компонентом, необходимым Вам.

Обращение к информации из базы данных - это доступ к отдельным записям и/или полям таблицы.

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

Программный код прохода по всем записям БД имеет вид:

// От начала к концу БД

Table1.First;

while not Table1.EOF do begin

DoSomething; // Раб. процедура

Table1.Next;

End;

// От конца к началу БД

Table1.Last;

while not Table1.BOF do begin

DoSomething;// Раб. процедура

Table1.Prior;

End;

N.B.! Если Вы не планируете получить бесконечный цикл, не забывайте писать Next или Prior !

Обратите внимание, что Table1.MoveBy соответствует Table1.Next; а Table1.MoveBy(-1) соответствует Table1.Prior.

При использовании этой функции Вы должны всегда помнить, что DataSet - это изменяющиеся объекты, и запись, которая была пятой по счету в предыдущий момент, теперь может быть четвертой, или шестой, или вообще может быть удалена.

Пример. Осуществлять перемещение по БД с заданным шагом

Table1. Open;

Table1.MoveBy (StrToInt(edit1.Text);

Общее количество записей в БД определяется функцией RecordCount, т.е. цикл прохода по всем записям БД может иметь вид:

Table1.First;

For i:=1 to Table1.RecordCount do begin

DoSomething;// Некоторая рабочая процедура

Table1.Next;

End;

Для доступа из программы к индивидуальные полям записи используются следующие свойства и методы TDataSet:

1. FieldCount возвращает число полей в текущей структуре записи.

Например, программный код вывода сведения о числе полей текущей БД будет иметь вид:

Table1.Open;

label1.caption:='Число полей '+ IntToStr(Table1.FieldCount);

Свойство Fields позволяет получить доступ к именам полей записи, а также к содержимому полей.

2. Fields[n].FieldName доступ к именам полей.

Например, для вывода на экран списка имен полей из текущей БД можно применить следующий программный код:

for i:=0 to Table1.FieldCount - 1 do begin; // Нумерация ведется с 0

ListBox1.Items.Add(Table1.Fields[i].FieldName);

End;

Функции Fields[n].As<String или Integer или Float или Date или Boolean для выбора типа результата> доступ к содержанию конкретного поля конкретной записи.

// Вывод в ListBox информации из первого поля БД:

Table1.First; ListBox1.Clear;

while not Table1.EOF do begin

ListBox1.Items.Add(Table1.Fields[0].AsString);

Table1.Next;

End;

Всякий раз (когда это имеет смысл) Delphi сможет сделать преобразования. Например, Delphi может преобразовывать поле Boolean к Integer или Float или поле Integer к String. Но не будет преобразовывать String к Integer. Если Вы хотите работать с полями Date или DateTime, то можете использовать AsString и AsFloat для доступа к ним.

Визуальные компоненты работы с БД

Эти компоненты предназначены для построения интерфейсной части приложения.

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

Интересной особенностью DBGrid является то, что информация из открытой БД автоматически вносится в сетку уже на стадии проектирования формы, причем визуализируются поля и записи в габаритах формы (рис. 7.15), а при инициализации проекта становится возможным просмотр ранее недоступных полей и записей.

Как было сказано выше, остановимся подробнее на свойстве Columns.

Рассмотрим еще один компонент, управляющий работой с таблицей, - навигатор DBNavigator . Как и при работе с DBGrid, обязательным устанавливаемым свойством является DataSource, в котором следует выбрать ранее заданное имя компонента DataSource (то же, что было выбрано для DBGrid).

Основными свойствами DBNavigator являются DataSource (ОБЯЗАТЕЛЬНОЕ!) VisibleButtons, пользуясь которым можно убрать любые ненужные в данном приложении кнопки. Если нужно запретить пользователю вводить новые записи, следует установить в нём nbInsert=false, а если нужно запретить редактирование, следует оставить только кнопки nbFirst, nbPrior, nbNext, nbLast.

При работе с DBNavigator внесенные изменения зафиксируются в таблице после нажатия кнопки nbPost.

Таким образом, если на форме разместить компонеты

Table для связи с таблицей БД;

DataSorce для связи таблицы с визуальным компонетом;

DBGrid для отображения информации из выбранных полей таблицы в форме;

DBNavigator для редактирования и управления данными без процедур управления полями и записями, описанными выше, можно было бы вообще обойтись.

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

Создание таблиц с помощью SQL-запросов.

Основы языка SQL.

Язык SQL предназначен для манипулирования данными в реляционных базах данных, определения структуры баз данных, для управления правами доступа к информации, манипулирования данными в таблицах баз данных. В отличие от алгоритмических языков в нем нет команд управления, средств ввода - вывода. Программу на языке SQL обычно называют SQL - запросом. SQL не используется в чистом виде, а является, как правило, встроенным средством. За обеспечение возможности выполнения операторов SQL отвечают специальные компонеты. В Delphi это Query.

Операторы язык SQL можно разделить на следующие группы:

определения данных;

управления данными;

манипулирования данными.

Последняя группа состоит из четырех команд:

SELECT (выбрать);

INSERT (вставить);

UPDATE (обновить);

DELETE (удалить).

Характеристика оператора SELECT.

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

SELECT [DISTINCT] <список выбираемых элементов (полей)>

FROM <список таблиц (или представлений)>

[WHERE <условие отбора (предикат)>]

[GROUP BY <список полей>] [HAVING <условие группировки>]]

[UNION <вложенный оператор_Select>]

[ORDER BY <список полей или номеров>];

Рассмотрим подробно отдельные составляющие оператора Select.

DISTINCT -получение списка неповторяющихся строк.

Если из результирующего набора необходимо устранить все повторы строк, следует применить модификатор DISTINCT. Данный модификатор действует на весь список.

Список выбираемых элементов может содержать следующие составляющие:

имена полей;

* (все поля);

вычисления;

литералы;

функции;

агрегирующие конструкции.

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

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

Пример. Получить список товаров, объем заказа и остаток от заказа.

SELECT tovar, zak, zak-prod, FROM sell;

Литералы - это строковые константы, которые применяются наряду с наименованиями столбцов и таким образом выступают в роли "псевдостолбцов". Строка символов, представляющая собой литерал, должна быть заключена в одинарные или двойные кавычки.

Пример. Получить сведения о сделках (товар, дата, заказ) с необходимыми пояснениями.

SELECT "товар",Tovar, "заказан", Zak, "шт. ", DataProd FROM Sell;

Конкатенация (|| или +) дает возможность соединять столбцы, имеющие строковый тип, друг с другом и с литералами. Для этого используется операция конкатенации.

Пример. Получить из базы Sell.db неповторяющиеся комбинации "товар - посредник":

SELECT Distinct "группа " || Tovar || " " || Delir FROM Sell;

Квалификатор AS используется для замены в результирующей таблице существующего названия столбца на заданное новое имя.

Пример. Получить список товаров из базы Price.db:

SELECT Tovar AS Товар FROM Price

Агрегатные функции - функции вычисления суммы (SUM), максимального (SUM) и минимального (MIN) значений столбцов, арифметического среднего (AVG), а также количества строк, удовлетворяющих заданному условию (COUNT).

SELECT avg(zak) As Среднее from sel;l

Предложение FROM команды SELECT.

В предложении FROM перечисляются все объекты (один или несколько), из которых производится выборка данных. Каждая таблица или представление, о которых упоминается в запросе, должны быть перечислены в предложении FROM.

Подробно сведения о работе с несколькими таблицами БД будут приведены ниже.

Условие WHERE (ограничения на число записей).

Число возвращаемых в результате запроса записей ограничено путем использования предложения WHERE, содержащего условия отбора. При этом запрос возвращает в качестве результата только те записи, для которых предикат имеет значение true.

Критерий отбора - логическое выражение, в котором происходят операции сравнения.

Элементом сравнения могут выступать:

значение поля;

литерал (конечные пробелы игнорируются);

арифметическое выражение;

агрегирующая функция;

другая встроенная функция;

значение (значения), возвращаемое подзапросом.

Операции сравнения могут быть сгруппированы с помощью логических операторов, к числу которых относятся операторы AND, OR, NOT.

В одном предикате логические операторы выполняются в следующем порядке:

оператор NOT;

оператор AND;

оператор OR.

Для изменения порядка выполнения операторов разрешается использовать скобки.

Сравнение ведется с использованием реляционных операторов

=

<> или !=

>

<

>=

<=

а также логических операторов, представленных в табл. 8.2.

Работа с датами.

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

"yesterday" (вчера);

"today" (сегодня);

"now" сейчас (включая время);

"tomorrow" (завтра).

Дата может неявно конвертироваться в строку (из строки), если выражение не содержит неоднозначностей в толковании типов столбцов.

SELECT Tovar, DatProd FROM Sell WHERE DatProd > "01.05.03";

Обратите внимание: разделитель в дате - ТОЛЬКО ТОЧКА.

Значения дат можно сравнивать друг с другом, с относительными датами, вычитать одну дату из другой.

SELECT Tovar, DatProd FROM Sell WHERE "today" - DatProd > 365/2; // проданных более полугода назад

Функция EXTRACT применяется для извлечения из выражения, содержащего дату и время, значение, соответствующее указанному элементу.

EXTRACT(<элемент> from <выражение>)

В качестве элемента можно использовать значения: Year, Month, Day

SELECT Tovar from Sell Where EXTRACT(Month from DatProd)=5 ;

Преобразование типов (CAST)

Для преобразования значение столбца или функции к другому типу (с целью более гибкого использования операций сравнения) используется функция CAST(<выражение> AS <тип>).

Типы данных могут быть конвертированы следующим образом:

NUMERIC

CHAR

VARCHAR

DATE

SELECT Tovar, DatProd FROM Sell

WHERE CAST(DataProd As Date) ="11.02.2004";

Группирование записей (GROUP BY).

Группу образуют записи, имеющие одинаковое значение полей, перечисленных в списке GROUP BY. Группирование автоматически исключает повтор выводимых записей. Совместно с оператором GROUP BY можно указывать оператор HAVING, в котором указываются дополнительные критерии группирования. Оператор GROUP BY удобен для проведения статистических отборов.

SELECT count(Zak) from Sell

GROUP BY extract(month from DatProd)

HAVING tovar ="компьютер";

Изменение порядка выводимых строк (ORDER BY).

Порядок выводимых строк может быть изменен с помощью дополнительного предложения ORDER BY в конце SQL-запроса, имеющего вид:

ORDER BY <порядок строк> [ASC | DESC]

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

Способ упорядочивания определяется дополнительными словами

ASC (по возрастанию (по умолчанию));

DESC (по убыванию).

SELECT Tovar FROM Sell ORDER BY Tovar

SELECT Tovar, DatProd FROM Sell ORDER BY Tovar, DatProd DESC

Соединение (JOIN).

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

Связывание производится, как правило, по первичному ключу одной таблицы и внешнему ключу другой таблицы для каждой пары таблиц. При этом очень важно учитывать все поля внешнего ключа, иначе результат будет искажен. Соединяемые поля могут присутствовать в списке выбираемых элементов (хотя это и не обязательно). В одном предложении WHERE могут присутствовать множественные условия соединений. Условие соединения не исключает наличия других предикатов в предложении WHERE.

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

В одном запросе нельзя смешивать использование написания имен таблиц и их алиасов

SELECT s.Tovar,(s.Zak-s.Prod)*p.Price FROM Sell s, Price p

WHERE (s.Zak-s.Prod)*p.Price >400');

Если имена таблиц указываются вместе с форматом таблиц, то в обозначении поля имя этой таблицы заключается в кавычки.

SELECT s.Tovar,(s.Zak-s.Prod)*p.Price

FROM "Sell.db" s, "Price.db" p WHERE (s.Zak-s.Prod)*p.Price >400');

В стандарте (ANSI-92) условия соединения записываются в предложении FROM, в котором слева и справа от зарезервированного слова "JOIN" указываются соединяемые таблицы; условия поиска, основанные на правой таблице, помещаются в предложение ON; условия поиска, основанные на левой таблице, помещаются в предложение WHERE.

SELECT s.Tovar,(s.Zak-s.Prod)*p.price

FROM Sell s JOIN Price p ON (s.Zak-s.Prod)*p.Price >400');

Применение компонента Query для отбора данных.

Так же, как и при работе с компонентом Table, визуализация информации, полученной через компонент Query (вкладка BDE), обеспечивается компонентами DataSouce и DBGrid. В отличие от навигационного доступа к БД, обеспечиваемого компонентом Table, компонент Query дает возможность формировать запросы на языке SQL. Компонент Query имеет большинство свойств и методов, совпадающих с Table.

Если запрос SQL сводится к просмотру таблицы (запрос Select), то результат этого запроса (а не сама исходная таблица) помещается во временном файле на компьютере пользователя. Это таблица только для чтения, и она не допускает каких-либо изменений. Если же запрос связан с какими-либо изменениями содержания таблицы, то никаких временных таблиц не создается. BDE передает запрос на сервер, там он обрабатывается, и в приложение возвращается информация о том, успешно ли завершена соответствующая операция.

Delphi может использовать утверждения SQL для просмотра таблиц, выполнять объединение таблиц, создавать отношения один-ко-многим.

Таким образом, эффективность Query при работе в сети выше, чем у Table.

Одна из полезных особенностей свойства SQL - это способность читать файлы, содержащие текст запроса, непосредственно с диска.

В приведенном ниже программном коде выбранный файл загружается с диска в свойство SQL, текущий запрос закрывается, а загруженный запрос выполняется, и результат показывается пользователю.

with Query1 do begin

Close;

SQL.LoadFromFile(<полное имя файла>);

Open;

end.

Так же, как и Table, компонент Query (набор данных) помещается на форму вместе с компонентом DataSource (источник данных) и компонентами отображения данных, например DBGrid. Основные свойства Query приведены в табл. Отличие свойства DataSource: это свойство компонента Query позволяет строить приложения, содержащее связанные друг с другом таблицы.

Свойство SQL - самая важная часть Query. Доступ к этому свойству происходит либо через Инспектор Объектов во время конструирования проекта, либо программно.

Свойство SQL имеет тип TString. Это список строк, содержащих запросы SQL. В процессе проектирования приложения целесообразно сформировать в этом свойстве некоторый предварительный запрос SQL, который показал бы, с какой таблицей (или таблицами) будет проводиться работа.

Обратите внимание, что свойства TableName у компонента Query нет, так как таблица, с которой ведется работа, будет указываться в запросах SQL. Поэтому в свойство SQL надо занести запрос, содержащий таблицы, и перечислить параметры, если они используются в приложении. Пока такой запрос в SQL отсутствует, дальнейшая настройка Query невозможна.

Но далее во время выполнения приложения свойство SQL может формироваться программными методами, обычными для класса TString: Clear - очистка, Add - добавление строки и т.д.

При программном использовании TQuery, рекомендуется сначала закрыть текущий запрос и очистить список строк в свойстве SQL:

Query1.Close;

Query1.SQL.Clear.

Следующий шаг - добавление новых строк в запрос методом Add.

Query1.SQL.Add(‘Select <список поле> from <имя базы>’);

Query1.SQL.Add(‘where <условие>’).

Чтобы Delphi отработал запрос и возвратил курсор, содержащий результат в виде таблицы, можно вызвать метод:

Query1.Open.

Для управления отображением данных в компоненте Query, как и в компоненте Table, имеется редактор полей Field Editor. Он вызывается либо двойным щелчком на компоненте Query, либо из контекстного меню выбором пункта Fields Editor. В нем можно добавить имена получаемых полей (add), задать заголовки полей, отличающиеся от их имен, сделать поля невидимыми (visible), нередактируемыми (ReadOnly), в логических полях задать текст(например: да; нет; м; ж), задать формат высвечивания чисел, создать вычисляемые поля, задать диапазоны значений и др.

Основная нужная нам команда SELECT языка SQL была подробно рассмотрена в предыдущем разделе. Рассмотрим ее применение в Delphi на примерах.

40.Мультимедиа.

Компонент Animate (вкладка Win32) предназначен для воспроизведения видеоклипов в формате AVI. Насколько компонент прост в использовании, настолько он ограничен в применении, так как позволяет проигрывать только файлы, которые:

  • не содержат звука;

  • не содержат сжатой информации;

  • размер файла не превышает 64 Кбайт.

В Delphi есть компонент MediaPlayer (вкладка System), который предоставляет доступ ко всем основным возможностям программирования мультимедиа. Данный компонент очень прост в использовании, поскольку обеспечивает доступ к набору подпрограмм, созданных Microsoft и называемых Media Control Interface (MCI). Эти подпрограммы дают программисту простой доступ к широкому кругу устройств мультимедиа.

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

Компонент MediaPlayer , размещенный на форме, имеет вид панели управления устройством с кнопками. Как и на магнитофоне, здесь есть кнопки «воспроизведение», «перемотка», «запись».

Необходимо указать имя файла (свойство FileName) и установить AutoOpen в True. После выполнения этих шагов программа готова к работе. Запустив программу, нажмите кнопку «воспроизведение», и Вы увидите видеоролик (если выбрали AVI) или услышите звук (если выбрали WAV или MID). Если этого не произошло или появилось сообщение об ошибке, то возможны два варианта:

Вы ввели неправильное имя файла.

Вы не настроили правильным образом мультимедиа в Windows. Это означает, что либо у Вас нет соответствующего оборудования, либо не установлены нужные драйверы.

Если свойство Display не заполнено, видео воспроизводится в отдельном окне. В качестве экрана для показа ролика можно использовать, например, панель. На форму нужно поместить компонент TPanel, убрать текст из свойствава Caption. Далее для MediaPlayer в свойстве Display выбрать из списка Panel1. После этого надо запустить программу и нажать кнопку "воспроизведение".

Если запуск компонента MediaPlayer производится программно, этот компонент можно скрыть от пользователя (MediaPlayer.Visible:= False;).

Во время выполнения программы может потребоваться отобразить текущее состояние объекта MediaPlayer и самого ролика (время, прошедшее с начала воспроизведения, длину ролика). Для этого у объекта TMediaPlayer есть соответствующие свойства и события.

Пример. Создать программу, которая при вводе правильного пароля воспроизводит клип "Пляшущий карандаш".

begin

if StrToDate(edit1.text)=date() then begin

MediaPlayer1.Visible:=True;

end;

При воспроизведении клипа, продолжающегося длительное время, на форме целесообразно отразить процент исполнения клипа. Для этого на форму выносится невизуальный компонент Timer (вкладка System) и индикатор Gauge (вкладка Samples).

В свойствах компонента Timer следует указать интервал времени (в миллисекундах), по истечении которого следует отражать процент выполнения задания (Timer1.Interval:=100;), а индикатор Gauge отобразит в процентах, сколько прошло времени.

В обработчике события OnTimer нужно записать:

begin

with MediaPlayer1 do

if FileName<>'' then Gauge1.Progress:=Round(100*Position/Length);

end;