Получение информации о триггерах.
Триггеры хранятся в БД, по-
этому информацию о них можно получить из представления словаря
данных USER_TRIGGERS, например, следующей командой:
SELECT * FROM USER_TRIGGERS;
П р и м е р ы
1.
Создать триггер, который перед вставкой очередной строки в таб-
лицу BOOKS_DELIVERY проверяет наличие указанного кода книги в
таблице BOOKS. При отсутствии указанного кода книги в таблице
BOOKS должно генерироваться исключение с выдачей соответствующе-
го сообщения.
Добавление новых строк в таблицу BOOKS_DELIVERY выполняется
оператором INSERT. Поскольку триггер должен запускаться перед вы-
полнением каждого оператора INSERT, следовательно, он должен быть
строковым BEFORE-триггером. Для сохранения целостности данных не-
обходимо проверить, имеются ли вносимые коды книг и в таблице
BOOKS. Для этого с помощью однострочного оператора SELECT осу-
ществляется выборка информации из таблицы BOOKS, где в условии
выборки используется поле CODE_BOOK псевдозаписи :new. Если ко-
личество строк с данным кодом книги в таблице BOOKS окажется рав-
166
ным нулю, будет сгенерировано исключение и выдано соответствующее
сообщение.
Создание триггера TR1 выполняется вводом следующего оператора:
CREATE OR REPLACE TRIGGER TR1
BEFORE INSERT ON BOOKS_DELIVERY
FOR EACH ROW
DECLARE
QUANTITY NUMBER(4);
BEGIN
SELECT COUNT(*) INTO QUANTITY FROM BOOKS
WHERE CODE_BOOK = :NEW.CODE_BOOK;
IF QUANTITY = 0 THEN RAISE_APPLICATION_ERROR
(–20212,'В таблице BOOKS нет информации о данной книге');
END IF;
END TR1;
При создании триггера с помощью SQL*PLUS, необходимо указы-
вать в строке, следующей за последним оператором, косую черту (/),
чтобы оператор CREATE … TRIGGER выполнился.
Действие триггера TR1 может быть проверено выполнением следую-
щего оператора, осуществляющего вставку строки в таблицу
BOOKS_DELIVERY и тем самым вызывающего активизацию триггера
TR2:
INSERT INTO BOOKS_DELIVERY VALUES
(21, 15, 'Иванов И. И. ',15, '20-01-06');
Поскольку код книги 15 отсутствует в таблице BOOKS, то будет сге-
нерировано исключение и выдано соответствующее сообщение.
2.
Создать триггер, который запрещает вносить в таблицу BOOKS
строки со значением поля PRICE больше, чем 5000 руб., а также осуще-
ствлять увеличение цены книг, информация о которых хранится в табли-
це BOOKS, более чем на 20 %. При нарушении данного требования
должно генерироваться исключение с выдачей соответствующего сооб-
щения.
Так как внесение новых строк в таблицу BOOKS осуществляется в
результате выполнения оператора INSERT, а значение поля PRICE в таб-
лице BOOKS, содержащего цену книги, может быть изменено в резуль-
тате выполнения оператора UPDATE, то в триггере указывается сово-
купность запускающих DML-операторов. Поскольку триггер должен за-
пускаться перед выполнением каждого из указанных DML-операторов,
167
следовательно, он является строковым BEFORE-триггером. Так как дей-
ствия, выполняемые триггером, различны для каждого из запускающих
DML-операторов, модифицирующих таблицу BOOKS, то для распозна-
вания типа DML-оператора используются соответствующие триггерные
предикаты INSERTING и UPDAITING. Вследствие того что при вставке
новых строк проверке должно быть подвергнуто новое значение поля
PRICE, а при модификации значения поля PRICE новое значение должно
сравниваться со старым значением, необходимо использовать псевдоза-
писи :new и :old.
Создание триггера TR2 выполняется вводом следующего оператора:
CREATE OR REPLACE TRIGGER TR2
BEFORE INSERT OR UPDATE OF PRICE ON BOOKS
FOR EACH ROW
BEGIN
IF INSERTING THEN
IF :NEW.PRICE > 5000 THEN
RAISE_APPLICATION_ERROR
(–20102, 'В таблицу BOOKS нельзя вносить записи
с ценой книги > 5000');
END IF;
END IF;
IF UPDATING THEN
IF :NEW.PRICE > :OLD.PRICE*1.2 THEN
RAISE_APPLICATION_ERROR
(–20103, 'В таблице BOOKS нельзя изменять цену книги
более чем на 20 %');
END IF;
END IF;
END TR2;
Действие триггера TR2 может быть проверено выполнением следую-
щих операторов, которые, осуществляя вставку строк в таблицу BOOKS
и обновление строк в таблице BOOKS, тем самым вызывают его активи-
зацию.
Оператор вставки строк в таблицу BOOKS, вызывающий активиза-
цию триггера TR2:
INSERT INTO BOOKS VALUES
( 21, 'Дюна', 'Герберт Ф.', 5268, 'Аст', 'Фантастика');
Оператор обновления строк в таблице BOOKS, вызывающий активи-
зацию триггера TR2:
168
UPDATE BOOKS SET PRICE = 6000;
Поскольку эти операторы нарушают требования, предъявляемые к
значению и модификации цены книг, то во всех случаях будет сгенери-
ровано исключение и выдано соответствующее сообщение.
3.
Создать триггер, который в созданную таблицу STAT, содержащую
столбцы
название издательства – PUBLISH_H,
количество книг в жанре «Роман» – QUANTITY_ROM,
количество книг в жанре «Фантастика» – QUANTITY_FAN,
при каждой модификации таблицы BOOKS формирует и заносит в соот-
ветствующие столбцы таблицы STAT суммарное количество книг по ка-
ждому из издательств в разрезе указанных тематик: «Роман» и «Фанта-
стика».
Модификация таблицы BOOKS осуществляется выполнением сле-
дующих DML-операторов: INSERT, DELETE или оператора UPDATE,
модифицирующего значения столбца GENRE в таблице BOOKS. Так как
действия по формированию информации таблицы STAT выполняются
после выполнения каждого из модифицирующих таблицу BOOKS опера-
торов, то по типу это операторный AFTER-триггер. Поскольку действия,
выполняемые триггером, одинаковы для всех типов активизирующих его
операторов, то триггерные предикаты не используются. Перед созданием
триггера должна быть создана таблица STAT.
Создание таблицы STAT может быть выполнено вводом следующей
совокупности операторов:
DROP TABLE STAT;
CREATE TABLE STAT
(PUBLISH_H VARCHAR2(15),
QUANTITY_ROM NUMBER(7),
QUANTITY_FAN NUMBER(7)
);
Создание триггера TR3 выполняется вводом следующего оператора:
CREATE OR REPLACE TRIGGER TR3
AFTER INSERT OR DELETE OR UPDATE OF GENRE
ON BOOKS
DECLARE
CURSOR V1 IS SELECT PUBLISH_HOUSE,
COUNT(TITLE) QUANTITY1
FROM BOOKS WHERE GENRE = 'Роман'
169
GROUP BY PUBLISH_HOUSE;
CURSOR V2 IS SELECT PUBLISH_HOUSE,
COUNT(TITLE) QUANTITY2
FROM BOOKS WHERE GENRE = 'Фантастика'
GROUP BY PUBLISH_HOUSE;
BEGIN
DELETE FROM STAT;
FOR Z1 IN V1 LOOP
INSERT INTO STAT VALUES(Z1.PUBLISH_HOUSE,
Z1.QUANTITY1, 0);
END LOOP;
FOR Z1 IN V2 LOOP
UPDATE STAT SET QUANTITY_FAN = Z1. QUANTITY2
WHERE PUBLISH_H = Z1.PUBLISH_HOUSE;
IF SQL%NOTFOUND THEN
INSERT INTO STAT VALUES(Z1.PUBLISH_HOUSE, 0,
Z1.QUANTITY2);
END IF;
END LOOP;
END TR3;
Действие триггера может быть проверено выполнением следующих
операторов, которые, осуществляя вставку строк в таблицу BOOKS, уда-
ление строк и обновление строк в таблице BOOKS, тем самым вызывают
активизацию триггера TR3.
Операторы вставки строк в таблицу BOOKS, вызывающие активиза-
цию триггера TR3:
INSERT INTO BOOKS VALUES
(46, 'Еретики Дюны', 'Герберт Ф.', 368, 'Аст', 'Фантастика');
INSERT INTO BOOKS VALUES(42, 'Ингвар и Ольха',
'Никитин Ю.', 168, 'Аст', 'Роман');
Операторы удаления строк из таблицы BOOKS, вызывающие активи-
зацию триггера TR3:
DELETE BOOKS WHERE AUTHOR = 'Герберт Ф.';
DELETE BOOKS WHERE TITLE = 'Казаки';
Оператор модификации строк в таблице BOOKS, вызывающие акти-
визацию триггера TR3:
UPDATE BOOKS SET GENRE='Фантастика' WHERE TITLE =
'Ингвар и Ольха';
170
Просмотр информации в таблице STAT можно выполнить следую-
щим оператором:
SELECT * FROM STAT;
Достарыңызбен бөлісу: |