Учебно-методический комплекс дисциплины (опд. Ф. 10) Базы данных (код и название дисциплины по учебному плану специальности)
Вид материала | Учебно-методический комплекс |
Содержание Задание: Реализуйте подпрограмму выдачи результата произвольного SQL-запроса в таблицу Excel. Работа №11. Разработка программы для ввода основных фактов о предметной области |
- Рабочая программа дисциплины «Зоология» Код дисциплины по учебному плану опд, 751.31kb.
- Учебно-методический комплекс дисциплины базы данных Специальность, 414.37kb.
- Рабочая программа дисциплины «экологический мониторинг» Код дисциплины по учебному, 254.39kb.
- Рабочая программа дисциплины «Цитология и гистология» Код дисциплины по учебному плану, 271.37kb.
- Рабочая программа дисциплины «ботаника» Код дисциплины по учебному плану опд., 301.75kb.
- Рабочая программа дисциплины «методика преподавания экологии» Код дисциплины по учебному, 283.89kb.
- Рабочая программа дисциплины «методика преподавания биологии» Код дисциплины по учебному, 350.54kb.
- Учебно-методический комплекс дисциплины математические методы в бизнесе и управлении, 423.86kb.
- Рабочая программа дисциплины «роль микроорганизмов в жизни растений» Код дисциплины, 88.04kb.
- Рабочая программа дисциплины «радиационная экология» Код дисциплины по учебному плану, 137.34kb.
Задание:
Реализуйте подпрограмму выдачи результата произвольного SQL-запроса в таблицу Excel.
Работа №9. Просмотр справочников иерархической структуры
Иерархический справочник – это таблица в базе данных, между записями которой устанавливается (рекурсивное) отношение 1:N. Пример иерархического справочника – справочник диагнозов болезней или справочник клиентов торговой фирмы, в частности:
Физические лица 1 уровень иерархии
Местные 2 уровень иерархии
Иванов 3 уровень иерархии
Петров
Иногородние 2 уровень иерархии
Сидоров 3 уровень иерархии
…
Организации 1 уровень иерархии
ООО 2 уровень иерархии
Гарант-Сервис 3 уровень иерархии
… …
ОАО
КМК
ЗСМК
…
Прочие
…
Рисунок 9.1. Справочник иерархической структуры.
Для отражения такой иерархии в структуру таблицы в дополнение к идентификатору записи вводятся еще два поля: Родитель (PARENT), Потомок (CHILD).
Таблица 9.1. Отображение иерархической структуры в реляционной таблице.
ID | PARENT | CHILD | NAME |
1 | 0 | 1 | Физические лица |
2 | 1 | 2 | Местные |
3 | 2 | 3 | Иванов |
4 | 2 | 4 | Петров |
5 | 1 | 5 | Иногородние |
6 | 5 | 0 | Сидоров |
7 | 5 | 0 | … |
9 | 6 | 7 | ООО |
10 | 7 | 0 | Гарант-Сервис |
11 | 8 | 0 | … |
12 | 6 | 9 | ОАО |
13 | 9 | 0 | КМК |
14 | 9 | 0 | ЗСМК |
15 | 9 | 0 | … |
16 | 9 | 10 | Прочие |
17 | 10 | 11 | … |
Задание:
Разработайте универсальный класс (THCatalog) для просмотра иерархических справочников, и на его основе реализуйте формы просмотра (а в последствии и редактирования) справочников.
Этот класс должен быть основан на модальной форме. Основной интерфейсный элемент в этой форме – компонент класса TDBGrid (по имени Grid). Форма должна создаваться динамически по мере запроса на вывод окна просмотра-редактирования справочника. В элементе Grid должны присутствовать необходимые для просмотра поля справочника (искусственные коды, уникально идентифицирующие запись в справочнике, не должны быть видны по умолчанию, однако следует создать элемент управления, позволяющий сделать их видимыми).
Для просмотра такого справочника следует использовать не TADOTable-компонент, а TADOQuery. Для него следует задать выражение SQL-запроса, которое позволит извлечь записи только одного уровня иерархии. Для этого придется ввести в SQL-запрос параметр, задающий значение поля PARENT, по которому будет осуществляться выборка.
SELECT PARENT, CHILD, NAME FROM CLIENTS WHERE PARENT = :p
В этом выражении :p – обозначение параметра запроса по имени ‘p’.
После вставки этого кода в свойство SQL компонента TADOQuery (договоримся, что его имя – Q), в свойстве Parameters образуется один элемент, соответствующий параметру ‘p’. Необходимо в редакторе параметров TADOQuery определить его тип – в нашем случае Integer.
Для выборки записей самого верхнего уровня иерархии следует задать значение параметра p равным 0. Значение параметра SQL-запроса можно задать следующим образом (компонент TADOQuery по имени Q):
Q.Close;
Q.Parameters.ParamByName(‘p’).Value := 0;
Q.Open;
Для перехода на один уровень иерархии вниз необходимо задать соответствующее значение того же параметра:
Var i:Integerl
…
i := Q.FieldByName(‘CHILD’).AsInteger; //Определить уровень потомков текущей записи
Q.Close;
Q.Parameters.ParamByName(‘p’).Value:= i; // Перейти на уровень потомков, сделать его текущим
Q.Open;
Для возврата на предыдущий уровень иерархии придется использовать еще один компонент TADOQuery (по имени Q1) (см. таблицу 2.), свойство SQL которого должно содержать код
SELECT PARENT FROM CLIENTS WHERE CHILD = :p1
а параметр ‘p1’ должен будет задаваться в момент, когда нам захочется вернуться на уровень назад (см. Таблица №2):
Q1.Parameters.ParamByName(‘p1’).Value := Q.FieldByName(‘PARENT’).Value;
Q1.Open;
Q.Close;
Q.Parameters.ParamByName(‘p’).Value := Q1.FieldByName(‘PARENT’).AsInteger;
Q1.Close;
Q.Open;
Работа №10. Редактирование справочников иерархической структуры
Имеются 4 случая редактирования справочника, задевающие его иерархическую структуру.
1. Для осуществления ввода новой записи на уже существующем уровне необходимо в поле PARENT новой записи записать общее для всех записей данного уровня значение, а в поле CHILD занести значение 0.
Level := Q.FieldByName(‘PARENT’).AsInteger;
Q2.SQL.Clear;
Q2.SQL.Add(‘INSERT INTO CLIENTS (PARENT, CHILD) VALUES (:p, 0)’);
// Можно задать тип параметра динамически!
Q2.Parameters.ParamByName(‘p’).DataType := ftInteger;
// Задать значение параметра
Q2.Parameters.ParamByName(‘p’).Value := level;
Q2.ExecSQL;
После выполнения этого SQL-запроса, в таблице появиться соответствующая запись, но ее нельзя будет увидеть на форме просмотра-редактирования справочника до тех пор, пока SQL-запрос компонента Q не будет выполнен повторно!
Q.Close;
Q.Open;
2. Для создания записи-потомка для записи, которая еще не имеет детей, необходимо выполнить более сложную работу. Во первых, надо определить значение идентификатора для записей нового уровня (поле PARENT), во вторых это значение занести в поле CHILD родительской записи, в третьих в поле PARENT новой записи-потомка записать это значение, а в поле CHILD занести значение 0:
Q2.SQL.Clear;
Q2.SQL.Add(‘SELECT MAX(PARENT) AS MP FROM CLIENTS’);
Q2.Open;
Level := Q2.FieldByName(‘MP’).AsInteger + 1;
Q2.Close;
Q.Edit;
Q.FieldByName(‘CHILD’).AsInteger := level;
Q.Post;
Q2.SQL.Clear;
Q2.SQL.Add(‘INSERT INTO CLIENTS (PARENT, CHILD) VALUES (:p, 0)’);
Q2.Parameters.ParamByName(‘p’).DataType := ftInteger;
Q2.Parameters.ParamByName(‘p’).Value := level;
Q2.ExecSQL;
Так как описанные действия достаточно сложны, следует выполнить их в рамках явной транзакции для того, чтобы обеспечить целостность данных.
Try
DM.AdoConnection1.BeginTrans;
Q2.SQL.Clear;
Q2.SQL.Add(‘SELECT MAX(PARENT) AS MP FROM CLIENTS’);
Q2.Open;
Level := Q2.FieldByName(‘MP’).AsInteger + 1;
Q2.Close;
Q.Edit;
Q.FieldByName(‘CHILD’).AsInteger := level;
Q.Post;
Q2.SQL.Clear;
Q2.SQL.Add(‘INSERT INTO CLIENTS (PARENT, CHILD) VALUES (:p, 0)’);
Q2.Parameters.ParamByName(‘p’).DataType := ftInteger;
Q2.Parameters.ParamByName(‘p’).Value := level;
Q2.ExecSQL;
DM.AdoConnection1.CommitTrans;
Except
On e:Exception do
begin
DM.AdoConnection1.RollBack;
ShowMessage(e.Message);
End;
End;
3. Для удаления записи справочника, не последней на текущем уровне, следует просто удалить ее из таблицы
Q2.SQL.Clear;
Q2.SQL.Add(‘DELETE FROM CLIENTS WHERE ID = :t’);
Q2.Parameters.ParamByName(‘t’).DataType := ftInteger;
Q2.Parameters.ParamByName(‘t’).Value := Q.FieldByName(‘ID’).AsInteger;
Q2.ExecSQL;
Q.Close;
Q.Open;
4. Для удаления последней на текущем уровне справочника записи следует выполнить более сложную последовательность действий: во первых удалить запись из таблицы, во вторых записать 0 в поле CHILD родительской записи, в третьих перейти к записям родительского уровня
// Запомнить уровень удаляемой записи
level := Q.FieldByName(‘PARENT’).AsInteger;
// Удалить ее
Q2.SQL.Clear;
Q2.SQL.Add(‘DELETE FROM CLIENTS WHERE ID = :t’);
Q2.Parameters.ParamByName(‘t’).DataType := ftInteger;
Q2.Parameters.ParamByName(‘t’).Value := Q.FieldByName(‘ID’).AsInteger;
Q2.ExecSQL;
// Определить уровень родительской записи
Q2.SQL.Clear;
Q2.SQL.Add(‘SELECT PARENT FROM CLIENTS WHERE CHILD = :t’);
Q2.Parameters.ParamByName(‘t’).DataType := ftInteger;
Q2.Parameters.ParamByName(‘t’).Value := Q.FieldByName(‘ID’).AsInteger;
Q2.Open;
// Запомнить его
newLevel := Q2.FieldByName(‘PARENT’).AsInteger;
// Обнулить ссылку на детей – их больше нет у родительской записи
Q2.SQL.Clear;
Q2.SQL.Add(‘UPDATE CLIENTS SET CHILD = 0 WHERE CHILD = :t’);
Q2.Parameters.ParamByName(‘t’).DataType := ftInteger;
Q2.Parameters.ParamByName(‘t’).Value := level;
Q2.ExecSQL;
// Открыть уровень, который содержит родительскую запись (теперь она уже не родительская!)
Q.Close;
Q.Parameters.ParamByName(‘p’).Value := newLevel;
Q.Open;
Разумеется, весь код следует выполнить в рамках явной транзакции.
Возникает вопрос: а как определить, является ли удаляемая запись последней на текущем уровне? Для этого можно, например, узнать количество записей, возвращенных SQL-запросом, вызвав свойство RecordCount соответсвующего объекта класса TADOQuery:
i := Q.RecordCount;
либо выполнить соответсвующий SQL-запрос с помощью еще одного объекта класса TADOQuery (назовем его qKOL). Такой компонент можно создать динамически, воспользоваться им, а затем уничтожить:
qKol := TADOQuery.Create;
qKol.Connection := DM.DBC;
qKol.SQL.Add(‘SELECT COUNT(*) AS KOL_VO FROM CLIENTS WHERE PARENT=:p ‘);
with qKol.Parameters(‘p’) do begin
DataType := ftInteger;
Value := …
End;
qKol.Open;
i := qKOL.FieldByName(‘KOL_VO).AsInteger;
q.Kol.Close;
FreeAndNil(qKol);
Задание:
Реализуйте возможность редактирования справочника иерархической структуры в своей программе.
Работа №11. Разработка программы для ввода основных фактов о предметной области
Под фактами предметной области будем понимать то, ради чего собственно и создается приложение. Например, для спорткомплекса таким фактом является то, что клиент Иванов, проживающий по ул. Металлургов 33, 41 и работающий в ОАО НКМК купил абонемент на 8 посещений тренажерного зала по пятницам, в 17.00, заплатив за него 1000 руб.
Задание:
Реализуйте программу для ввода в базу данных фактов, наблюдаемых в Вашей предметной области. Для этого следует использовать возможность задания свойств с помощью таблиц-справочников. Программа должна поддерживать ввод новых фактов, исправление ошибочно введенных и удаление неверных фактов. Интерфейс программы – на Ваш вкус.