Мета: отримати уявлення про призначення, структуру та послідовність DDL і DML команд мови SQL на прикладі створення БД «БІБЛІОТЕКА».
Script-файл – це програма, яка автоматизує деяке завдання, яке без сценарію користувач робив би вручну, використовуючи інтерфейс програми. Це найбільш загальне визначення файлу script, яке нам вдалося знайти. Звузимо це визначення для нашого випадку: script-файл – це послідовність DDL і DML команд мови SQL для створення фізичної моделі БД.
На нашу думку методика застосування скриптів SQL в Interbase не відрізняється від інших СУБД для створення фізичної моделі БД. Загалом для СУБД Interbase вона включає три послідовні кроки:
Для створення та редагування script-файлу в ОС Windows Вам буде цілком достатньо програми «Блокнот». MS Word використовуйте для цього обережно. Справа в тому, що ця програма має приховані керуючі символи. Вони можуть бути причиною нетипової поведінки обробника script-файлів у СУБД Interbase.
Досвід роботи показує, що сценарій створення фізичної моделі реляційної БД у script-файлі зручніше виконувати крок за кроком. Після кожного SQL-оператора або групи операторів Ви маєте можливість бачити результат їхньої роботи. Якщо він Вас влаштовує, перенесіть SQL-оператори у script-файл. Такий підхід дозволить одержати сценарій відновлення початкової структури БД. Надалі Ви маєте можливість доповнювати чи змінювати його. Залишилося додати, що якісна логічна модель БД забезпечує успіх її фізичного моделювання.
Для створення БД «БІБЛІОТЕКА» скористаємся script-файлом. Він містить 8-м частин:
Оператор «COMMIT;» завершує script-файл. Він закриває транзакцію, яка автоматично була відкрита одразу перед початком його виконання. Він фіксує всі зміни, які були виконані в БД «БІБЛІОТЕКА». Решта операторів у script-файлі мають докладні коментарі.
Давайте докладно розглянемо послідовність дій створення БД «БІБЛІОТЕКА» в СУБД «Interbase».
Рис. Г.1. Діалогове вікно Transaction Editor
Script-файл перевірений на наявність помилок в Interbase 2020. Після його виконання до БД LIBRARY.IB будуть додані всі об'єкти та дані, які описані DDL та DML командами мови SQL у script-файлі. Наприклад, у лівій частині діалогового вікна Interactive SQL «Tables and Views» Ви можете бачити список таблиць та представлень даних БД «БІБЛІОТЕКА». Знайдіть в цьому списку таблицю READERS й встановить на неї курсор. В «Fields» Ви побачите список її стовбців. Порівняйте його з описом цієї таблиц у фізичній моделі.
Для того щоб побачити дані, які занесені у таблицю READERS виконайте найпростіший оператор SELECT з прикладу 6.1. Для цього скопіюйте його в Input Aria діалогового вікна Interactive SQL. Далі в Tool Bar натисніть кнопку Execute. Результат буде відображений в Output Aria.
Приємного вивчення організації реляційних баз даних.
Оператори, що призначені для створення доменів, які визначених у фізичній моделі БД «БІБЛІОТЕКА».*/
/* Домен призначено для визначення унікального номера рядків для усіх відношень БД «БІБЛІОТЕКА» (поле Code). Цей домен використовується для всіх вторинних ключів, які посилаються на первинні ключі та не допускають значення NULL.*/
CREATE DOMAIN AllCode AS INTEGER
NOT NULL;
/* Домен призначений для визначення коду бібліотекаря, який прийняв книгу читача. Це зовнішній ключ таблиці BookGiveOutRecord. Він припускає значення NULL. Коли читач бере книгу в бібліотеці, ми не можемо заздалегідь визначити бібліотекаря, який прийме її. */
CREATE DOMAIN InLibrarianCode AS INTEGER;
/* Домен призначений для визначення множини усіх прізвищ, імен та по-батькові людей БД «БІБЛІОТЕКА» (поля FamilyName, Name, Patronymic).*/
CREATE DOMAIN FIO AS CHAR(30)
NOT NULL;
/* Домен призначений для визначення множини усіх додаткових відомостей та автобіографій людей БД «БІБЛІОТЕКА» (поля Note, ShortBiography).*/
CREATE DOMAIN AllNote AS BLOB;
/* Домен призначений для визначення множини усіх назв книг БД «Бібліотека» у (поле Name у таблиці Books).*/
CREATE DOMAIN BookName AS CHAR(200)
NOT NULL;
/* Домен призначений для визначення множини усіх тиражів книг БД «Бібліотека» (поле Drawing у таблиці Books).*/
CREATE DOMAIN AllDrawing AS INTEGER
CHECK(VALUE >= 10)
NOT NULL;
/* Домен призначений для визначення множини усіх УДК БД «Бібліотека» (поле UDK у таблиці Books).*/
CREATE DOMAIN AllUDK AS CHAR(20)
NOT NULL;
/* Домен призначений для визначення множини усіх шифрів книг БД «Бібліотека» (поле Cipher у таблиці Books).*/
CREATE DOMAIN AllCipher AS CHAR(30)
NOT NULL;
/* Домен призначений для визначення множини усіх серій паспортів БД «Бібліотека» (поле Series у таблиці PasportData).*/
CREATE DOMAIN AllSeries AS CHAR(2)
NOT NULL;
/* Домен призначений для визначення множини усіх номерів паспортів БД «Бібліотека» (поле Number у таблиці PasportData).*/
CREATE DOMAIN AllNumber AS INTEGER
CHECK(VALUE >= 10)
NOT NULL;
/* Домен призначений для визначення множини усіх місць народження БД «Бібліотека» (поле BirthPlace у таблиці PasportData).*/
CREATE DOMAIN AllPlace AS CHAR(100)
NOT NULL;
/* Домен призначений для опису статі БД «Бібліотека» (поле Sex у таблиці PasportData).*/
CREATE DOMAIN AllSex AS CHAR(100)
CHECK(VALUE IN ('Ж','Ч'));
/* Домен призначений для визначення множини усіх місць видачі паспорта БД «Бібліотека» (поле IssuePlace у таблиці PasportData).*/
CREATE DOMAIN AllIssuePlace AS CHAR(100)
NOT NULL;
/* Домен призначений для визначення множини усіх типів книжкових фондів БД «Бібліотека» (поле AllName у таблиці BookFunds).*/
CREATE DOMAIN AllName AS CHAR(20)
NOT NULL;
/* Домен призначений для визначення множини усіх типів телефонів БД «Бібліотека» (поле AllNameType у таблиці PhoneTypes).*/
CREATE DOMAIN AllNameType AS CHAR(20)
NOT NULL;
/* Домен призначений для визначення множини усіх номерів читацьких квитків БД «Бібліотека» (поле ReaderCardNumber у таблиці Readers).*/
CREATE DOMAIN AllReaderCardNumber AS INTEGER
CHECK(VALUE >= 10)
NOT NULL;
/* Домен призначений для визначення множини усіх табельних номерів БД «Бібліотека» (поле ClockNumber у таблиці Librarians).*/
CREATE DOMAIN AllClockNumber AS INTEGER
CHECK(VALUE >= 10)
NOT NULL;
/* Домен призначений для визначення множини усіх інвентарних номерів книг БД «Бібліотека» (поле InventoryNumber у таблиці BookInventoryNumbers).*/
CREATE DOMAIN AllInventoryNumber AS INTEGER
CHECK(VALUE >= 10)
NOT NULL;
/* Домен призначений для роботи з вартістю кожної книги БД «Бібліотека» (поле Cost у таблиці BookInventoryNumbers).*/
CREATE DOMAIN AllCost AS FLOAT
NOT NULL;
/* Домен призначений для визначення множини усіх місць основної роботи читачів БД «Бібліотека» (поле Job у таблиці Readers).*/
CREATE DOMAIN AllJob AS CHAR(60)
NOT NULL;
/* Домен призначений для визначення множини усіх посад БД «Бібліотека» (поле AllPost у таблиці Readers).*/
CREATE DOMAIN AllPost AS CHAR(30)
NOT NULL;
/* Домен призначений для визначення множини усіх домашніх телефонів бібліотекарів БД «Бібліотека» (поле HomePhone у таблиці Librarians).*/
CREATE DOMAIN AllHomePhone AS CHAR(20)
NOT NULL;
Далі йдуть оператори, які створюють таблиці бази даних.*/
/* Спочатку створюємо таблиці, на які є посилання зовнішніх ключів – фраза FOREIGN KEY оператора CREATE TABLE. З двох таблиць таблиць PasportData та Readers першою має бути створена таблиця PasportData.*/
/* Створюємо таблицю, в якій зберігатимуться відомості про паспортні дані. */
CREATE TABLE PasportData
(Code AllCode,
Series AllSeries,
Number AllNumber,
Birthday DATE NOT NULL,
BirthPlace AllPlace,
Sex AllSex,
IssuePlace AllIssuePlace,
IssueDate DATE,
Note AllNote);
/* Створюємо таблицю, в якій зберігатимуться відомості про читачів. */
CREATE TABLE Readers
(Code AllCode,
FamilyName FIO,
Name FIO,
Patronymic FIO,
ReaderCardNumber AllReaderCardNumber,
PasportCode AllCode,
Job AllJob,
Post AllPost,
Note AllNote);
/* Створюємо таблицю, в якій зберігатимуться відомості про бібліотекарів. */
CREATE TABLE Librarians
(Code AllCode,
ClockNumber AllClockNumber,
FamilyName FIO,
Name FIO,
Patronymic FIO,
PasportCode AllCode,
Post AllPost,
HomePhone AllHomePhone,
Note AllNote,
PRIMARY KEY (Code));
/* Створюємо таблицю, в якій зберігатимуться відомості про типи книжкових фондів. */
CREATE TABLE BookFunds
(Code AllCode,
Name AllName,
PRIMARY KEY (Code));
/* Створюємо таблицю, в якій зберігатимуться відомості про типи телефонів. */
CREATE TABLE PhoneTypes
(Code AllCode,
Name AllNameType,
PRIMARY KEY (Code));
/* Створюємо таблицю, в якій зберігатимуться відомості про авторів книг. */
CREATE TABLE BookAuthors
(Code AllCode,
FamilyName FIO,
Name FIO,
Patronymic FIO,
Birthday DATE NOT NULL,
Deatheday DATE,
ShortBiography AllNote,
PRIMARY KEY (Code));
/* Створюємо таблицю, в якій зберігатимуться відомості про книги, що зберігаються у фондах бібліотеки. */
CREATE TABLE Books
(Code AllCode,
Name BookName,
IssueYear DATE NOT NULL,
Drawing AllDrawing,
BookPublishers CHAR(60),
UDK AllUDK,
Cipher AllCipher,
Note AllNote,
PRIMARY KEY (Code));
/* Створюємо таблицю, яка дозволяє вказувати для однієї книги декілька авторів та для одного автора декілька книг. З точки зору реляційної БД ця таблиця замінює відношення «багато до багатьох» між таблицями BookAuthors та Books на два відношення «один до багатьох». Одне – між таблицями BookAuthors та CoAuthorship, а друге між таблицями Books та CoAuthorship. Це наочно видно на діаграмі «сутність зв’язок» БД «БІБЛІОТЕКА». */
CREATE TABLE CoAuthorship
(BookCode AllCode,
AuthorCode AllCode,
PRIMARY KEY (BookCode, AuthorCode),
FOREIGN KEY (AuthorCode) REFERENCES BookAuthors
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (BookCode) REFERENCES Books
ON DELETE CASCADE
ON UPDATE CASCADE);
/* Створюємо таблицю, в якій зберігатимуться відомості про телефони. */
CREATE TABLE Phones
(ReaderCode AllCode,
PhoneTypesCode AllCode,
PhoneNumber AllHomePhone);
/* Створюємо таблицю, в якій зберігатимуться відомості про інвентарні номери книг. */
CREATE TABLE BookInventoryNumbers
(Code AllCode,
BookCode AllCode,
FundCode AllCode,
InventoryNumber AllInventoryNumber,
Cost AllCost,
PRIMARY KEY (Code),
FOREIGN KEY (BookCode) REFERENCES Books
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (FundCode) REFERENCES BookFunds
ON DELETE CASCADE
ON UPDATE CASCADE);
/* Створюємо таблицю, де зберігатимуться відомості про облік видачі книг. */
/* Є одна істотна відмінність між зовнішніми ключами, які забезпечують цілісність посилань даних між таблицею BookGiveOutRecord і таблицями Librarians та BookInventoryNumbers. FOREIGN KEY (OutLibrarianCode) та FOREIGN KEY (InventoryCode) вимагають ОБЯЗАТЕЛЬНОГО присутності значень первинних ключів Librarians.Code та BookInventoryNumbers.Code. FOREIGN KEY (InLibrarianCode) не вимагає обов'язкової присутності значення Librarians.Code. Ми не знаємо наперед який бібліотекар прийме книгу, коли читач її поверне. При додаванні нового рядка ми не вводимо код бібліотекаря, залишаючи значення NULL. Домен InLibrarianCode допускає введення цього значення. */
CREATE TABLE BookGiveOutRecord
(Code AllCode,
ReaderCode AllCode,
OutLibrarianCode AllCode,
InventoryCode AllCode,
IssueDate DATE NOT NULL,
ReturnDate DATE NOT NULL,
FactReturnDate DATE,
InLibrarianCode InLibrarianCode,
PRIMARY KEY (Code),
FOREIGN KEY (OutLibrarianCode) REFERENCES Librarians
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (InventoryCode) REFERENCES BookInventoryNumbers
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (InLibrarianCode) REFERENCES Librarians
ON DELETE CASCADE
ON UPDATE CASCADE);
/* СТВОРЕННЯ ПРЕДСТАВЛЕНЬ ДАНИХ
Оператори, які створюють представлення даних. */
/* Створюємо представлення даних для довідника "КНИГИ". */
CREATE VIEW Book
(InventoryNumber, BookName, IssueYear, Drawing, UDK, Cipher,
FamilyName, BookAuthorsName, Patronymic, Birthday,
Deatheday, FundName)
AS
SELECT BIN.InventoryNumber, B.Name, B.IssueYear, B.Drawing, B.UDK, B.Cipher,
BA.FamilyName, BA.Name, BA.Patronymic, BA.Birthday,
BA.Deatheday, BF.Name
FROM BookInventoryNumbers BIN, Books B, BookAuthors BA, BookFunds BF, CoAuthorship CA
WHERE BIN.BookCode = B.Code AND
BIN.FundCode = BF.Code AND
CA.AuthorCode = BA.Code AND
B.Code = CA.BookCode;
/* Створюємо представлення даних для довідника "ЧИТАЧІ". */
CREATE VIEW ReadersView
(ReaderCode, FamilyName, ReaderName, Patronymic, ReaderCardNumber,
Job, Post, Series, Number, BirthDay,
BirthPlace, Sex, IssuePlace, IssueDate)
AS
SELECT R.Code, R.FamilyName, R.Name, R.Patronymic, R.Job,
R.Post, R.ReaderCardNumber, PD.Series, PD.Number, PD.BirthDay,
PD.BirthPlace, PD.Sex, PD.IssuePlace, PD.IssueDate
FROM Readers R, PasportData PD
WHERE PD.Code = R.PasportCode;
CREATE VIEW PhonesView
(ReaderCode, TypeName, PhoneNumber, PhoneTypesCode)
AS
SELECT P.ReaderCode, P.PhoneNumber, PT.Name, PT.Code
FROM Phones P, PhoneTypes PT
WHERE P.PhoneTypesCode = PT.Code;
Оператори, які створюють генератори значень первинних ключів. */
/* Визначаємо генератор для поля Code таблиці BookAuthors та встановлюємо його початкове значення. */
CREATE GENERATOR BookAuthorsCode;
SET GENERATOR BookAuthorsCode TO 0;
/* Визначаємо генератор для поля Code таблиці PasportData та встановлюємо його початкове значення. */
CREATE GENERATOR PasportDataCode;
SET GENERATOR PasportDataCode TO 0;
/* Визначаємо генератор для поля Code таблиці Books та встановлюємо його початкове значення. */
CREATE GENERATOR BooksCode;
SET GENERATOR BooksCode TO 0;
/* Визначаємо генератор для поля Code таблиці Readers та встановлюємо його початкове значення. */
CREATE GENERATOR ReadersCode;
SET GENERATOR ReadersCode TO 0;
/* Визначаємо генератор для поля Code таблиці Librarians та встановлюємо його початкове значення. */
CREATE GENERATOR LibrariansCode;
SET GENERATOR LibrariansCode TO 0;
/* Визначаємо генератор для поля Code таблиці BookInventoryNumbers та встановлюємо його початкове значення. */
CREATE GENERATOR BookInventoryNumbersCode;
SET GENERATOR BookInventoryNumbersCode TO 0;
/* Визначаємо генератор для поля Code таблиці BookFunds та встановлюємо його початкове значення. */
CREATE GENERATOR BookFundsCode;
SET GENERATOR BookFundsCode TO 0;
/*Определяем генератор для поля Code таблиці PhoneTypes та встановлюємо його початкове значення. */
CREATE GENERATOR PhoneTypesCode;
SET GENERATOR PhoneTypesCode TO 0;
/*Определяем генератор для поля Code таблиці BookGiveOutRecord та встановлюємо його початкове значення. */
CREATE GENERATOR BookGiveOutRecordCode;
SET GENERATOR BookGiveOutRecordCode TO 0;
/* ВИЗНАЧЕННЯ ВИЙНЯТКОВИХ СИТУАЦІЙ
Оператори, які визначають виняткові ситуації для процедур і тригерів, що зберігаються. */
CREATE EXCEPTION ReaderCardNumberIsDuplicate
'У довіднику є читач з № читацького квитка, який Ви вводите!!!';
CREATE EXCEPTION ReaderPassportIsFound
'У довіднику є читач з серією та номером паспорта, який Ви вводите!!!';
CREATE EXCEPTION PsprtCdInReadersIsDuplicate
'Введення двох однакових значень потенційного ключа Readers.PassportCode!!!';
CREATE EXCEPTION PsprtCdInPasportDataNotFound
'Значення зовнішнього ключа Readers.PassportCode немає у PasportData.Code!!!';
CREATE EXCEPTION SrsAndNmbrIsDuplicate
'Паспорт із серією та номером, які Ви вводите, вже зареєстрований у БД!!!';
CREATE EXCEPTION PrKeyRdrPhnNbrIsDuplicate
'ReaderCode, PhoneNumber - первинний ключ таблиці Phones. Не дублювати!!!';
CREATE EXCEPTION PrKeyInPasportDataIsDuplicate
'Ввод двух одинаковых значений первичного ключа PasportData.Code не припустимо';
CREATE EXCEPTION ValOfFrKeyInLibrariansIsFound
'Значення PasportData.Code є у Librarians.PasportCode. Паспорт не видалено!!!';
CREATE EXCEPTION ValOfFrKeyInReadersIsFound
'Значення PasportData.Code є у Readers.PasportCode. Паспорт не видалено!!!';
CREATE EXCEPTION PrKeyInReadersDataIsDuplicate
'Введення двох однакових значень первинного ключа Readers.Code не припустимо!!!';
CREATE EXCEPTION ValOfFrKeyInPhonesIsFound
'Значення Readers.Code є у Phones.ReaderCode. Читача не видалено!!!';
CREATE EXCEPTION ValOfFrKeyInBkGvOutRcrdIsFound
'Значення Readers.Code є у BookGiveOutRecord.ReaderCode. Читача не видалено!!!';
CREATE EXCEPTION ReaderCodeIsNotFound
'Значення зовнішнього ключа Phones.ReaderCode відсутнє у Readers.Code!!!';
CREATE EXCEPTION PhoneTypeCodeIsNotFound
'Значення зовнішнього ключа Phones.PhoneTypeCode відсутнє у PhoneTypes.Code!!!';
/* СТВОРЕННЯ ТРИГГЕРІВ І ЗБЕРЕЖУВАНИХ ПРОЦЕДУР
Реалізовано тригери та процедури, що зберігаються, тільки для забезпечення корпоративних обмежень цілісності довідника "ЧИТАЧІ". */
/* За замовчуванням оператори в script-файлі розділяються крапкою з комою. Але ми не можемо використовувати цей роздільник між тригером або процедурою, що зберігається, і наступним оператором. Тому ми змінюємо крапку з комою на інший роздільник. Його ми будемо використовувати тільки після останнього оператора тригера або процедури. Усередині тригерів і процедур оператори розділятимуться як і раніше крапкою з комою.*/
SET TERM ### ;
/* Створюємо процедури, що зберігаються, і тригера, які забезпечують посилальну цілісність при додаванні зміні та видаленні рядків з таблиць, а також описують найбільш часто зустрічаються запити даних. */
/************************** ДОВІДНИК "ЧИТАЧІ" **********************************/
/* Процедура забезпечує цілісність даних, що додаються або змінюються у таблиці PasportData. */
CREATE PROCEDURE BfrInsUpdInPasportData
/* Процедура викликається з тригерів BfrInsInPasportData та BfrUpdInPasportData, які спрацьовують до події додавання та оновлення даних операторами INSERT та UPDATE відповідно.
Фактично ці тригери замінюють фразу PRIMARY KEY (Code) в операторі CREATE TABLE PasportData
Тригери забезпечують цілісність сутності паспорт. По-перше, вони виключають додавання двох однакових значень первинного ключа у поле Code. По-друге, вони не дозволяють додати пару однакових значень у поля Series та Number. Ці поля є потенційним ключем таблиці PasportData.
В обох випадках генерується виняткова ситуація.
ВНИМАНИЕ!!!
Ми не можемо використовувати зовнішні ключі у таблицях Readers та Libranians після видалення фрази PRIMARY KEY (Code) з оператора CREATE TABLE PasportData. Ми говоримо про фрази FOREIGN KEY (PasportCode) REFERENCES PasportData в операторах CREATE TABLE Readers та CREATE TABLE Librarians.
Але база даних потребує цілісності посилання для коректної роботи з даними читачів та бібліотекарів. ЇЇ підтримку забезпечують тригера і процедури, що зберігаються. Вони описані нижче.
УВАГА!!!
Ми не можемо одночасно використовувати тригери та ключі для забезпечення цілісності даних між парою відносин. Починайте із ключів. Це найпростіший спосіб забезпечення цілісності даних. Якщо потрібні складніші перевірки чи дії вибирайте тригери.
ПЕРЕВІРКА ЗНАЧЕНЬ, ЯКІ ВВОДЯТЬСЯ В ІНШІ АТРИБУТИ, ЗДІЙСНЮЄТЬСЯ НА РІВНІ ДОМЕНІВ. */
/* Ознака додавання нового рядка до таблиці. */
(DoInsert INTEGER,
/* Нове значення ідентифікатора паспорта. (первинний ключ CODE в таблиці PasportData). */
NewCode INTEGER,
/* Нове значення серії паспорта. Це є ПЕРША частина потенційного ключа в таблиці PasportData, який складається із серії та № паспорта. */
NewSeries CHAR(2),
/* Нове значення № паспорта. Це є ДРУГА частина потенційного ключа в таблиці PasportData, який складається із серії та № паспорта. */
NewNumber INTEGER,
/* СТАРЕ значення ідентифікатора паспорта (первинний ключ Code в таблиці PasportData). */
OldCode INTEGER,
/* СТАРЕ значення серії паспорта. Це є ПЕРША частина потенційного ключа в таблиці PasportData, який складається із серії та № паспорта. */
OldSeries CHAR(2),
/* СТАРЕ значення № паспорта. Це є ДРУГА частина потенційного ключа в таблиці PasportData, який складається із серії та № паспорта. */
OldNumber INTEGER)
AS
/* У змінну поміщаємо кількість паспортів, зареєстрованих у БД «БІБЛІОТЕКА», які мають значення первинного ключа збігаються зі значенням первинного ключа нового паспорта. Це значення отримано процедурою параметра New.Code. */
DECLARE VARIABLE CodeIsFound INTEGER;
/* Поміщаємо в змінну кількість паспортів, зареєстрованих у БД «БІБЛІОТЕКА», у яких серія та номер співпадають із серією та номером нового паспорта. Значення номера паспорта отримано процедурою у параметрі NewNumber. Значення серії паспорта отримано процедурою у NewSeries. */
DECLARE VARIABLE SrsAndNmbrIsFound INTEGER;
BEGIN
/* Процес перевірки значень при додаванні нового запису відрізняється від процесу перевірки значень під час коригування даних у вже існуючому рядку таблиці. Основна відмінність полягає в тому, що при додаванні нового запису необхідно перевіряти всі значення, а при коригуванні даних необхідно перевіряти лише ті значення, які були змінені. Ця особливість реалізована за допомогою операторів IF. Перша умова однакова для кожного оператора. Якщо :DoInsert = 1, тоді процедура викликана з тригера BfrInsInPasportData, який спрацював до додавання нового запису. У цьому випадку відпрацюють усі умови перевірки. Якщо :DoInsert = 0, процедура була викликана з тригера BfrUpdInPasportData. У цьому випадку перевірки виконуються у кожному блоці лише для тих значень, які було змінено. */
IF (:DoInsert = 1 OR :NewCode != :OldCode) THEN
BEGIN
/* Методом підрахунку визначаємо кількість значень первинного ключа Code. */
SELECT COUNT(*)
FROM PasportData PD
WHERE PD.Code = :NewCode
INTO :CodeIsFound;
/* Якщо у таблиці PasportData вже є значення первинного ключа Code, яке отримане процедурою у параметрі :NewCode, то генерується виняткова ситуація PrKeyInPasportDataIsDuplicate. */
IF (:CodeIsFound > 0) THEN
EXCEPTION PrKeyInPasportDataIsDuplicate;
END
IF (:DoInsert = 1 OR (:NewSeries != :OldSeries OR :NewNumber != :OldNumber)) THEN
BEGIN
/* Визначаємо кількість пар значень Series, Numbers складеного потенційного ключа розрахунковим методом. */
SELECT COUNT(*)
FROM PasportData PD
WHERE PD.Series = :NewSeries AND
PD.Number = :NewNumber
INTO :SrsAndNmbrIsFound;
/* Якщо у таблиці PasportData вже є пара значень Series, Numbers складеного потенційного ключа, отримана процедурою в параметрах :NewSeries і :NewNumbers, то генерується виняткова ситуація SrsAndNmbrIsDuplicate. */
IF (:SrsAndNmbrIsFound > 0) THEN
EXCEPTION SrsAndNmbrIsDuplicate;
END
END###
/* Тригер забезпечує цілісність даних при введенні нового рядка до таблиці PasportData. */
CREATE TRIGGER BfrInsInPasportData FOR PasportData
ACTIVE
BEFORE INSERT
AS
BEGIN
/* Виконуємо процедуру, яка забезпечує цілісність даних у таблиці PasportData при їх додаванні чи зміні. */
EXECUTE PROCEDURE BfrInsUpdInPasportData(1,
New.Code,
New.Series,
New.Number,
New.Code,
New.Series,
New.Number);
END###
/* Тригер забезпечує цілісність даних при їх коригуванні в таблиці PasportData. */
CREATE TRIGGER BfrUpdInPasportData FOR PasportData
ACTIVE
BEFORE UPDATE
AS
BEGIN
/* Виконуємо процедуру, яка цілісність даних у таблиці PasportData при їх додаванні чи зміні. */
EXECUTE PROCEDURE BfrInsUpdInPasportData(0,
New.Code,
New.Series,
New.Number,
Old.Code,
Old.Series,
Old.Number);
END###
/* Процедура забезпечує цілісність даних, що додаються або змінюються в таблиці Readers.*/
CREATE PROCEDURE BfrInsUpdInReaders
/* Процедура викликається з тригерів BfrInsInReaders та BfrUpdInReaders, які спрацьовують до події додавання та оновлення даних операторами INSERT та UPDATE відповідно.
Фактично ці тригери замінюють пропозицію PRIMARY KEY (Code) в операторі CREATE TABLE Readers
Тригери забезпечують цілісність сутності "Читач". Вони виключають додавання однакових значень потенційних ключів Code; PasportCode та ReaderCardNumber для двох різних читачів.
Додавання існуючого значення для будь-якого потенційного ключа генерує винятокову ситуацію.
ВНИМАНИЕ!!!
Ми відмовилися від пропозиції PRIMARY KEY (Code) в операторі CREATE TABLE Readers . У цьому випадку посилальна цілісність між таблицями Phones, BookGiveOutRecord та таблицею Readers підтримуватиметься за допомогою тригерів. Зовнішні ключі Phones.ReaderCode, BookGiveOutRecord.ReaderCode залишилися без змін.
УВАГА!!!
Ми не можемо одночасно використовувати тригери та ключі для забезпечення цілісності даних між парою відносин. Починайте із ключів. Це найпростіший спосіб забезпечення цілісності даних. Якщо потрібні складніші перевірки чи дії вибирайте тригери.
ПЕРЕВІРКА ЗНАЧЕНЬ, ЯКІ ВВОДЯТЬСЯ В ІНШІ АТРИБУТИ, ЗДІЙСНЮЄТЬСЯ НА РІВНІ ДОМЕНІВ. */
/* Ознака додавання нового рядка до таблиці. */
(DoInsert INTEGER,
/* Нове значення ідентифікатора читача (первинний ключ CODE в таблиці Readers). */
NewCode INTEGER,
/* Нове значення № картки читача. Це потенційний й зовнішній ключ таблиці Readers. */
NewReaderCardNumber INTEGER,
/* Нове значення ідентифікатора паспорта читача. Це потенційний й зовнішній ключ таблиці Readers. */
NewPasportCode INTEGER,
/* СТАРЕ значення ідентифікатора читача. (первинний ключ CODE в таблиці Readers). */
OldCode INTEGER,
/* СТАРЕ значення № картки читача. Це потенційний й зовнішній ключ таблиці Readers. */
OldReaderCardNumber INTEGER,
/* СТАРЕ значення ідентифікатора паспорта читача. Це потенційний й зовнішній ключ таблиці Readers. */
OldPasportCode INTEGER)
AS
/* Ця змінна використовується для збереження результату підрахунку значень первинного ключа Readers.Code, яке отримано процедурою у параметрі NewCode. Зверніть увагу, що в Readers.Code зберігаються ідентифікатори всіх читачів, які зареєстровані у базі даних LIBRARY. */
DECLARE VARIABLE CodeIsFound INTEGER;
/* Ця змінна використовується для збереження результату підрахунку значень потенційного ключа Readers.ReaderCardNumber, що отриманий процедурою у параметрі NewReaderCardNumber. Цей ідентифікатор використовується бібліотекарами. */
DECLARE VARIABLE ReaderCardNbrIsFound INTEGER;
/* Ця змінна використовується для збереження результату підрахунку значень потенційного ключа Readers.PasportCode, який отриманий процедурою у параметрі NewPasportCode. Він також використовується як зовнішній ключ таблиці Readers для зв'язку з таблицею PasportData.). */
DECLARE VARIABLE PasportCodeIsFound INTEGER;
/* Ця змінна використовується для збереження результату підрахунку значень первинного ключа Pasport.Code, який отриманий процедурою у параметрі NewPasportCode. Він також використовується як ідентифікатор паспорта читача. */
DECLARE VARIABLE PasportCodeIsFoundInPD INTEGER;
BEGIN
/* Коментар дивись після оператора BEGIN процедури BfrInsUpdInPasportData. */
IF (:DoInsert = 1 OR :NewCode != :OldCode) THEN
BEGIN
/* Методом підрахунку визначаємо кількість нових значень первинного ключа Code у таблиці Readers. */
SELECT COUNT(*)
FROM Readers R
WHERE R.Code = :NewCode
INTO :CodeIsFound;
/* Спроба реєстрації двох читачів з однаковим значенням ідентифікатора: NewCode у первинному ключі Readers.Code генерує виняткову ситуацію PrKeyInReadersDataIsDuplicate. */
IF (:CodeIsFound > 0) THEN
EXCEPTION PrKeyInReadersDataIsDuplicate;
END
/* Коментар дивись після оператора BEGIN процедури BfrInsUpdInPasportData. */
IF (:DoInsert = 1 OR :NewReaderCardNumber != :OldReaderCardNumber) THEN
BEGIN
/* Методом підрахунку визначаємо кількість нових значень потенційного ключа ReaderCardNumber у таблиці Readers. */
SELECT COUNT(*)
FROM Readers R
WHERE R.ReaderCardNumber = :NewReaderCardNumber
INTO :ReaderCardNbrIsFound;
/* Спроба реєстрації двох читачів з однаковим значенням ідентифікатора: NewReaderCardNumber у потенційному ключі Readers.ReaderCardNumber генерує виняткову ситуацію ReaderCardNumberIsDuplicate. */
IF (:ReaderCardNbrIsFound > 0) THEN
EXCEPTION ReaderCardNumberIsDuplicate;
END
/* Коментар дивись після оператора BEGIN процедури BfrInsUpdInPasportData. */
IF (:DoInsert = 1 OR :NewPasportCode != :OldPasportCode) THEN
BEGIN
/* Методом підрахунку визначаємо кількість нових значень потенційного ключа PasportCode у таблиці Readers. */
SELECT COUNT(*)
FROM Readers R
WHERE R.PasportCode = :NewPasportCode
INTO :PasportCodeIsFound;
IF (:PasportCodeIsFound = 0) THEN
BEGIN
/* Методом підрахунку визначаємо кількість значень первинного ключа Code у таблице PasportData. */
SELECT COUNT(*)
FROM PasportData PD
WHERE PD.Code = :NewPasportCode
INTO :PasportCodeIsFoundInPD;
IF (:PasportCodeIsFoundInPD != 1) THEN
/* Значенням ідентифікатора паспорта читача NewPasportCode не знайдено в первинному ключі PasportData.Code. Реєстрація такого читача генерує виняткову ситуацію PsprtCdInPasportDataNotFound. */
EXCEPTION PsprtCdInPasportDataNotFound;
END
ELSE
/* Спроба реєстрації двох читачів з однаковим значенням ідентифікатора паспорта NewPasportCode в потенційному ключі Readers.PasportCode генерує виняткову ситуацію PsprtCdInReadersIsDuplicate. */
EXCEPTION PsprtCdInReadersIsDuplicate;
END
END###
/* Тригер забезпечує цілісність даних при введенні нового рядка в таблицю Readers. */
CREATE TRIGGER BfrInsInReaders FOR Readers
ACTIVE
BEFORE INSERT
AS
BEGIN
/* Виконуємо процедуру, яка забезпечує цілісність даних у таблиці Readers при їх додаванні чи зміні. */
EXECUTE PROCEDURE BfrInsUpdInReaders(1,
New.Code,
New.ReaderCardNumber,
New.PasportCode,
New.Code,
New.ReaderCardNumber,
New.PasportCode);
END###
/* Тригер забезпечує цілісність даних при їх коригуванні в таблиці Readers. */
CREATE TRIGGER BfrUpdInReaders FOR Readers
ACTIVE
BEFORE UPDATE
AS
BEGIN
/* Виконуємо процедуру, яка забезпечує цілісність даних у таблиці Readers при їх додаванні чи зміні. */
EXECUTE PROCEDURE BfrInsUpdInReaders(0,
New.Code,
New.ReaderCardNumber,
New.PasportCode,
Old.Code,
Old.ReaderCardNumber,
Old.PasportCode);
END###
/* Процедура забезпечує цілісність даних, що додаються або змінюються в таблиці Phones. */
CREATE PROCEDURE BfrInsUpdInPhones
/* Процедура викликається з тригерів BfrInsInPhones и BfrUpdInPhones, которые срабатывают до события добавления и обновления данных операторами INSERT и UPDATE соответственно. Эти триггера обеспечивают целостность сущности "№ телефона читателя". Они исключают добавление данных о двух одинаковых № телефона для одного читателя. Таким образом в таблице Phones не может быть двух одинаков пар значений ReaderCode и PhoneNumber. Эта пара столбцов является составным потенциальным и первичным ключом таблицы Phones.
Додавання існуючої пари значень первинного ключа генерує виняткову ситуацію.
Тригери BfrInsInPhones, BfrUpdInPhones і BfrDltInReaders забезпечують цілісність посилань між сутностями "№ телефону читача" ( відношення Phones) і "читач" ( відношення Readers). Додатково тригери BfrInsInPhones, BfrUpdInPhones забезпечують цілісну зв'язок між сутностями "тип № телефону читача" ( відношення Phones) і "тип телефону" ( відношення PhoneTypes).
Це дає можливість не визначати зовнішні ключі FOREIGN KEY (ReaderCode) REFERENCES Readers та FOREIGN KEY (PhoneTypesCode) REFERENCES PhoneTypes в операторі CREATE TABLE Phones
УВАГА!!!
Прочитайте опис тригера BfrDltInReaders. Для таблиці PhoneTypes подібний тригер не визначено. Без нього не буде підтримана цілісність посилань між таблицями Phones и PhoneTypes в повному обсязі. Спробуйте створити цей тригер самостійно.
УВАГА!!!
Ми не можемо одночасно використовувати тригери та ключі для забезпечення цілісності даних між парою відносин. Починайте із ключів. Це найпростіший спосіб забезпечення цілісності даних. Якщо потрібні складніші перевірки чи дії вибирайте тригери.
ПЕРЕВІРКА ЗНАЧЕНЬ, ЯКЕ ВВОДИТЬСЯ В АТРИБУТ PhoneNumber, ЗДІЙСНЮЄТЬСЯ НА РІВНІ ДОМЕНА. */
/* Ознака додавання нового рядка до таблиці. */
(DoInsert INTEGER,
/* Нове значення ідентифікатора читача (зовнішній ключ Phones.ReaderCode). */
NewReaderCode INTEGER,
/* Нове значення ідентифікатора типу телефону читача (зовнішній ключ Phones.PhoneTypesCode). */
NewPhoneTypesCode INTEGER,
/* Нове значення № телефону читача. */
NewPhoneNumber CHAR(20),
/* СТАРЕ значення ідентифікатора читача (зовнішній ключ Phones.ReaderCode). */
OldReaderCode INTEGER,
/* СТАРЕ значення ідентифікатора типу телефону читача (зовнішній ключ Phones.PhoneTypesCode). */
OldPhoneTypesCode INTEGER,
/* СТАРЕ значення № телефону читача. */
OldPhoneNumber CHAR(20))
AS
/* Змінна використовується для збереження результату підрахунку кількісті значень зовнішнього ключа Phones.ReaderCode. Підрахунок здійснюється серед значень первинного ключа Readers.Code. Значення зовнішнього ключа процедура отримує у параметрі NewReaderCode. */
DECLARE VARIABLE ReaderCodeIsFound INTEGER;
/* Змінна використовується для збереження результату підрахунку кількісті значень зовнішнього ключа Phones.PhoneTypesCode. Підрахунок здійснюється серед значень первинного ключа PhoneTypes.Code. Значення зовнішнього ключа процедура отримує у параметрі NewPhoneTypesCode. */
DECLARE VARIABLE PhoneTypeCodeIsFound INTEGER;
/* Змінна використовується для збереження результату підрахунку кількісті пари значень ReaderCode, PhoneNumber у таблиці Phones. Вони є складовим потенційним і первинним ключем у відношенні Phones. Процедура отримує пару значень цього ключа через параметри NewReaderCode та NewPhoneNumber. */
DECLARE VARIABLE PrKeyRdrPhnNbrIsDuplicate INTEGER;
BEGIN
/* Коментар дивись після оператора BEGIN процедури BfrInsUpdInPasportData. */
IF (:DoInsert = 1 OR :NewReaderCode != :OldReaderCode) THEN
BEGIN
/* Методом підрахунку визначаємо кількість нових значень зовнішнього ключа Phones.ReaderCode серед значень первинного ключа Readers.Code. */
SELECT COUNT(*)
FROM Readers R
WHERE R.Code = :NewReaderCode
INTO :ReaderCodeIsFound;
/* Виняткова ситуація ReaderCodeIsNotFound генерується якщо значення ідентифікатора читача: NewReaderCode не знайдено в таблиці Readers. */
IF (:ReaderCodeIsFound != 1) THEN
EXCEPTION ReaderCodeIsNotFound;
END
/* Коментар дивись після оператора BEGIN процедури BfrInsUpdInPasportData. */
IF (:DoInsert = 1 OR :NewPhoneTypesCode != :OldPhoneTypesCode) THEN
BEGIN
/* Методом підрахунку визначаємо кількість нових значень зовнішнього ключа Phones.PhoneTypesCode серед значень первинного ключа PhoneTypes.Code. */
SELECT COUNT(*)
FROM PhoneTypes PT
WHERE PT.Code = :NewPhoneTypesCode
INTO :PhoneTypeCodeIsFound;
/* Виняткова ситуація PhoneTypeCodeIsNotFound генерується, якщо значення ідентифікатора типу телефону: NewPhoneTypesCode не знайдено в таблиці PhoneTypes. */
IF (:PhoneTypeCodeIsFound != 1) THEN
EXCEPTION PhoneTypeCodeIsNotFound;
END
/* Коментар дивись після оператора BEGIN процедури BfrInsUpdInPasportData. */
IF (:DoInsert = 1 OR :NewReaderCode != :OldReaderCode OR :NewPhoneNumber != :OldPhoneNumber) THEN
BEGIN
/* Методом підрахунку визначаємо кількість нових значень складеного потенційного та первинного ключа ReaderCode, PhoneNumber. */
SELECT COUNT(*)
FROM Phones P
WHERE P.ReaderCode = :NewReaderCode AND
P.PhoneNumber = :NewPhoneNumber
INTO :PrKeyRdrPhnNbrIsDuplicate;
/* Спроба реєстрації двох однакових номерів телефону: NewPhoneNumber для одного ідентифікатора читача: NewReaderCode генерує виняткову ситуацію PrKeyRdrPhnNbrIsDuplicate. */
IF (:PrKeyRdrPhnNbrIsDuplicate > 0) THEN
EXCEPTION PrKeyRdrPhnNbrIsDuplicate;
END
END###
/* Тригер забезпечує цілісність даних при введенні нового рядка в таблицю Phones. */
CREATE TRIGGER BfrInsInPhones FOR Phones
ACTIVE
BEFORE INSERT
AS
BEGIN
/* Процедура забезпечує цілісність даних у таблиці Phones при їх додаванні або зміні. */
EXECUTE PROCEDURE BfrInsUpdInPhones(1,
New.ReaderCode,
New.PhoneTypesCode,
New.PhoneNumber,
New.ReaderCode,
New.PhoneTypesCode,
New.PhoneNumber);
END###
/* Тригер забезпечує цілісність даних при їх коригуванні в таблиці таблиці Phones. */
CREATE TRIGGER BfrUpdInPhones FOR Phones
ACTIVE
BEFORE UPDATE
AS
BEGIN
/* Процедура забезпечує цілісність даних у таблиці Phones при їх додаванні або зміні. */
EXECUTE PROCEDURE BfrInsUpdInReaders(0,
New.ReaderCode,
New.PhoneTypesCode,
New.PhoneNumber,
Old.ReaderCode,
Old.PhoneTypesCode,
Old.PhoneNumber);
END###
/* Тригер забезпечує каскадне оновлення ідентифікатору паспорта у таблицях Readers та Librarians. Ідентифікатор паспорта посилається на значення первинного ключа PasportData.Code. */
CREATE TRIGGER AftUpdtInPasportData FOR PasportData
/* Це дає можливість не визначати зовнішні ключі з каскадним оновленням в операторах CREATE TABLE Readers та CREATE TABLE Librarians
УВАГА!!!
Ми не маємо можливості одночасно використовувати тригери та ключі для каскадного оновлення. */
ACTIVE
AFTER UPDATE
AS
BEGIN
/* Значення первинного ключа PasportData.Code змінено. */
IF (NEW.Code != OLD.Code) THEN
BEGIN
/* Каскадне оновлення зовнішнього ключа Readers.PasportCode. */
UPDATE Readers
SET PasportCode = NEW.Code
WHERE PasportCode = OLD.Code;
/* Каскадне оновлення зовнішнього ключа Librarians.PasportCode. */
UPDATE Librarians
SET PasportCode = NEW.Code
WHERE PasportCode = OLD.Code;
END
END###
/* Тригер забезпечує каскадне оновлення значення ідентифікатора читача ReaderCode у таблиці Phones. */
CREATE TRIGGER AftUpdtInReaders FOR Readers
/* Ідентифікатор читача посилається на первинний ключ Readers.Code. У цьому випадку зовнішній ключ ReaderCode повинен бути визначений без пропозиції ON UPDATE CASCADE в операторі CREATE TABLE Phones .
УВАГА!!!
Ми не можемо одночасно використовувати тригери та ключі для каскадного оновлення. */
ACTIVE
AFTER UPDATE
AS
BEGIN
/* Значення первинного ключа Readers.Code змінено. */
IF (NEW.Code != OLD.Code) THEN
BEGIN
/* Каскадне оновлення зовнішнього ключа Phones.ReaderCode. */
UPDATE Phones
SET ReaderCode = NEW.Code
WHERE ReaderCode = OLD.Code;
END
END###
/* Тригер забезпечує цілісність даних між таблицею Readers та таблицями Phones й BookGiveOutRecord. */
CREATE TRIGGER BfrDltInReaders FOR Readers
/* Перед видаленням рядка у таблиці Readers послідовно виконуються дві дії. Пошук значення первинного ключа Readers.Code серед значень зовнішніх ключів Phones.ReaderCode та BookGiveOutRecord.ReaderCode. Якщо хоча б один пошук буде вдалим, то буде згенеровано виняткову ситуацію.
Такий підхід до забезпечення цілісності даних еквівалентний визначенню зовнішніх ключів Phones.ReaderCode та BookGiveOutRecord.ReaderCode без опції ON DELETE CASCADE. Каскадне видалення у цьому тригері можна організувати за допомогою операторів
DELETE FROM Phones
WHERE ReaderCode = Old.Code
DELETE FROM BookGiveOutRecord
WHERE ReaderCode = Old.Code
Їх потрібно розмістити замість операторів
EXCEPTION ValOfFrKeyInPhonesIsFound
EXCEPTION ValOfFrKeyInBkGvOutRcrdIsFound
УВАГА!!!
Ми не можемо одночасно використовувати тригери та ключі для каскадного видалення. */
ACTIVE
BEFORE DELETE
AS
/* Змінна використовується для збереження результату підрахунку кількісті значення первинного ключа Readers.Code серед значень зовнішніх ключів Phones.ReaderCode та BookGiveOutRecords.ReaderCode. */
DECLARE VARIABLE ReaderCodeIsFound INTEGER;
BEGIN
/* Методом підрахунку визначаємо кількість старих значень первинного ключа Readers.Code серед значень вторинного ключа Phones.ReaderCode. Old.Code – значення Readers.Code у рядку, який видаляється з таблиці Readers. */
SELECT COUNT(*)
FROM Phones P
WHERE P.ReaderCode = Old.Code
INTO :ReaderCodeIsFound;
/* Виняткова ситуація ValOfFrKeyInPhonesIsFound генерується, якщо старе значення первинного ключа Readers.Code знайдено серед значень вторинного ключа Phones.ReaderCode. */
IF (:ReaderCodeIsFound > 0) THEN
EXCEPTION ValOfFrKeyInPhonesIsFound;
/* Методом підрахунку визначаємо кількість старих значень первинного ключа Readers.Code серед значень вторинного ключа BookGiveOutRecord.ReaderCode. Old.Code – значення Readers.Code у рядку, який видаляється з таблиці Readers. */
SELECT COUNT(*)
FROM BookGiveOutRecord BG
WHERE BG.ReaderCode = Old.Code
INTO :ReaderCodeIsFound;
/* Виняткова ситуація ValOfFrKeyInBkGvOutRcrdIsFound генерується, якщо старе значення первинного ключа Readers.Code знайдено серед значень вторинного ключа BookGiveOutRecord.ReaderCode. */
IF (:ReaderCodeIsFound > 0) THEN
EXCEPTION ValOfFrKeyInBkGvOutRcrdIsFound;
END###
/* Тригер забезпечує цілісність даних між таблицею PasportData та таблицями Readers й Librarians. */
CREATE TRIGGER BfrDltInPasportData FOR PasportData
/* Перед видаленням рядка у таблиці таблиці PasportData послідовно виконуються дві дії. Пошук значення первинного ключа PasportData.Code серед значень зовнішніх ключів Readers.PasportCode та Librarians.PasportCode. Якщо хоча б один пошук буде вдалим, то буде згенеровано виняткову ситуацію.
Такий підхід до забезпечення цілісності даних еквівалентний визначенню зовнішніх ключів Readers.PasportCode та Librarians.PasportCode без опції ON DELETE CASCADE. Каскадне видалення у цьому тригері можна організувати за допомогою операторів
DELETE FROM Readers
WHERE PasportCode = Old.Code;
DELETE FROM Librarians
WHERE PasportCode = Old.Code;
Їх потрібно розмістити замість операторів
EXCEPTION ValOfFrKeyInReadersIsFound;
EXCEPTION ValOfFrKeyInLibrariansIsFound;
УВАГА!!!
Ми не можемо одночасно використовувати тригери та ключі для каскадного видалення. */
ACTIVE
BEFORE DELETE
AS
/* Змінна використовується для збереження результату підрахунку кількісті значення первинного ключа PasportData.Code серед значень зовнішніх ключів Readers.PasportCode та Librarians.PasportCode. */
DECLARE VARIABLE PasportCodeIsFound INTEGER;
BEGIN
/* Методом підрахунку визначаємо кількість старих значень первинного ключа PasportData.Code серед значень вторинного ключа Readers.PasportCode. Old.Code – значення PasportData.Code у рядку, який видаляється з таблиці PasportData. */
SELECT COUNT(*)
FROM Readers R
WHERE R.PasportCode = Old.Code
INTO :PasportCodeIsFound;
/* Виняткова ситуація ValOfFrKeyInReadersIsFound генерується, якщо старе значення первинного ключа PasportData.Code знайдено серед значень вторинного ключа Readers.PasportCode. */
IF (:PasportCodeIsFound > 0) THEN
EXCEPTION ValOfFrKeyInReadersIsFound;
/* Методом підрахунку визначаємо кількість старих значень первинного ключа PasportData.Code серед значень вторинного ключа Librarians.PasportCode. Old.Code – значення PasportData.Code у рядку, який видаляється з таблиці PasportData. */
SELECT COUNT(*)
FROM Librarians L
WHERE L.PasportCode = Old.Code
INTO :PasportCodeIsFound;
/* Виняткова ситуація ValOfFrKeyInLibrariansIsFound генерується, якщо старе значення первинного ключа PasportData.Code знайдено серед значень вторинного ключа Librarians.PasportCode. */
IF (:PasportCodeIsFound > 0) THEN
EXCEPTION ValOfFrKeyInLibrariansIsFound;
END###
/* Процедура повертає кількість повних збігів прізвищ, імен та по-батькові серед читачів. Вона використовується для попередження оператора про такі збіги у довіднику "Читачі". Така інформація корисна при прийнятті рішення щодо додавання нових або коригування існуючих даних про читача у довіднику. */
CREATE PROCEDURE SlcFNP_InReaders
/* Прізвище читача. */
(FamilyName CHAR(30),
/* Ім'я читача. */
Name CHAR(30),
/* По-батькові читача. */
Patronymic CHAR(30))
RETURNS
/* Змінна використовується для збереження результату підрахунку кількості повних збігів прізвищ імен та по-батькові читачів у таблиці Readers та повернення його до програми, яка викликала цю процедуру. */
(FNP_IsFound INTEGER)
AS
BEGIN
/* Результат підрахунку кількості повних збігів прізвища, імені та по батькові читача процедура повертає у додаток клієнта. */
SELECT COUNT(*)
FROM Readers R
WHERE R.FamilyName = :FamilyName AND
R.Name = :Name AND
R.Patronymic = :Patronymic
INTO :FNP_IsFound;
END###
/* Процедура повертає кількість телефонних номерів у таблиці Phones, які не належать читачеві з ідентифікатором, переданим із програми клієнта. Оператор може використовувати цю інформацію для роботи з даними існуючого чи нового читача. */
CREATE PROCEDURE SlcRP_InPhones
/* Телефонний номер читача. */
(PhoneNumber CHAR(20),
/* Ідентифікатор читача. */
ReaderCode INTEGER)
RETURNS
/* Змінна використовується для збереження результату підрахунку кількості телефонних номерів у таблиці Phones, які не належать читачеві з ідентифікатором, переданим із програми клієнта. */
(RP_IsFound INTEGER)
AS
BEGIN
/* Результат підрахунку кількості телефонних номерів у таблиці Phones, які не належать читачеві з ідентифікатором, переданим із програми клієнта. Результат повертається додатку клієнта. */
SELECT COUNT(*)
FROM Phones P
WHERE P.ReaderCode != :ReaderCode AND
P.PhoneNumber = :PhoneNumber
INTO :RP_IsFound;
END###
/* Це процедура дії. Вона викликається з програми клієнта та реєструє нового читача у таблицях Readers та PasportData. Значення параметрів з префіксом "PD_" заносяться до таблиці PasportData. Значення параметрів з префіксом "R_" заносяться до таблиці Readers. */
CREATE PROCEDURE NewReader
/* Серія паспорта читача. */
(PD_Series CHAR(2),
/* № паспорта читача. */
PD_Number INTEGER,
/* Дата народження читача. */
PD_Birthday DATE,
/* Місце народження читача. */
PD_BirthPlace CHAR(100),
/* Стать читача. */
PD_Sex CHAR(1),
/* Місце видачі паспорта читачеві. */
PD_IssuePlace CHAR(30),
/* Дата видачі паспорта читача. */
PD_IssueDate DATE,
/* Прізвище читача. */
R_FamilyName CHAR(30),
/* Ім'я читача. */
R_Name CHAR(30),
/* По-батькові читача. */
R_Patronymic CHAR(30),
/* № читацького квитка. */
R_ReaderCardNumber INTEGER,
/* Місце роботи читача. */
R_Job CHAR(60),
/* Посада читача. */
R_Post CHAR(30))
AS
/* Змінна використовується для збереження результату підрахунку точних збігів пари значень PD_Series та PD_Number у таблиці PasportData. */
DECLARE VARIABLE SrsAndNmbrIsFound INTEGER;
/* У змінну поміщаються ідентифікатор паспорта читача, що реєструється. */
DECLARE VARIABLE R_PasportCode INTEGER;
BEGIN
/* Методом підрахунку визначаємо кількість точних збігів комбінації серії та номера паспорта нового читача зі значеннями PasportData.Series та PasportData.Number. */
SELECT COUNT(*)
FROM PasportData PD
WHERE PD.Series = :PD_Series AND
PD.Number = :PD_Number
INTO :SrsAndNmbrIsFound;
IF (:SrsAndNmbrIsFound = 0) THEN
/* Якщо дані про паспорт нового читача не знайдені у таблиці Readers, тоді оператор INSERT додає дані про нового читача до таблиці PasportData. */
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), :PD_Series, :PD_Number, :PD_Birthday, :PD_BirthPlace,
:PD_Sex, :PD_IssuePlace, :PD_IssueDate);
ELSE
/* Дані про паспорт нового читача знайдено у таблиці Readers.
УВАГА!!!
Новий читач може працювати бібліотекаром. Тому його паспорт може бути вже зареєстрований у таблиці PasportData.
Оператор оновлює дані про паспорт читача у таблиці PasportData. Для цього використовується складовий потенційний ключ PasportData.Series та PasportData.Number. */
UPDATE PasportData
SET Birthday = :PD_Birthday,
BirthPlace = :PD_BirthPlace,
Sex = :PD_Sex,
IssuePlace = :PD_IssuePlace,
IssueDate = :PD_IssueDate
WHERE Series = :PD_Series AND
Number = :PD_Number;
/* Визначаємо ідентифікатор паспорта нового читача. Він нам потрібен для додавання даних про нового читача до таблиці Readers. */
SELECT PD.Code
FROM PasportData PD
WHERE PD.Series = :PD_Series AND
PD.Number = :PD_Number
INTO :R_PasportCode;
/* Оператор додає дані про нового читача до таблиці таблицу Readers. */
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), :R_FamilyName, :R_Name, :R_Patronymic, :R_ReaderCardNumber,
:R_PasportCode, :R_Job, :R_Post);
END###
/* Це процедура дії. Вона викликається з програми клієнта та реєструє новий номер телефону читача у таблиці Phones. */
CREATE PROCEDURE NewReaderPhone
/* Ідентифікатор читача. */
(ReaderCode INTEGER,
/* Ідентифікатор типу телефону. */
PhoneTypesCode INTEGER,
/* № телефону у міжнародному форматі. */
PhoneNumber CHAR(20))
AS
/* Змінна використовується для збереження результатів підрахунку пар значень :ReaderCode та :PhoneNumber у таблиці Phones. Значення Phones.ReaderCode та Phones.PhoneNumber є складовим потенційним та первинним ключем таблиці Phones. */
DECLARE VARIABLE PrKeyIsDuplicate INTEGER;
BEGIN
SELECT COUNT(*)
FROM Phones P
WHERE P.ReaderCode = :ReaderCode AND
P.PhoneNumber = :PhoneNumber
INTO :PrKeyIsDuplicate;
/* Методом підрахунку визначаємо кількість точних збігів пари значень :ReaderCode та :PhoneNumber зі значеннями пари Phones.ReaderCode та Phones.PhoneNumber у рядках таблиці Phones. */
IF (PrKeyIsDuplicate > 0) THEN
/* Телефон читача вже зареєстрований у таблиці Phones. */
UPDATE Phones
SET PhoneTypesCode = :PhoneTypesCode
WHERE ReaderCode = :ReaderCode AND
PhoneNumber = :PhoneNumber;
/* Оператор оновлює дані про ідентифікатор типу телефону читача. */
ELSE
/* Телефон читача не зареєстрований у таблиці Phones. */
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(:ReaderCode, :PhoneTypesCode, :PhoneNumber);
/* Оператор додає дані про новий телефон читача до таблиці Phones. */
END###
/* Це процедура дії. Вона оновлює дані про читача у таблиці Readers. Вона викликається із застосунка клієнта. Для оновлення паспортних даних читача у таблиці PasportData використовуйте процедуру дії UpdDataInPasportData. */
CREATE PROCEDURE UpdDataInReaders
/* У цьому параметрі процедура отримує номер одного з потенційних ключів таблиці Readers: */
/* 1 - Code; */
/* 2 - ReaderCardNumber; */
/* 3 - PasportCode. */
/* Значення потенційного ключа використовується для пошуку рядка з даними читача, які мають бути оновлені. */
(PotentialKey INTEGER,
/* Ідентифікатор читача. */
Code INTEGER,
/* Прізвище читача. */
FamilyName CHAR(30),
/* Ім'я читача. */
Name CHAR(30),
/* По-батькові читача. */
Patronymic CHAR(30),
/* № читацького квитка. */
ReaderCardNumber INTEGER,
/* Ідентифікатор паспорта читача. */
PasportCode INTEGER,
/* Місце роботи читача. */
Job CHAR(60),
/* Посада читача. */
Post CHAR(30))
AS
BEGIN
IF (PotentialKey = 1) THEN
/* Значення потенційного та первинного ключа Readers.Code визначає рядок для коригування даних читача. */
UPDATE Readers
SET FamilyName = :FamilyName,
Name = :Name,
Patronymic = :Patronymic,
ReaderCardNumber = :ReaderCardNumber,
PasportCode = :PasportCode,
Job = :Job,
Post = :Post
WHERE Code = :Code;
/* Оператор UPDATE оновлює всі значення у рядку, крім значення потенційного та первинного ключа Readers.Code. */
IF (PotentialKey = 2) THEN
/* Значення потенційного ключа Readers.ReaderCardNumber визначає рядок коригування даних читача. */
UPDATE Readers
SET FamilyName = :FamilyName,
Name = :Name,
Patronymic = :Patronymic,
ReaderCardNumber = :ReaderCardNumber,
PasportCode = :PasportCode,
Job = :Job,
Post = :Post
WHERE ReaderCardNumber = :ReaderCardNumber;
/* Оператор UPDATE оновлює всі значення в рядку, крім значення потенційного ключа Readers.ReaderCardNumber. */
IF (PotentialKey = 3) THEN
/* Значення потенційного ключа Readers.PasportCode визначає рядок коригування даних читача. */
UPDATE Readers
SET FamilyName = :FamilyName,
Name = :Name,
Patronymic = :Patronymic,
ReaderCardNumber = :ReaderCardNumber,
PasportCode = :PasportCode,
Job = :Job,
Post = :Post
WHERE PasportCode = :PasportCode;
/* Оператор UPDATE оновлює всі значення в рядку, крім значення потенційного ключа Readers.PasportCode. */
END###
/* Це процедура дії. Вона оновлює дані про паспорт читача у таблиці PasportData. Вона викликається із застосунка клієнта. Для оновлення даних читача у таблиці Readers використовуйте процедуру дії UpdDataInReaders. */
CREATE PROCEDURE UpdDataInPasportData
/* У цьому параметрі процедура отримує номер одного з потенційних ключів таблиці PasportData: */
/* 1 - Code; */
/* 2 - Series, Number. */
/* Значення потенційного ключа використовується для пошуку рядка з даними паспорта читача, які мають бути оновлені. */
(PotentialKey INTEGER,
/* Ідентифікатор паспорта. */
Code INTEGER,
/* Серія паспорта. */
Series CHAR(2),
/* № паспорта. */
Number INTEGER,
/* Дата народження читача. */
Birthday DATE,
/* Місце народження читача. */
BirthPlace CHAR(100),
/* Стать читача. */
Sex CHAR(1),
/* Місце видачі паспорта читачеві. */
IssuePlace CHAR(30),
/* Дата видачі паспорта читача. */
IssueDate DATE)
AS
BEGIN
IF (PotentialKey = 1) THEN
/* Значення потенційного та первинного ключа PasportData.Code визначає рядок для коригування даних паспорта читача. */
UPDATE PasportData
SET Series = :Series,
Number = :Number,
Birthday = :Birthday,
BirthPlace = :BirthPlace,
Sex = :Sex,
IssuePlace = :IssuePlace,
IssueDate = :IssueDate
WHERE Code = :Code;
/* Оператор UPDATE оновлює всі значення у рядку, крім значення потенційного та первинного ключа PasportData.Code. */
IF (PotentialKey = 2) THEN
/* Пара значень PasportData.Series і PasportData.Number визначають рядок коригування даних паспорта читача. Ця пара значень є складовим потенційним ключем таблиці PasportData. */
UPDATE PasportData
SET Series = :Series,
Number = :Number,
Birthday = :Birthday,
BirthPlace = :BirthPlace,
Sex = :Sex,
IssuePlace = :IssuePlace,
IssueDate = :IssueDate
WHERE Series = :Series AND
Number = :Number;
/* Оператор UPDATE оновлює всі значення у рядку, крім значень PasportData.Series та PasportData.Number. Ця пара значень є складовим потенційним ключем таблиці PasportData. */
END###
/* Це процедура дії. Вона коригує номер та тип телефону читача у таблиці Phones. Вона викликається із застосунка клієнта. */
CREATE PROCEDURE UpdDataInPhones
/* Ідентифікатор читача. */
(ReaderCode INTEGER,
/* Ідентифікатор типу телефону. */
PhoneTypesCode INTEGER,
/* Старий телефонний номер читача. */
PhoneNumber CHAR(20),
/* Новий номер телефону читача. */
NewPhoneNumber CHAR(20))
AS
BEGIN
/* Оператор UPDATE змінює старий номер читача на новий. У рядку зі старим номером читача пара значень Phones.ReaderCode та Phones.PhoneNumber складеного потенційного та первинного ключа таблиці Phones повинна збігатися з парою значень :ReaderCode та :PhoneNumber. */
UPDATE Phones
SET ReaderCode = :ReaderCode,
PhoneTypesCode = :PhoneTypesCode,
PhoneNumber = :NewPhoneNumber
WHERE ReaderCode = :ReaderCode AND
PhoneNumber = :PhoneNumber;
END###
/* Це процедура дії. Вона видаляє всі дані про читача з БД "БІБЛІОТЕКА". Інформація видаляється з таблиць BookGiveOutRecord, PasportData, Phones та Readers. Процедура викликається із застосунка клієнта. */
CREATE PROCEDURE DltReader
/* Ідентифікатор читача. */
(ReaderCode INTEGER)
AS
/* Змінна використовується для збереження ідентифікатора паспорта читача. */
DECLARE VARIABLE PasportCode INTEGER;
/* Змінна використовується для збереження результату підрахунку кількості ідентифікаторів паспорта читача у таблиці Librarians. */
DECLARE VARIABLE PasportCodeIsFound INTEGER;
BEGIN
/* Оператор видаляє інформацію про телефони читача у таблиці Phones. */
DELETE FROM Phones
WHERE ReaderCode = :ReaderCode;
/* Оператор видаляє інформацію в таблиці BookGiveOutRecord про книги, які видавалися читачеві. */
DELETE FROM BookGiveOutRecord
WHERE ReaderCode = :ReaderCode;
/* Визначаємо ідентифікатор паспорта читача. Він нам потрібен для пошуку в таблиці Librarians. */
SELECT R.PasportCode
FROM Readers R
WHERE R.Code = :ReaderCode
INTO :PasportCode;
/* Оператор видаляє інформацію про читача у таблиці Readers. */
DELETE FROM Readers
WHERE Code = :ReaderCode;
/* Методом підрахунку кількості ведемо пошук ідентифікатора паспорта читача у таблиці Librarians. Якщо його знайдено, то читач є співробітником бібліотеки. */
SELECT COUNT(*)
FROM Librarians L
WHERE L.PasportCode = :PasportCode
INTO :PasportCodeIsFound;
IF (:PasportCodeIsFound = 0) THEN
/* Ідентифікатор паспорта читача не знайдено у таблиці Librarians. Читач не є співробітником бібліотеки. */
DELETE FROM PasportData
WHERE Code = :PasportCode;
/* Оператор видаляє паспортні дані читача у таблиці PasportData. */
END###
/********************* ДОВІДНИК "ЧИТАЧІ" (ЗАВЕРШЕННЯ) **********************/
/* Повертаємо роздільник між операторами script-файлу, який використовується за умовчанням. */
SET TERM ; ###
Індекси необхідні прискорення пошуку інформації у таблицях. Основні принципи їх використання описані у параграфі "Оптимізація структури індексів". */
CREATE INDEX RdrCd
ON BookGiveOutRecord
(FactReturnDate);
CREATE INDEX RdrCdFctRtrnDt
ON BookGiveOutRecord
(ReaderCode, FactReturnDate);
CREATE INDEX CdPsprtCd
ON Readers
(Code, PasportCode);
CREATE INDEX CdBrthday
ON PasportData
(Code, Birthday);
CREATE INDEX CdUDK
ON Books
(Code, UDK);
CREATE INDEX CdBkCd
ON BookInventoryNumbers
(Code, BookCode);
CREATE INDEX FndCd
ON BookInventoryNumbers
(FundCode);
CREATE INDEX RdrCrdNmbr
ON Readers
(ReaderCardNumber);
CREATE INDEX PhnTpCd
ON Phones
(PhoneTypesCode);
/* Операторы INSERT, які додають інформацію до бази даних. */
/* Додаємо 24 рядки до таблиці PasportData. */
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АА', 45003, '05/30/1930', 'Росія, м. Опочки',
'Ж', 'Дніпропетровськ', '01/12/1995');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АА', 15700, '02/23/1930', 'Росія. м. Володимир',
'Ж', 'Житомирр', '03/16/2000');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АБ', 87134, '01/20/1963', 'Дніпропетровська область, село Солоне',
'Ж', 'Дніпропетровська область, село Солоне', '01/10/1998');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АЕ', 12300, '11/12/1960', 'Україна, м. Донецьк',
'Ч', 'Донецьк', '12/15/1991');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АЕ', 01067, '07/19/1981', 'Україна, Дніпропетровськ',
'Ч', 'Дніпропетровськ', '08/25/1997');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АЖ', 01568, '09/14/1956', 'Казахстан, місто Павлодар',
'Ч', 'Київ', '05/24/1999');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АЗ', 43188, '11/13/1970', 'Дніпропетровська область, м. Дніпродзержинськ',
'Ж', 'Дніпропетровська область, м. Дніпродзержинськ', '05/15/1998');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АК', 23490, '01/05/1961', 'Росія, місто Самара',
'Ж', 'Дніпропетровськ', '09/13/2000');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АС', 90843, '10/10/1949', 'Молдова, місто Кишинів',
'Ж', 'Дніпропетровськ', '12/13/1998');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АЯ', 90764, '11/14/1950', 'Україна, місто Миколаїв',
'Ж', 'м. Миколаїв', '11/11/1998');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'ИК', 10842, '07/19/1949', 'Україна, м. Кіровоград',
'Ч', 'Дніпропетровськ', '01/06/1998');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'ИК', 45190, '07/18/1983', 'Дніпропетровська область, село Петропавлівка',
'Ж', 'Дніпропетровська область, село Петропавлівка', '09/20/1999');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АН', 61327, '10/1/1960', 'Росія, Санкт-Пітербург',
'Ж', 'Санкт-Пітербург', '10/12/1976');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АН', 64277, '12/23/1972', 'Україна, м. Львів',
'Ч', 'Львів', '01/06/1988');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АК', 89125, '05/07/1980', 'Україна, м. Київ',
'Ч', 'Київ', '01/10/1998');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АК', 55706, '04/07/1965', 'Донецьк',
'Ж', 'Донецьк', '04/20/1982');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АС', 73271, '07/05/1950', 'Крим',
'Ч', 'Сімферополь', '08/23/1970');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АЖ', 45879, '02/04/1961', 'Дніпропетровськ',
'Ж', 'Дніпродзержинськ', '03/14/1980');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АС', 12548, '04/08/1974', 'Трускавець',
'Ж', 'Прикарпаття', '05/28/1989');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АК', 12578, '11/11/1987', 'Донецьк, Краматорськ',
'Ж', 'Киев', '01/26/2000');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АС', 55489, '09/25/1981', 'Суми',
'Ж', 'Харків', '11/06/1999');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АЯ', 45789, '08/07/1972', 'Угорщина',
'Ж', 'Івано-Франківськ', '10/03/1988');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АЖ', 35126, '03/18/1975', 'Одеса',
'Ж', 'Одеса', '06/19/1993');
INSERT INTO PasportData
(Code, Series, Number, Birthday, BirthPlace,
Sex, IssuePlace, IssueDate)
VALUES
(GEN_ID(PasportDataCode, 1), 'АН', 15625, '06/19/1966', 'Дніпропетровськ',
'Ч', 'Дніпропетровськ, Петриківка', '08/12/1982');
/* Додаємо 12 рядків до таблиці Readers. */
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Іванов', 'Петро', 'Іванович', 317,
4, 'НГУ, каф. ЕОТ', 'Асистент');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Федорец', 'Ірина', 'Олегівна', 28,
1, 'НГУ, АХЧ', 'Вахтер');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Ільїн', 'Іван', 'Петрович', 1345,
11, 'НГУ, каф. фізики', 'Доцент');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Суренко', 'Дмитро', 'Павлович', 543,
6, 'НГУ, каф. геофізики', 'Ст. викладач');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Коршунова', 'Наталя', 'Юріївна', 128,
8, 'НГУ, каф. геоіформатики', 'Асистент');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Носенко', 'Олег', 'Володимирович', 5672,
5, 'НГУ, ІКК', 'Інженер');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Брусов', 'Володимир', 'Михайлович', 485,
24, 'НГУ, каф. геодезії', 'Лаборант');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Козирєв', 'Олексій', 'Сергійович', 759,
15, 'НГУ, каф. кримінології', 'Професор');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Левченко', 'Юлія', 'Павлівна', 146,
18, 'НГУ, каф. політичної теорії', 'Завідувач кафедри');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Світла', 'Тетяна', 'Іванівна', 2021,
22, 'НГУ, каф. перекладу', 'Ст. викладач');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Щиглів', 'Петро', 'Євгенович', 997,
14, 'НГУ, каф. електропостачання', 'Асистент');
INSERT INTO Readers
(Code, FamilyName, Name, Patronymic, ReaderCardNumber,
PasportCode, Job, Post)
VALUES
(GEN_ID(ReadersCode, 1), 'Кириленко', 'Віктор', 'Олександрович', 1010,
17, 'НГУ, каф. електроприводу', 'Заступник декана');
/* Додаємо 12 рядків до таблиці Librarians. */
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 28, 'Іванова', 'Олена', 'Володимирівна',
2, 'Бібліотекар', '52-XX-75');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 12, 'Ніколаєнко', 'Любов', 'Миколаївна',
10, 'Бібліотекар', '46-XX-19');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 187, 'Іноземцева', 'Іванна', 'Модестівна',
9, 'Ст. бібліотекар', '775-XX-00');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 83, 'Мальцева', 'Діана', 'Петрівна',
12, 'Бібліотекар', '29-XX-15');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 10, 'Сизранцева', 'Тетяна', 'Ігорівна',
3, 'Бібліотекар', '370-XX-22');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 100, 'Ставка', 'Лілія', 'Іванівна',
7, 'Бібліотекар', '22-XX-01');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 50, 'Лещенко', 'Алла', 'Федорівна',
13, 'Бібліотекар', '722-XX-36');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 36, 'Сіра', 'Лідія', 'Іванівна',
19, 'Бібліотекар', '254-XX-02');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 45, 'Прохіна', 'Тамара', 'Львівна',
21, 'Бібліотекар', '63-XX-01');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 78, 'Самойленко', 'Вікторія', 'Ігорівна',
20, 'Бібліотекар', '125-XX-80');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 69, 'Степанова', 'Олександра', 'Миколаївна',
16, 'Ст. бібліотекар', '445-XX-65');
INSERT INTO Librarians
(Code, ClockNumber, FamilyName, Name, Patronymic,
PasportCode, Post, HomePhone)
VALUES
(GEN_ID(LibrariansCode, 1), 17, 'Петрова', 'Аліна', 'Сергіївна',
23, 'Бібліотекар', '999-XX-05');
/* Додаємо 2 рядки до таблиці BookFunds. */
INSERT INTO BookFunds
(Code, Name)
VALUES
(GEN_ID(BookFundsCode, 1), 'НТБ');
INSERT INTO BookFunds
(Code, Name)
VALUES
(GEN_ID(BookFundsCode, 1), 'Студентський');
/* Додаємо 16 рядківв до таблиці BookAuthors. */
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Тіхонов', 'Олег', 'Миколайович', '07/12/1945');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Акуленко', 'Леонід', 'Дмитрович', '11/26/1962');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Процуто', 'Віктор', 'Сергійович', '08/14/1950');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Колосов', 'Геннадій', 'Євгенович', '06/01/1950');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Козаков', 'Ігор', 'Єлисейович', '09/18/1962');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Павловська', 'Тетяна', 'Олександрівна', '08/03/1967');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Зайцев', 'Валентин', 'Федорович', '07/03/1955');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Полянин', 'Андрій', 'Дмитрович', '03/15/1939');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Андронов', 'Олександр', 'Михайлович', '06/18/1969');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Копитов', 'Євген', 'Олександрович', '03/09/1950');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Гринглаз', 'Леонід', 'Якович', '07/11/1950');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Баврін', 'Іван', 'Іванович', '09/12/1949');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Пугачов', 'Володимир', 'Семенович', '02/03/1958');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Оліфер', 'Віктор', 'Григорович', '04/07/1961');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Оліфер', 'Наталя', 'Олексіївна', '12/11/1965');
INSERT INTO BookAuthors
(Code, FamilyName, Name, Patronymic, Birthday)
VALUES
(GEN_ID(BookAuthorsCode, 1), 'Флегонтов', 'Олександр', 'Володимирович', '07/07/1963');
/* Додаємо 4 рядки до таблиці PhoneTypes. */
INSERT INTO PhoneTypes
(Code, Name)
VALUES
(GEN_ID(PhoneTypesCode, 1), 'Домашній');
INSERT INTO PhoneTypes
(Code, Name)
VALUES
(GEN_ID(PhoneTypesCode, 1), 'Робочий');
INSERT INTO PhoneTypes
(Code, Name)
VALUES
(GEN_ID(PhoneTypesCode, 1), 'Мобільний');
INSERT INTO PhoneTypes
(Code, Name)
VALUES
(GEN_ID(PhoneTypesCode, 1), 'Супутниковий');
/* Додаємо 14 рядків до таблиці Books. */
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Автоматизація виробничих процесів на збагачувальній фабриці',
'01/01/1985', 6000, '«Надра»', '622.7', '622.7-52/Т');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Розв''язання завдань по автоматизації процесів збагачення й металургії',
'01/01/1969', 2000, '«Наука»', '622.7-52', '622.7-52(075)/Т');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Асимптотичні методи оптимального керування',
'01/01/1987', 1000, '«Автомат»', '681.513.5', '681.513.5:/А');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Синтез оптимальних автоматичних систем',
'01/31/1984', 5000, '«Автомат»', '681.513.5', '681.513.5:/ДО');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Методи оптимізації стохастичних систем',
'01/01/1987', 4500, '«Матстат»', '681.513.5', '681.513.5:/ДО');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Автоматизовані системи керування технологічним процесом збагачення руди',
'01/31/1987', 4000, '«Автомат»', '622.7-52', '622.7-52/П');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'C/C++ Програмування мовою високого рівня',
'01/11/2007', 5500, '«Пітер»', '681.3.06', '681.3.06(075)');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Комп''ютерні мережі. Принципи, технології, протоколи',
'01/31/2006', 6000, '«Пітер»', '004.72', '004.72(075)');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Довідник по диференціальних рівняннях з приватними похідними першого порядку',
'01/31/2003', 10000, '«ФИЗМАТЛІТ»', '517.9', '517.9');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Теорія ймовірностей й математична статистика',
'01/31/2004', 1000, '«Пітер»', '519.2', '519.2');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'C#. Програмування мовою високого рівня',
'01/31/2009', 1500, '«Пітер»', '004.43', '004.43');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Теорія імовірностей й математична статистика',
'01/31/2005', 2000, '«Вища школа»', '519.2', '519.2');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Теорія імовірностей й математична статистика',
'01/31/2002', 2500, '«ФИЗМАТЛІТ»', '519.2', '519.2');
INSERT INTO Books
(Code,
Name,
IssueYear, Drawing, BookPublishers, UDK, Cipher)
VALUES
(GEN_ID(BooksCode, 1),
'Дискретно-групові методи інтегрування звичайних диференціальних рівнянь',
'01/31/1991', 7000, '«ЛІІАН»', '517.9', '517.9-37');
/* Додаємо 19 рядків до таблиці CoAuthorship. */
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(1, 1);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(2, 1);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(3, 2);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(4, 4);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(5, 5);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(6, 3);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(7, 6);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(8, 14);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(8, 15);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(9, 7);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(9, 8);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(10, 9);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(10, 10);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(10, 11);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(11, 6);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(12, 12);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(13, 13);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(14, 16);
INSERT INTO CoAuthorship
(BookCode, AuthorCode)
VALUES
(14, 7);
/* Додаємо 25 рядків до таблиці Phones. */
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(1, 1, '29-XX-15');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(1, 2, '98-XX-88');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(1, 3, '38053198XX87');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(2, 2, '47-XX-10');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(3, 1, '68-XX-09');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(4, 1, '370-XX-20');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(4, 3, '38097567XX54');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(5, 1, '744-XX-00');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(6, 1, '33-XX-35');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(6, 3, '38096231XX83');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(8, 1, '68-XX-58');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(8, 2, '47-XX-45');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(8, 3, '38063257XX88');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(9, 1, '144-XX-48');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(9, 2, '32-XX-02');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(9, 3, '38097555XX22');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(10, 1, '56-XX-01');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(10, 2, '89-XX-98');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(10, 3, '38053456XX52');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(11, 1, '789-XX-97');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(11, 2, '47-XX-96');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(11, 3, '38054022XX84');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(12, 1, '777-XX-45');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(12, 2, '41-XX-39');
INSERT INTO Phones
(ReaderCode, PhoneTypesCode, PhoneNumber)
VALUES
(12, 3, '38067454XX21');
/* Додаємо 15 рядків до таблиці BookInventoryNumbers. */
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 1, 1, 4567890, 15.56);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 2, 1, 4510000, 22.33);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 3, 1, 4532477, 34.01);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 4, 1, 4512890, 12.99);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 5, 2, 4678532, 56.78);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 6, 2, 4632112, 10.10);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 7, 2, 7569832, 73.50);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 7, 2, 5478956, 45.10);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 8, 2, 2145876, 59.25);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 9, 1, 5214786, 36.05);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 10, 1, 5268933, 74.20);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 11, 2, 7865890, 21.32);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 12, 1, 6589321, 36.69);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 13, 1, 7812639, 48.13);
INSERT INTO BookInventoryNumbers
(Code, BookCode, FundCode, InventoryNumber, Cost)
VALUES
(GEN_ID(BookInventoryNumbersCode, 1), 14, 1, 7523690, 27.99);
/* Додаємо 10 рядків до таблиці BookGiveOutRecord. */
INSERT INTO BookGiveOutRecord
(Code, ReaderCode, OutLibrarianCode, InventoryCode, IssueDate,
ReturnDate, FactReturnDate, InLibrarianCode)
VALUES
(GEN_ID(BookGiveOutRecordCode, 1), 2, 4, 6, '09/11/2004',
'09/25/2004', '09/24/2004', 3);
INSERT INTO BookGiveOutRecord
(Code, ReaderCode, OutLibrarianCode, InventoryCode, IssueDate,
ReturnDate, FactReturnDate, InLibrarianCode)
VALUES
(GEN_ID(BookGiveOutRecordCode, 1), 3, 4, 4, '09/02/2004',
'09/16/2004', '12/11/2004', 3);
INSERT INTO BookGiveOutRecord
(Code, ReaderCode, OutLibrarianCode, InventoryCode, IssueDate,
ReturnDate, FactReturnDate, InLibrarianCode)
VALUES
(GEN_ID(BookGiveOutRecordCode, 1), 6, 4, 3, '09/02/2004',
'09/16/2004', '09/16/2004', 1);
INSERT INTO BookGiveOutRecord
(Code, ReaderCode, OutLibrarianCode, InventoryCode, IssueDate,
ReturnDate, FactReturnDate, InLibrarianCode)
VALUES
(GEN_ID(BookGiveOutRecordCode, 1), 4, 3, 6, '10/30/2004',
'11/13/2004', '01/10/2005', 6);
INSERT INTO BookGiveOutRecord
(Code, ReaderCode, OutLibrarianCode, InventoryCode, IssueDate,
ReturnDate, FactReturnDate, InLibrarianCode)
VALUES
(GEN_ID(BookGiveOutRecordCode, 1), 7, 10, 7, '11/10/2009',
'11/24/2009', '11/24/2009', 12);
INSERT INTO BookGiveOutRecord
(Code, ReaderCode, OutLibrarianCode, InventoryCode, IssueDate,
ReturnDate, FactReturnDate, InLibrarianCode)
VALUES
(GEN_ID(BookGiveOutRecordCode, 1), 9, 7, 12, '12/15/2009',
'12/29/2009', NULL, NULL);
INSERT INTO BookGiveOutRecord
(Code, ReaderCode, OutLibrarianCode, InventoryCode, IssueDate,
ReturnDate, FactReturnDate, InLibrarianCode)
VALUES
(GEN_ID(BookGiveOutRecordCode, 1), 11, 8, 10, '02/06/2009',
'02/20/2009', '02/19/2009', 7);
INSERT INTO BookGiveOutRecord
(Code, ReaderCode, OutLibrarianCode, InventoryCode, IssueDate,
ReturnDate, FactReturnDate, InLibrarianCode)
VALUES
(GEN_ID(BookGiveOutRecordCode, 1), 7, 9, 8, '03/07/2009',
'03/21/2009', '04/10/2009', 10);
INSERT INTO BookGiveOutRecord
(Code, ReaderCode, OutLibrarianCode, InventoryCode, IssueDate,
ReturnDate, FactReturnDate, InLibrarianCode)
VALUES
(GEN_ID(BookGiveOutRecordCode, 1), 9, 8, 12, '02/05/2010',
'02/28/2010', NULL, NULL);
INSERT INTO BookGiveOutRecord
(Code, ReaderCode, OutLibrarianCode, InventoryCode, IssueDate,
ReturnDate, FactReturnDate, InLibrarianCode)
VALUES
(GEN_ID(BookGiveOutRecordCode, 1), 12, 10, 15, '09/21/2010',
'10/05/2010', '10/03/2010', 9);
/* Оператор COMMIT закриває транзакцію. Усі зміни, які були внесені до БД «БІБЛІОТЕКА», фіксуються. */
1. Структура script-файлу має суттєві розбіжності із послідовністю викладу фізичної моделі БД «БІБЛІОТЕКА». Це пов’язано зі зручністю роботи з секціями коду, у яких SQL-оператори визначають однотипні об'єкти: домени, таблиці, представлення даних тощо.
2. Створення індексів таблиць не відображено у фізичній моделі БД «БІБЛІОТЕКА». Вони потрібні для скорочення часу вибірки даних за допомогою SQL-запитів.
3. Script-файл – це транзакція, яку необхідно завершити оператором COMMIT для фіксації змін у БД «БІБЛІОТЕКА».
© Куваєв Я.Г., 2005—2023.
Всі права захищені.
Вся інформація, яка розміщена на цьому веб-сайті, призначена тільки для персонального використання і не підлягає подальшому відтворенню і/або поширенню в будь-якій формі, інакше як за письмовим дозволом Автора.