Особливості проектування баз даних

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати

Завдання

· Відповідно до варіантом спроектуйте базу даних будь-яким методом проектування на основі опису предметної області.
1. У СУБД InterBase 6.0/Firebird 1.5 реалізуйте серверну частину спроектованої раніше бази даних, яка повинна містити:
1) таблиці з визначенням первинного ключа
2) тригери, реалізують каскадне оновлення та каскадне видалення пов'язаних полів
3) тригери, які присвоюють унікальне значення генератора в полі первинного ключа
4) тригери, що забезпечують журналізацію змін певної таблиці
5) не менше трьох різних процедур, що зберігаються
2. У ІСР Delphi створіть клієнтське додаток, використовуючи будь-яку технологію доступу до даних (BDE, IBX, ADO та ін) з можливістю пошуку і фільтрації даних, а також виведення звіту.
1) У кожної книги в бібліотеці свій ідентифікаційний номер.
2) Кожна книга може бути видана в одному видавництві.
3) В одному і тому ж видавництві видається кілька книг.
4) Кожна книга має певну кількість сторінок, тип обкладинки, величину тиражу.
5) Кожна книга в конкретний момент може знаходитися або в бібліотеці або на руках тільки в одного читача.
6) Кожен читач може взяти з бібліотеки кілька книг.
7) Кожен читач має унікальний номер абонемента.
8) Ім'я читача не унікально. Назва видавництва не унікально.
9) Читач має ПІБ, телефон, адресу. Видавництво - назва, місто.

Проектування бази даних

Наведемо ER-діаграму згідно з описом предметної області:
SHAPE \ * MERGEFORMAT
Читачі
Тип палітурки
Тираж
Кількість сторінок
  ID Книги
Видавництво
  ID Абонента
ПІБ
Адреса
1
1
1
1
1
М
1
1
1
1
1
1
1
М
М
М
М
1
М
М
М
М
1
Найменування
1

Рис.1. ER-діаграма
Так як кожна книга в конкретний момент часу може перебувати на руках тільки в одного читача, то ми можемо пов'язати суті «Книга» та «Читачі» по полю «ID Абонента» зв'язком типу Багато до одного так як в цьому полі, що є зовнішнім ключем для атрибуту «Книги», можуть повторюватися запису, бо один і той же читач може взяти відразу кілька книг. Якщо це поле містить значення NULL, то значить, що дана книга ні знаходиться на руках у читача, а знаходиться в бібліотеці. Додамо для сутності «Книга» додаткове властивість «Дата видачі». Значення цього поля мають дорівнювати NULL якщо значення поля «ID Абонента» так само дорівнює NULL.
Наведемо базу даних до третьої нормальній формі. Властивість «Видавництво» сутності «Книги» має додаткові властивості не залежать від ключових. Тому зробимо властивість «Видавництво» самостійною сутністю і введемо для нього додаткове властивість «ID Видавництва» і зробимо його ключовим.
SHAPE \ * MERGEFORMAT
Книги
Читачі
Тип палітурки
Тираж
Кількість сторінок
  ID Книги
Назва
  ID Абонента
ПІБ
Адреса
1
1
1
1
1
М
1
1
1
1
1
1
1
М
М
М
М
1
Видавництва
  ID Видавництва
1
1
М
М
М
Дата видачі
1
М
1
Найменування
1

Рис.2. ER-діаграма
Опишемо структуру кожної таблиці.
Таблиця «Книжки» (Books)
Найменування поля
Тип даних
Обмеження
ID Книги (ID_Books)
Ціле число
NOT NULL
Первинний ключ
Значення унікально
Найменування (Name)
Рядок (30)
NOT NULL
ID Видавництва (ID_Publishers)
Ціле число
NOT NULL
Зовнішній ключ
Кількість сторінок (K_pages)
Ціле число
NOT NULL
Тип палітурки (Cover)
Рядок (15)
NOT NULL
Наклад (Tiraz)
Ціле число
NOT NULL
ID Абонента (ID_abonent)
Ціле число
Зовнішній ключ
Дата видачі (Date_issue)
Дата
Таблиця «Видавництва» (Publishers)
Найменування поля
Тип даних
Обмеження
ID Видавництва (ID_Publishers)
Ціле число
NOT NULL
Первинний ключ
Значення унікально
Назва (Name)
Рядок (20)
NOT NULL
Місто (City)
Рядок (20)
Таблиця «Читачі» (Readers)
Найменування поля
Тип даних
Обмеження
ID Абонента (ID_ abonent)
Ціле число
NOT NULL
Первинний ключ
Значення унікально
ПІБ (FIO)
Рядок (30)
NOT NULL
Телефон (Telephone)
Рядок (10)
Адреса (Address)
Рядок (20)
NOT NULL

Реалізація серверної частини бази даних

Серверну частину бази даних будемо виконувати на сервері FireBird 2.1 у візуальному середовищі розробки IBExpert.
Запустимо IBExpert. Виберемо команду Database / Create Database (База даних / Створити базу даних). У вікні Create Database (Створення бази даних) вкажемо:
· Server (Сервер) - Local (локальний)
· Database (Файл БД) - C: \ 01 \ LIBRARY.fdb
· UserName (ім'я_користувача) - SYSDBA
· Password (пароль) - masterkey - це ім'я і пароль адміністратора за замовчуванням.
· Charset (кодування) - WIN1251
· SQL Dialect (Діалект БД) - Dialect 3 (Діалект 3).
Натиснемо OK. база даних буде створена. У вікні Database Register (Реєстрація БД) виберемо в полі Версія сервера FireBird 2.1. Натиснемо кнопку Register, і база даних буде зареєстрована і відобразиться у вікні Database Explorer. У цьому вікні виберемо зареєстровану базу даних і виберемо Database / Connect to Database (База даних / Підключитися до Бази даних). У вікні Database Explorer відобразяться всі елементи бази даних.

Створення таблиць

Створимо таблицю «Книги» (Books). Виберемо Database / New Table (База даних / Нова таблиця). У вікні Table (Таблиця) задамо ім'я Books і визначимо називання атрибутів їх типи даних і обмеження. Відкомпілюємо скрипт, натиснувши <Ctrl+F9>.
Задамо ключове поле таблиці «BOOKS». Для цього зробимо активної вкладку Constraint (Обмеження). Клацнемо правою кнопкою миші у вільному просторі вікна Table (Таблиця) і в випадаючому меню виберемо пункт New primary key (новий первинний ключ). Далі встановимо первинний ключ для атрибуту «ID_BOOKS». Для цього клацнемо лівою кнопкою миші в полі On Field (На полі) і встановимо потрібний атрибут. Встановимо сортування за зростанням значення індексу - виберемо Ascending для Index Sorting.
Перейдемо на вкладку Fields (поля) клацанням правою кнопкою миші на полі «ID_BOOKS» викличемо меню, з якого виберемо Edit Field ID_BOOKS. У вікні перейдемо на вкладку Autoincrement (авто прирощення). Нижче з'являться три додаткові вкладки Generator (генератор) Trigger (тригер) і Procedure (процедура). На вкладці Generator виберемо Create Generator (створити генератор), привласнимо йому ім'я «GEN_BOOKS_ID» і початкове значення зазначимо рівним 1. Перейдемо на вкладку Trigger і виберемо Create Trigger (створити тригер). Автоматично буде написаний код:
IF (NEW. "ID_ BOOKS" IS NULL) THEN
NEW. "ID_ BOOKS" = GEN_ID (GEN_BOOKS_ID, 1);
Тут міститься оператор умови. Якщо при зверненні до нового значенням стовпця «ID_ BOOKS» (оператор NEW), воно є порожнім (оператор IS NULL) то йому присвоюється значення, що генерується створеним раніше генератором GEN_BOOKS_ID (GEN_ID (імя_генератора, крок) - оператор звернення до генератора). Натиснемо «ОК» і откомпіліруем скрипт.
Аналогічно ми створимо при створенні інших таблиць генератори і тригери, які присвоюють унікальні значення ключовим стовпцях цих таблиць.
Створимо дві решта таблиці: «Видавництва» (Publishers) і «Читачі» (Readers).

Створення тригерів

Створимо тригери журналізації змін таблиці «BOOKS». Для цього створимо таблицю «BOOKS_JOURNAL», в яку будуть автоматично записуватися будь-які зміни, доповнення, видалення в таблиці «BOOKS». При цьому буде фіксуватися дата (поле «DATE»), операція (INS, UPD, DEL) над таблицею «BOOKS» (поле «OPERATION»), а також старе і нове значення стовпців цієї таблиці. Для операції видалення нове значення стовпців буде порожнім. Для операції додавання порожнім буде старе значення стовпців.
Для журналізації була створена таблиця:
CREATE TABLE BOOKS_JOURNAL (
OPERATION CHAR (6) NOT NULL,
ID_BOOKS_OLD INTEGER,
ID_BOOKS_NEW INTEGER,
ID_PUBLISHERS_OLD INTEGER,
ID_PUBLISHERS_NEW INTEGER,
K_PAGES_OLD INTEGER,
K_PAGES_NEW INTEGER,
COVER_OLD VARCHAR (15),
COVER_NEW VARCHAR (15),
TIRAZ_OLD INTEGER,
TIRAZ_NEW INTEGER,
ID_ABONENT_OLD INTEGER,
ID_ABONENT_NEW INTEGER,
DATE_ISSUE_OLD DATE,
DATE_ISSUE_NEW DATE,
NAME_OLD VARCHAR (20),
NAME_NEW VARCHAR (20),
DATE_ DATE NOT NULL,
TIME_ TIME NOT NULL,
ID_JOURNAL INTEGER NOT NULL);
ALTER TABLE BOOKS_JOURNAL ADD PRIMARY KEY (ID_JOURNAL);
Тепер створимо тригер, закріплений за таблицею «BOOKS» для вставки, зміни та видалення записів. Для створення тригера виберемо Triggers / New Trigger ... (Тригер / Новий тригер). З'явиться вікно створення тригера в якому вкажемо:
· Ім'я - «JOURNAL»;
· Для таблиці - «BOOKS»;
· Тип - «BEFORE», тобто виконується перш операції;
· Зазначимо INSERT, UPDATE, DELETE.
Повний текст тригера буде наступний:
SET TERM ^;
CREATE OR ALTER TRIGGER JOURNAL FOR BOOKS
ACTIVE BEFORE INSERT OR UPDATE OR DELETE POSITION 0
AS
begin
IF (INSERTING) THEN
begin
insert into BOOKS_JOURNAL values ​​('INSERT', null, new.id_books, null, new.id_publishers, null, new.k_pages, null, new.cover, null, new.tiraz, null, new.id_abonent, null, new.date_issue , null, new.name, 'now', 'now', gen_id (generator_journal, 1));
end
IF (updating) THEN
begin
insert into BOOKS_JOURNAL values ​​('UPDATE', old.id_books, new.id_books, old.id_publishers, new.id_publishers, old.k_pages, new.k_pages, old.cover, new.cover, old.tiraz, new.tiraz, old . id_abonent, new.id_abonent, old.date_issue, new.date_issue, old.name, new.name, 'now', 'now', gen_id (generator_journal, 1));
end
IF (deleting) THEN
begin
insert into BOOKS_JOURNAL values ​​('DELETE', old.id_books, null, old.id_publishers, null, old.k_pages, null, old.cover, null, old.tiraz, null, old.id_abonent, null, old.date_issue, null , old.name, null, 'now', 'now', gen_id (generator_journal, 1));
end
end
^ SET TERM; ^
Тригер складається з трьох умовних операторів, які перевіряють чи виконується над записами таблиці відповідно операція вставки, зміни та видалення. Для операції вставки буде виконано перший оператор, де в таблиці журналу в полі «OPERATION» буде вставлено значення «INSERT», в полі «DATE_» поточна дата (значення «now»), в полі «TIME_» поточний час (значення «now» ), також будуть переписані всі нові значення полів, а в полях таблиці журналу, визначених для зберігання старих значень полів таблиці «BOOKS», занесуть значення NULL. Другий оператор "IF (updating) THEN» перевіряє, чи виконується зміна даних, і якщо так, то виконається оператор вставки запису в таблицю журналу «BOOKS_JOURNAL». Цей оператор заданий аналогічно попередньому, тільки в поля під старі значення замість NULL заносяться значення відповідних стовпців таблиці «BOOKS» до їх зміни. Аналогічно заданий останній оператор на видалення запису з таблиці «BOOKS», де NULL заноситься в стовпці під нові значення.
Створимо тригери каскадного оновлення та вилучення даних.
Створимо тригер каскадного оновлення та вилучення даних «BOOKS» при оновленні та видаленні відповідних ним записів у таблиці «PUBLISHERS».
Цей тригер закріплений за таблицею «PUBLISHERS», і заданий як тригер для зміни і видалення записів. Для створення тригера виберемо Triggers / New Trigger ... (Тригер / Новий тригер). З'явиться вікно створення тригера, в якому вкажемо:
· Ім'я - «PUBLISHERS_CASCADE_BOOKS»;
· Для таблиці - «PUBLISHERS»;
· Тип - «BEFORE», тобто виконується перш операції;
· Зазначимо UPDATE, DELETE.
Повний текст тригера буде наступний:
SET TERM ^;
CREATE OR ALTER TRIGGER PUBLISHERS_CASCADE_BOOKS FOR PUBLISHERS
ACTIVE BEFORE UPDATE OR DELETE POSITION 0
AS
begin
IF (updating) THEN
begin
update books C
set C.id_publishers = new.id_publishers
where c.id_publishers = old.id_publishers;
end
else
begin
delete from books C
where c.id_publishers = old.id_publishers;
end
end
^
SET TERM; ^
Оскільки даний тригер виконується при зміні та видаленні записів з таблиці «PUBLISHERS», то в ньому задана умова, що перевіряє, яка операція над записами цієї таблиці проводиться. IF (updating) THEN = ІСТИНА, якщо операція зміни (UPDATE), інакше = БРЕХНЯ (для даного тригера це операція видалення). У першому випадку проводиться каскадне оновлення записів за допомогою оператора зміни даних UPDATE, у другому каскадне видалення за допомогою операції DELETE FROM. В обох випадках умовою відбору записів на зміну або видалення є рівність значень поля «ID_PUBLISHERS» таблиці «BOOKS» і старим значенням поля «ID_PUBLISHERS» таблиці «PUBLISHERS». У разі зміни даних цих полях присвоюються нові значення записів.
Аналогічно створимо тригер каскадного оновлення та вилучення даних «BOOKS» при оновленні та видаленні відповідних ним записів у таблиці «READERS» - «READERS_CASCADE_BOOKS». Різниця тут у тому, що тригер буде задано для таблиці «READERS» і в записах порівнюються значення полів «ID_ABONENT».

Створення збережених процедур

Створимо три збережених процедури.
Перша процедура буде виводити список книг, що знаходяться в бібліотеці. Для цього задамо запит на вибірку списку книг, в полі «BOOKS.ID_ABONENT» яких стоїть значення NULL.
Для створення нової процедури виберемо Procedures \ New Procedure (Процедури \ Нова процедура). Виберемо Output Parameters (Вихідні Параметри) потім Insert parameter / variable (Додати параметр / змінну). Додамо параметр «NAME_BOOKS VARCHAR (30)» під назву книги, а також ще два - під найменування і місто видавництва - відповідно «NAME_PUBLISHERS VARCHAR (20)» і «CITY_PUBLISHERS VARCHAR (20)».
Лістинг першої процедури «BOOKS_LIBRARY»:
CREATE PROCEDURE BOOKS_LIBRARY
returns (
city_publishers varchar (20) character set win1251,
name_publishers varchar (20) character set win1251,
name_books varchar (30) character set win1251)
as
begin
for
select distinct books.name, publishers.name, publishers.city
from books inner join publishers on books.id_publishers = publishers.id_publishers
where books.id_abonent iS NULL
into: name_books,: name_publishers,: city_publishers
do suspend;
end
В цій процедурі замість звичайного запиту на вибірку SELECT використана конструкція «FOR SELECT ... INTO ... DO ...», що робить обробку повертається набору записів у циклі. Інакше якщо SELECT поверне більше одного рядка, то виникне помилка «multiple rows in singleton select». Тут же після кожної повертається рядка відбувається примусовий видача параметрів, після чого вони приймають нові значення при наступній ітерації циклу і т. д. поки не будуть видані всі рядки, що задовольняють умові запиту.
Друга процедура буде виводити список книг, виданих за вказаний період (вхідні параметри - початкова та кінцева дата). Задамо вхідні параметри «DATE_1 DATE» і «DATE_2 DATE». Задамо вихідні параметри: «NAME_BOOKS VARCHAR (30)», «NAME_PUBLISHERS VARCHAR (20)» і «CITY_PUBLISHERS VARCHAR (20)».
Лістинг процедури «BOOKS_LIST_PERIOD»:
CREATE PROCEDURE BOOKS_LIST_PERIOD (
date_1 date,
date_2 date)
returns (
city_publishers varchar (20) character set win1251,
name_publishers varchar (20) character set win1251,
name_books varchar (30) character set win1251)
as
declare variable var_date date;
begin
for
select distinct books.name, publishers.name, publishers.city, books.date_issue
from books inner join publishers on books.id_publishers = publishers.id_publishers
into: name_books,: name_publishers,: city_publishers,: var_date
do if (var_date between date_1 and date_2) then suspend;
end
У цій процедурі в операторі циклічної вибірки для кожного запису, отриманої в результаті виконання оператора вибірки «SELECT», перевіряється, чи лежить значення однієї з повертаються SELECT-му змінної var_date між двома введеними, заданими вхідними параметрами date_1 і date_2. Якщо так, то проводиться видача процедурою значень вихідних параметрів за допомогою оператора suspend.
Створимо третій процедуру, яка буде виводити кількість книг і середній тираж по видавництвах. Тут вихідні дані будуть представляти собою значення функцій агрегування, обчислювані для кожної групи за значенням поля «PUBLISHERS. NAME ».
Лістинг процедури «KOL_BOOKS_TIRAZ»:
CREATE PROCEDURE KOL_BOOKS_TIRAZ
returns (
publishers_name varchar (20) character set win1251,
avg_tiraz integer,
count_ integer)
as
begin
for
select distinct publishers.name, count (publishers.id_publishers), AVG (books.tiraz)
from books inner join publishers on books.id_publishers = publishers.id_publishers
group by publishers.name
into: publishers_name,: count_,: avg_tiraz
do suspend;
end
Вихідними параметрами процедури є:
· Publishers_name varchar (20) character set win1251 - строковою параметр для значень імені видавництва;
· Avg_tiraz integer - параметр для середнього значення тиражу книги кожної групи.
· Count_ integer - параметр для видачі значення кількості рядків кожної групи.
В цій процедурі здійснюється вибірка значень поля «PUBLISHERS.NAME», кількості повертаються рядків і середнього значення по полю «BOOKS.TIRAZ» для кожного значення поля «PUBLISHERS.NAME».
Тепер структура бази даних готова. Заповнимо таблиці деякими записами:
Таблиця «Видавництва» (Publishers)
ID_Publishers
Name
City
1
Пітер
С. - Петербург
2
ДіаСофт
Київ
3
КОРОНА принт
С. - Петербург
4
Фінанси та статистика
Москва
Таблиця «Читачі» (Readers)
ID _ abonent
FIO
Telephone
Address
1
Іванов Вадим
12345678
Москва вул. 1 буд.1 кв. 1
2
Петров Борис
11111111
Орел вул. 1 буд.1 кв. 1
3
Сидоров Іван
22222222
Курськ вул. 1 буд.1 кв. 1
4
Кузнєцов Артем
12121212
Воронеж вул.1 буд.1 кв.1
Таблиця «Книжки» (Books)
ID_ Books
Name
ID_ Publishers
K_ pages
Cover
Tiraz
ID_ abonent
Date_issue
1
Ефективна робота із СУБД
1
704
твердий
6000
1
01.01.2009
2
Delphi. Розробка баз даних
1
477
твердий
5000
1
01.01.2009
3
Бази даних і додатки
2
592
твердий
7000
2
11.01.2009
4
Бази даних
2
416
твердий
5000
NULL
NULL

Створення клієнтської програми баз даних

Створимо клієнтське додаток в ІСР Delphi, використовуючи технологію доступу до даних InterBase eXdivss (IBX).
Виберемо File / New / Application (Файл / Нове / Додаток), потім додамо модуль даних для компонентів доступу до даних - File / New / Data Module (Файл / Новий / Модуль даних). Компоненти доступу до даних розташовані на сторінці Data Access Палітри компонентів. Компоненти відображення даних розташовані на сторінці Data Controls Палітри компонентів. Компоненти, що використовуються в технології InterBase eXdivss распологаются на сторінці InterBase, а компоненти для створення звітів - QReport.
Помістимо на модуль даних компонент TIBDatabase. Зазначимо у властивості DatabaseName повний шлях (включаючи ім'я сервера) до обраного файлу БД - «C: \ 01 \ LIBRARY.FDB».
Помістимо наступні компоненти на форму модуля даних:
· Компонент IBTransaction
· Три IBDataSet,
· Три DataSource
Підключимося до бази даних. Виділимо компонент TIBDatabase і виберемо з контекстного меню Database Editor. ... У цьому вікні вкажемо User Name = SYSDBA, Character Set = WIN1251. Потім встановимо властивість Connected компонента IBDatabase1 рівним True і властивість DefaultTransaction компонента IBDatabase1 рівним IBTransaction1.
Задамо керування транзакціями. Зробимо активним компонент IBTransaction1, для чого його властивості Active додамо значення True. Викличемо редактор Transaction Editor ..., і в діалоговому вікні виберемо рівень ізоляції транзакцій - Read Committed.
Встановимо значення властивостей:
· DefaultAction - TACommitRetaining
· DefaultDatabase - IBDatabase1
· Params - read_committed
rec_version
nowait
· Active - True
Перейдемо до компоненту IBDataSet1. Перейменуємо його на BOOKS_DataSet (властивість Name). Зазначимо базу даних - DataBase = IBDataBase1 і компонент обробки транзакцій - Transaction = IBTransaction1. Зазначимо у властивості SelectSQL текст основного запиту: «select * from BOOKS». За допомогою властивості GeneratorField вибираємо поле, значення якого привласнюється генератором і сам генератор. Активуємо компонент: Active - True. Викличемо редактор компонента Dataset Editor .... Виберемо зі списку Table Name таблицю і натиснемо кнопку Get Table Fields (Отримати поля таблиці). У списку Key Fields (Ключові поля) виділимо полі «ID_BOOKS», яке будуть формувати умова WHERE в запитах. Після натискання на кнопку Generate SQL автоматично згенерує значення властивостей DeleteSQL, InsertSQL, ModifySQL, RefreshSQL. Ці значення стануть рівні:
DeleteSQL:
delete from BOOKS
where
ID_BOOKS =: OLD_ID_BOOKS
InsertSQL:
insert into BOOKS
(ID_BOOKS, NAME, ID_PUBLISHERS, K_PAGES, COVER, TIRAZ, ID_ABONENT, DATE_ISSUE)
values
(: ID_BOOKS,: NAME,: ID_PUBLISHERS,: K_PAGES,: COVER,: TIRAZ,: ID_ABONENT,
: DATE_ISSUE)
ModifySQL:
update BOOKS
set
ID_BOOKS =: ID_BOOKS,
NAME =: NAME,
ID_PUBLISHERS =: ID_PUBLISHERS,
K_PAGES =: K_PAGES,
COVER =: COVER,
TIRAZ =: TIRAZ,
ID_ABONENT =: ID_ABONENT,
DATE_ISSUE =: DATE_ISSUE
where
ID_BOOKS =: OLD_ID_BOOKS
RefreshSQL:
Select
ID_BOOKS,
NAME,
ID_PUBLISHERS,
K_PAGES,
COVER,
TIRAZ,
ID_ABONENT,
DATE_ISSUE
from BOOKS
where
ID_BOOKS =: ID_BOOKS
Аналогічно задамо значення властивостей двом іншим компонентам IBDataSet.
У кожного компонента DataSource у властивості Dataset вкажемо назву відповідного йому компонента IBDataSet.
Створимо три форми для відображення таблиць. На кожну форму помістимо компоненти DBGrid і DBNavigator. У компонентів DBGrid і DBNavigator у властивості DataSource вкажемо відповідний компонент DataSource.

Пошук даних

Для пошуку даних використовується функція
function LocateNext (const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean;
де KeyFields - список полів, за якими проводиться пошук (імена полів розділяються крапкою з комою), KeyValues ​​- список значень, порівнюваних із значеннями цих полів (значення розділяються комою), TLocateOptions - параметри пошуку, де loCaselnsensitive означає пошук без урахування регістру (великі та малі символи), а loPartialKey. - Значення полів для пошуку дані не повністю. Функція LocateNext дозволяє знаходити декілька записів, які відповідають умовам пошуку, для відображення чергового запису слід викликати функцію ще раз. Функція повертає значення логічного типу, рівного TRUE (ІСТИНА), якщо знайдена відповідна запис, і FALSE (БРЕХНЯ) у противному випадку.
На формі відображення і редагування даних з таблиці BOOKS для пошуку розмістимо наступні компоненти:
· Edit1 - для введення користувачем значень KeyValues.
· Button1 - для активації пошуку.
· Кілька компонентів CheckBox для зазначення списку полів для пошуку, тобто значення KeyFields.
У процедурі - обробнику події натискання на кнопку Button1 спочатку здійснюється збір рядка списку полів KeyFields відповідно до вказівок прапорців CheckBox. Потім це значення разом зі значенням поля Edit1 відправляється у функцію LocateNext через користувача функцію loc (Fields, Values), описану в модулі Unit2 (в модулі Unit2 описаний клас TDataModule2 (форма модуля даних) в якому визначено і компонент «BOOKS_DataSet: TIBDataSet;») .
Аналогічно в програмі організований пошук в таблицях PUBLISHERS і READERS.

Фільтрація даних

Задамо фільтрацію значень в таблиці BOOKS.
На формі таблиці BOOKS помістимо компоненти CheckBox для того, щоб користувач мав можливість включати і вимикати фільтр по окремих полях. Фільтр проводиться тільки за тих полів, для яких вибрані відповідні їм перемикачі CheckBox, для цього в програмі визначені логічні змінні (в модулі Unit2) для вказівки, чи слід фільтрувати записи по введеному користувачем значенням відповідного поля. Для включення фільтра служить кнопка «Увімкнути фільтр» де виробляється присвоєння змінним (модуля Unit2) введених значень вказаних полів, після чого включається фільтр завданням властивості BOOKS_DataSet.Filtered значення True. Після того, як властивості Filtered компонента TIBDataSet буде присвоєно значення True то виробляється переоткритіє набору даних, але при цьому виконується метод OnFilterRecord цього компоненту. Процедура - обробник цього методу визначена наступним чином:
procedure TDataModule2.BOOKS_DataSetFilterRecord (DataSet: TDataSet; var Accept: Boolean);
де DataSet відповідний набір даних. Ця процедура виконується для кожного запису і якщо повертається цією процедурою параметр Accept дорівнює True, то поточна запис відображається, у противному випадку - ні. Приклад фільтра:
if (DataSet ['NAME'] <> Name_) then Accept: = False;
де NAME - назва поля, Name_ - змінна, значення якої порівнюється зі значенням цього поля поточного запису.
У програмі визначено такий фільтр:
procedure TDataModule2.BOOKS_DataSetFilterRecord (DataSet: TDataSet;
var Accept: Boolean);
begin
Accept: = True;
if P1 then if (DataSet ['NAME'] <> Name_) then Accept: = False;
if P2 then if (DataSet ['K_PAGES'] <K_Pages_1) then Accept: = False;
if P3 then if (DataSet ['K_PAGES']> K_Pages_2) then Accept: = False;
if P4 then if (DataSet ['DATE_ISSUE'] <Date_1) then Accept: = False;
if P5 then if (DataSet ['DATE_ISSUE']> Date_2) then Accept: = False;
if P6 then if (DataSet ['ID_PUBLISHERS'] <> Id_pub) then Accept: = False;
if P7 then if (DataSet ['COVER'] <> Cov) then Accept: = False;
if P8 then if (DataSet ['TIRAZ'] <Tiraz_1) then Accept: = False;
if P9 then if (DataSet ['TIRAZ']> Tiraz_2) then Accept: = False;
if 10 then if (DataSet ['ID_ABONENT'] <> Id_ab) then Accept: = False;
end;
Логічні змінні P1 - P10 зберігають значення, що відповідають вибраним прапорцям CheckBox, і якщо прапорець обраний, то відповідна йому змінна буде дорівнює True, а значить, буде проводитися фільтр за значенням цього поля. Спочатку мінлива Accept приймає значення True, тобто вважається, що рядок проходить, якщо не буде показано невиконання хоча б однієї умови фільтрації. Тому тут перевіряється невиконання кожного із заданих умов (наприклад замість «DataSet ['NAME'] = Name_» перевіряється «DataSet ['NAME'] <> Name_» і ставиться не «Accept: = True» у разі виконання цієї умови, а « Accept: = False »). Досить невиконання однієї умови, щоб рядок не пройшла, тобто мінлива Accept приймає значення False.
Аналогічно задамо фільтр і для інших таблиць.

Висновок звіту

Організуємо висновок звітів в програмі. Для початку створимо запит на вибірку записів таблиці BOOKS, де замість кодів видавництва і читача буде виводитися вся про них інформація, отримана з таблиць PUBLISHERS і READERS. Для цього помістимо компонент IBQuery, назвемо його BOOKS_Query і у властивості SQL запишемо:
select all BOOKS.NAME, BOOKS.COVER, BOOKS.TIRAZ, BOOKS.K_PAGES, PUBLISHERS.NAME, PUBLISHERS.CITY, READERS.FIO, READERS.ADDRESS, READERS.TELEPHONE, BOOKS.DATE_ISSUE
from (BOOKS inner join PUBLISHERS on BOOKS.ID_PUBLISHERS = PUBLISHERS.ID_PUBLISHERS) left join READERS on BOOKS.ID_ABONENT = READERS.ID_ABONENT
order by BOOKS.NAME;
Запит виводить поля з усіх трьох таблиць. Таблиці BOOKS і PUBLISHERS пов'язані з рівності поля ID_PUBLISHERS, а отримана в результаті такого зв'язку вибірка додатково пов'язана з таблицею READERS за рівністю поля ID_ABONENT. Тут завдяки зв'язку left join в запит виводяться записи, що містять в полі BOOKS.ID_ABONENT значення NULL. Додатково до записів застосовується сортування за значенням поля BOOKS.NAME.
Встановимо властивість Active компонента BOOKS_Query в True. Якщо при цьому не з'явиться повідомлення про помилку, то запит SQL введено без помилок.
Також помістимо на модуль даних компонент DataSourse, назвемо його BOOKS_Query_Source і у властивості DataSet вкажемо BOOKS_Query.
Створимо нову форму і помістимо на неї компонент DBGrid1 у властивості DataSourse якого вкажемо DataModule2.BOOKS_Query_Source. На формі розташуємо кнопку «Вивести звіт», після натискання на яку буде виводитися звіт запиту BOOKS_Query.
Для створення безпосередньо звіту створимо для нього нову форму і помістимо на неї компонент QuickRep. І вкажемо у властивості DataSet DataModule2.BOOKS_Query. Зазначимо у властивості Page.Orientation = poLandscape (Пейзажна орієнтація сторінки). У властивості Bands встановимо в True наступні подсвойства: HasDetail, hasTitle, PageHander. Помістимо на компонент QuickRep в область Detail компоненти QRDBText для кожного поля, у властивості DataSet яких вкажемо DataModule2.BOOKS_Query, а властивості DataField відповідне поле. В область Title помістимо така ж кількість компонентів QRLabel для назв атрибутів, і вкажемо ці назви у властивості Caption цих компонентів. Розташуємо на формі компоненти QRTextFilter, QRHTMLFilter для збереження звітів у форматах HTML, TXT. В області звіту PageHander помістимо компонент QRSysData для виведення поточної дати, для чого у властивості Data встановимо значення qrsDate. Ті ж компоненти використовуємо і для виведення поточного часу і поточного номера сторінки.

Введення SQL запитів і висновок збережених процедур

Працюючи з додатком баз даних, користувач повинен мати можливість задавати SQL запити, деякі з яких збережені на сервері у вигляді збережених процедур. Для забезпечення такої можливості слід на головну форму помістити компонент для введення тексту Memo, в який користувач і буде вводити текст запиту. Потім на модуль даних помістимо компонент IBQuery1: TIBQuery1 (відповідно і DataSource1: TDataSource1), створимо форму для виведення результату і помістимо на неї компонент DBGrid1: TDBGrid1. Потім на головну форму помістимо кнопку і в обробнику її натискання задамо перезапис введеного запиту з текстового поля у властивість SQL компонента IBQuery1 після чого зробимо компонент IBQuery1 активним та відобразимо форму виведення результату.
Якщо в запиті вказати висновок збереженої процедури, просто вказавши
select * from KOL_BOOKS_TIRAZ;
або
select * from BOOKS_LIBRARY;
то виконається запит, визначений у цій процедурі.
Лістинг процедури - обробника події натискання на кнопку «Вивести результат запиту»:
procedure TForm1.Button10Click (Sender: TObject);
var i: integer;
begin
DataModule2.IBQuery1.Active: = False;
DataModule2.IBQuery1.SQL.Clear;
for i: = 0 to Memo1.Lines.Count do
begin
DataModule2.IBQuery1.SQL.Append (Memo1.Lines [i]);
end;
DataModule2.IBQuery1.Active: = True;
Form10.Show;
end;
Для збереженої процедури з вхідними параметрами попередньо потрібно вказати значення цих параметрів, тому виклик збереженої процедури BOOKS_LIST_PERIOD організований окремо. Лістинг процедури, що виконує виклик цієї процедури у програмі:
procedure TForm1.Button9Click (Sender: TObject);
begin
DataModule2.IBQuery1.SQL.Clear;
DataModule2.IBQuery1.SQL.Add ('select * from BOOKS_LIST_PERIOD (' + # 39 + MaskEdit1.Text + # 39 +','+# 39 + MaskEdit2.Text + # 39 +');');
DataModule2.IBQuery1.Active: = true;
Form9.Show;
end;
Тут за допомогою процедури Add додається запис до властивості SQL компонента IBQuery1 (попередньо вона очищається за допомогою процедури Clear). MaskEdit1.Text і MaskEdit2.Text - значення полів введення значень вхідних параметрів, # 39 - ASCII код одинарної лапки, лапки потрібні для укладання в них значень вхідних параметрів процедури, що зберігається в SQL запиті. Потім активується компонент IBQuery1 і відображається форма виведення результату збереженої процедури.

Список літератури

1. Ковязін С., Востріков С. Світ InterBase. Архітектура, адміністрування та розробка додатків баз даних в InterBase / Firebird / Yaffil. - М.: КУДИЦ - ОБРАЗ, 2005. - 496 с.
2. Хомоненко А.Д., Гофман В.Е. Робота з базами даних в Delphi. - СПб.: БХВ - Петербург, 2005. - 640с.
3. Кондзюба С.П., Громов В.М. Delphi 6. Бази даних та програми: Лекції і вправи. - Київ: ДіаСофт, 2001. - 576 с.
4. http://www.ibase.ru/devinfo/ibfaq.htm
5. http://www.piter.com/lib/978527200003/sql7.phtml?fil=Ch12
6. http://www.codenet.ru/progr/delphi/stat/SQL-Delphi.php
Додати в блог або на сайт

Цей текст може містити помилки.

Програмування, комп'ютери, інформатика і кібернетика | Контрольна робота
103.8кб. | скачати


Схожі роботи:
Проектування реляційних баз даних
Методологія проектування баз даних 2
Проектування баз даних MS Access
Основні принципи проектування баз даних
Введення в проектування реляційних баз даних
Методологія проектування баз даних 2 лютого
Теорія проектування віддалених баз даних
Принципи побудови та етапи проектування баз даних
Проектування інформаційних баз даних звіт за відвантаженими товарами
© Усі права захищені
написати до нас