Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаб_раб_11.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
145.92 Кб
Скачать

Иные применения триггеров.

С помощью триггеров можно вести журнал наблюдений за изменением информации в БД. Журнал изменений в БД представляет собой таблицу БД, в которой фиксируются действия над всей базой данных или отдельными ее таблицами. В многопользовательских системах ведение такого журнала позволяет определить источник недостоверных или искаженных данных.

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

Хранимые процедуры.

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

Существует две разновидности хранимых процедур:

  • процедуры выбора;

  • процедуры действия.

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

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

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

Хранимая процедура создается оператором

CREATE PROCEDURE ИмяПроцедуры

[(входной_параметр тип_данных [, входной_параметр тип_данных... ])]

[RETURNS

(выходной_параметр тип_данных [, выходной_параметр тип_данных ...])] AS

<тело процедуры>;

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

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

И входные, и выходные параметры могут быть опущены, если в них нет необходимости.

Тело процедуры имеет формат

[<объявление локальных переменных процедуры>]

BEGIN

< оператор>

[<оператор> ...]

END

Примеры хранимых процедур.

Хранимая процедура FindAuthorName возвращает в выходном параметре InAuthorName имя автора книги, код которого передается во входном параметре InAuthorCode:

CREATE PROCEDURE FindAuthorName

(InAuthorCode INTEGER)

RETURNS(InAuthorName CHAR(30))

AS

BEGIN

SELECT Name

FROM BookAuthors

WHERE Code = :InAuthorCode

INTO InAuthorName;

SUSPEND;

END

Заметим, что в приведенной процедуре за ненадобностью отсутствует определение локальных переменных. С оператором SELECT мы познакомимся позднее.

В логике хранимой процедуры можно проверять правила целостности и генерировать ошибку, если клиент запрашивает выполнение запрещенной операции. Например, ниже показан текст хранимой процедуры, выполняющей добавление новой записи в таблицу Books, которое произойдет только тогда, когда код автора книги будет найден в таблице Books. Если операция недопустима, после генерации соответствующей исключительной ситуации выполнение процедуры прекращается без добавления новой записи.

CREATE EXCEPTION AuthorNotFound "Автор книги не найден.";

CREATE PROCEDURE AddRecordInBooks

/*Процедура выполняет добавление новой записи в таблицу Books,

которое произойдет только тогда, когда код автора книги будет

найден в таблице Books. Если операция недопустима, после генерации

соответствующей исключительной ситуации выполнение процедуры

прекращается без добавления новой записи.*/

(AddAuthorCode INTEGER,

AddName CHAR (200),

AddIssueYear DATE,

AddDrawing INTEGER,

AddUDK CHAR (20),

AddCipher CHAR (30))

AS

DECLARE VARIABLE FindAuthorCode INTEGER;

BEGIN

SELECT COUNT(Code)

FROM BookAuthors

WHERE Code = :AddAuthorCode

INTO :FindAuthorCode;

/*В переменную помещаем результат поиска кода автора в таблице

BookAuthors.*/

IF (FindAuthorCode = 0) THEN

/*В таблице BookAuthors заданного кода автора книги не обнаружено.*/

BEGIN

EXCEPTION AuthorNotFound;

SUSPEND; END

ELSE

/*В таблице BookAuthors обнаружен заданный код автора книги.*/

BEGIN

INSERT INTO Books

(Code, Name, AuthorCode, IssueYear,

Drawing, UDK, Cipher)

VALUES

(GEN_ID(BooksCode, 1),

:AddName,

:AddAuthorCode,

:AddIssueYear,

:AddDrawing,

:AddUDK,

:AddCipher);

SUSPEND;

END

END

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

EXCEPTION ExceptionName;

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

Процедуру AddRecordInBooks вызывают из клиентского приложения. Для проверки правильности работы процедуры средствами утилиты WISQL в командной ее части можно выполнить такую команду:

EXECUTE PROCEDURE AddRecordInBooks(1, 'Методы оптимального

управления', '01/01/2002', 10000, '681.513.5', '681.513.5:/А')

После ее выполнения в таблицу Books будет добавлена новая запись со значениями полей, переданными процедуре AddRecordInBooks в качестве параметров. Если вместо существующего значения кода автора (первый передаваемый параметр) подставить значение, которого нет в таблице BookAuthors, то новая запись в таблицу Books добавлена не будет, и на экран будет выведено сообщение «Statement failed, SQLCODE = -836». Нажав кнопку Details, Вы увидите причину возникновения этого сообщения:

Необходимо отметить, что для того чтобы в таблицу Books не были добавлены записи с кодом автора книги, которого нет в таблице BookAuthors необходимо определить соответствующий триггер, срабатывающий по событию BEFORE INSERT. Он приведен в примере SCRIPT-файла после процедуры AddRecordInBooks.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]