Главное меню

EN | RU | UK

На главную

ПРИЛОЖЕНИЕ Г. Script-файл БД «БИБЛИОТЕКА». СУБД Interbase

Помощь & Консультация
Помощь & Консультация
Пишите мне в
Наверх страницы
Приложение Г
Цель

Цель: получить представление о назначении, структуре и последовательности DDL и DML команд языка SQL на примере создания БД «БИБЛИОТЕКА».

 

Г.1. Script-файл в СУБД Interbase

Script-файл – это сценарий или скрипт, написанный на одном из скриптовых языков программирования и сохраненный в общем формате. Это наиболее общее определение script-файла, которое нам удалось найти. Сузим это определение для нашего случая: script-файл – это последовательность DDL и DML команд языка SQL для создания физической модели БД.

По нашему мнению, методика применения скриптов SQL в Interbase не отличается от других СУБД для создания физической модели БД. В общем случае для СУБД Interbase она включает три последовательных шага:

  1. Создать script-файл, используя текстовый редактор.
  2. Выполнить файл с помощью isql в IBConsole.
  3. Посмотреть результаты выполнения и подтвердить изменения в БД.

Для создания и редактирования script-файла в ОС Windows Вам будет вполне достаточно приложения «Блокнот». MS Word используйте для этого с осторожностью. Дело в том, что у этого приложения имеются скрытые управляющие символы. Они могут быть причиной нетипичного поведения обработчика script-файлов в СУБД Interbase.

Опыт работы показывает, что сценарий создания физической модели реляционной БД в script-файле удобнее всего выполнять пошагово. После каждого SQL-оператора или группы операторов Вы можете видеть результат их работы. Если он Вас устраивает, переносите SQL-операторы в script-файл. Такой подход позволит получить сценарий восстановления начальной структуры БД. В дальнейшем Вы можете дополнять или изменять его. Осталось добавить, что качественная логическая модель БД обеспечивает успех её физического моделирования.

 

Г.2. Создание БД «БИБЛИОТЕКА»

Для создания БД «БИБЛИОТЕКА» воспользуемся script-файлом. Он состоит из 8-ми частей:

  1. Создание доменов.
  2. Создание таблиц.
  3. Создание представлений данных.
  4. Создание генераторов значений первичных ключей.
  5. Определение исключительных ситуаций.
  6. Создание триггеров и хранимых процедур.
  7. Создание индексов таблиц.
  8. Добавление информации в таблицы.

Оператор «COMMIT;» завершает script-файл. Он закрывает транзакцию, которая автоматически была открыта сразу перед началом его выполнения. Он фиксирует все изменения, которые были выполнены в БД «БИБЛИОТЕКА». Все остальные операторы в script-файле имеют подробные комментарии.

Давайте подробно рассмотрим последовательность действий для создания БД «БИБЛИОТЕКА» в СУБД «Interbase».

  1. Ознакомьтесь с условиями использования СУБД Interbase.
  2. Установите СУБД Interbase на Вашем устройстве.
  3. Откройте IBConsole.
  4. В интерфейсе IBConsole выберите в Menu Bar пункт Database.
  5. В Database Menu выберите пункт Create database….
  6. В диалоговом окне «Create Database» укажите место размещения и имя БД. Например, C:\DB\LIBRARY.IB.
  7. Оставьте остальные параметры без изменений и нажмите кнопку «ОК».
  8. В диалоговом окне «Database Connect» введите пароль «masterkey» и нажмите кнопку «Connect».
  9. В интерфейсе IBConsole выберите в Server Tree узел LIBRARY.IB.
  10. В интерфейсе IBConsole выберите в Tool Bar кнопку [Внешний вид кнопки] Interactive SQL.
  11. В Input Aria диалогового окна Interactive SQL скопируйте script-файл из приложения Г.3.
    1. Выделите фразу /* СОЗДАНИЕ ДОМЕНОВ. Она расположена в первой строке приложения Г.3.
    2. С помощью скроллинга найдите оператор COMMIT;. Он расположен в последней строке приложения Г.3.
    3. Удерживая клавишу Shift щёлкните левой кнопкой мыши правее оператора COMMIT;.
    4. Комбинация клавиш Ctrl+C скопирует выделенный фрагмент в буфер обмена.
    5. Перейдите в Input Aria диалогового окна Interactive SQL и нажмите Ctrl+V.
  12. В Menu Bar диалогового окна Interactive SQL выберите пункт Transactions.
  13. В Transactions Menu выберите пункт «Options».
  14. В диалоговом окне Transaction Editor установите Access Mode (поз. 1, рис. 1) Write (поз. 3, рис. 1) и нажмите «ОК».
  15. В Tool Bar диалогового окна Interactive SQL выберите кнопку [Внешний вид кнопки] Execute.

Рис. Г.1. Диалоговое окно Transaction Editor

Рис. Г.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.

Приятного изучения организации реляционных баз данных.

 

Г.3. Script-файл БД «БИБЛИОТЕКА»

/*СОЗДАНИЕ ДОМЕНОВ

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

/* Домен предназначен для определения уникального номера строк для всех таблиц БД «Библиотека» (поле 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.PasportCode!!!';

CREATE EXCEPTION PsprtCdInPasportDataNotFound

    'Значение внешнего ключа Readers.PasportCode отсутствует в 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

/* В переменную помещаем количество паспортов, зарегистрированных в БД «БИБЛИОТЕКА», у ко торых значение первичного ключа совпадает со значением первичного ключа нового пас порта, значение которого получено процеду рой (параметр 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, PassportCode и 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

/* Комментарий смотри в начале тела процедуры 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

/* Комментарий смотри в начале тела процедуры 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

/* Комментарий смотри в начале тела процедуры 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

/* Комментарий смотри в начале тела процедуры 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

/* Комментарий смотри в начале тела процедуры 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

/* Комментарий смотри в начале тела процедуры 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 закрывает транзакцию. Все изменения, которые были внесены в БД «БИБЛИОТЕКА», фиксируются. */

COMMIT;

 

Выводы

1. Структура script-файла имеет существенные расхождения с последовательностью изложения физической модели БД «БИБЛИОТЕКА». Это связано с удобством работы с секциями идентификатора, в которых SQL-операторы определяют однотипные объекты: домены, таблицы, представления данных и т.п.

2. Создание индексов таблиц не отражено в физической модели БД «БИБЛИОТЕКА». Они необходимы для сокращения времени выборки данных с помощью SQL-запросов.

3. Script-файл – это транзакция, которую необходимо завершить оператором COMMIT для фиксации изменений в БД «БИБЛИОТЕКА».

© Куваев Я.Г., 2005—2023.

Все права защищены.

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