End;
Обращение к псевдозаписям :old и :new должно производиться через имена полей и применимо только к строковым триггерам.
Условие WHERE
С его помощью можно заставить триггер работать по условию! Само условие WHERE в триггере применимо к типу строчных триггеров.
Пример:
Предварительно создадим таблицу, которая будет фиксировать записи, в которых не ввели название книги.
CREATE TABLE ADMIN_BOOKS.Audit_Trigger2(date_oper date, user_name char(20), code_book number(5));
Commit;
Теперь создадим триггер:
CREATE OR REPLACE TRIGGER ADMIN_BOOKS.Trigger2
BEFORE INSERT OR UPDATE OF Title_Book ON ADMIN_BOOKS.Books FOR EACH ROW WHEN (TRIM(new.Title_Book) = '')
DECLARE
BEGIN
INSERT INTO ADMIN_BOOKS.Audit_Trigger2 (date_oper,user_name,code_book) VALUES(sysdate, user, :new.code_book);
END Trigger2;
Обратите внимание на наличие строки OF Title_Book ON ADMIN_BOOKS.Books – это определяется поле, на которое устанавливаем условие триггера.
Предикаты
В триггерах БД Oracle возможно применение логических операторов - предикатов. Они имеют следующие определения: INSERTING, UPDATING, DELETING. Это внутренние переменные среды Oracle, ко- торые в зависимости от воздействующего на таблицу оператора DML при- нимают одно из значений: TRUE или FALSE.
Пример:
Предварительно создадим таблицу, которая будет фиксировать виды выполненных операций.
CREATE TABLE ADMIN_BOOKS.Audit_Trigger3(date_oper date, user_name char(20), oper varchar2(10));
75
Теперь создадим триггер:
CREATE OR REPLACE TRIGGER ADMIN_BOOKS.Trigger3 AFTER INSERT OR UPDATE OR DELETE ON ADMIN_BOOKS.Publishing_house FOR EACH ROW
DECLARE
TIP VARCHAR2(10); BEGIN
IF INSERTING THEN TIP := 'INSERT';
ELSIF UPDATING THEN TIP := 'UPDATE';
ELSIF DELETING THEN TIP := 'DELETE';
END IF;
INSERT INTO ADMIN_BOOKS.Audit_Trigger3(date_oper, user_name, oper) VALUES (SYSDATE, USER, TIP);
END Trigger3;
Системные триггеры
В БД существует два основных вида событий, на которые активизиру- ются системные триггеры, а именно на события DDL или самой БД. К со- бытиям DDL относятся операторы CREATE, DROP, ALTER, к событиям базы данных – запуск останов сервера, регистрация отключения пользова- теля БД, ошибка сервера. Основные примеры событий и их обработки да- ны в табл. 6.1. Описание атрибутивных функций, которые могут быть ис- пользованы в триггерах дано в табл. 6.2.
Синтаксис создания системного триггера:
CREATE OR REPLACE TRIGGER [схема.]имя_триггера
{BEFORE | AFTER}
{список_событий_DDL | список_событий_базы_данных} ON {DATABASE | [схема.]SCHEMA} конструкция_REFERENCING
[условие_WHEN]
тело триггера;
Системные триггеры могут создаваться на уровне схемы (SCHEMA) или уровне БД (DATABASE).
CREATE OR REPLACE TRIGGER Trigger4 AFTER LOGON ON
DATABASE
76
BEGIN
INSERT INTO SYSTEM.AUDTBASE(NZAP, POLZ, TMIN, OPER)
VALUES(1, USER, SYSDATE, 'UserIsLog(off)');
END Trigger4;
CREATE OR REPLACE TRIGGER Trigger5 AFTER LOGON ON SCHEMA
BEGIN
INSERT INTO SYSTEM.AUDTBASE(NZAP, POLZ, TMIN, OPER)
VALUES(1, USER, SYSDATE, 'UserIsLog(off)');
END Trigger5;
|
|
Таблица 6.1 |
|
События и их обработка для БД |
|
|
|
|
Событие |
Разрешенное вре- |
Описание |
|
мя выполнения |
|
STARTUP |
AFTER |
Активизируется после запуска экземпляра |
SHUTDOWN |
BEFORE |
Активизируется при остановке экземпляра. Для |
|
|
заметки: это событие не активизирует триггер, |
|
|
если останов БД аварийный! |
SERVERERROR |
AFTER |
Активизируется при возникновении ошибки |
LOGON |
AFTER |
Активизируется после успешного соединения |
|
|
пользователя с базой данных |
LOGOFF |
BEFORE |
Активизируется в начале отключения пользова- |
|
|
теля |
CREATE |
BEFORE, AFTER |
Активизируется до и после создания объекта |
|
|
схемы |
DROP |
BEFORE, AFTER |
Активизируется до и после удаления объекта |
|
|
схемы |
ALTER |
BEFORE, AFTER |
Активизируется до и после изменения объекта |
|
|
схемы |
Триггеры STARTUP и SHUTDOWN имеют смысл только на уровне БД, хотя их можно создать и в конкретной схеме, но активизироваться они не будут. Кроме того, для системных триггеров существует ряд атрибут- ных функций.
|
|
|
Таблица 6.2 |
|
Описание атрибутных функций |
||
|
|
|
|
Атрибутная |
Тип данных |
Системное со- |
Описание |
функция |
|
бытие |
|
1 |
2 |
3 |
4 |
SYSEVENT |
VARCHAR2 |
Все события |
Возвращает системное собы- |
|
(20) |
|
тие, активизировавшее триг- |
|
|
|
гер |
INSTANCE_NUM |
NUMBER |
Все события |
Возвращает номер текущего |
|
|
|
экземпляра |
77
|
|
|
Окончание табл. 6.2 |
1 |
2 |
3 |
4 |
DATABASE_NAME |
VARCHAR2 |
Все события |
Возвращает имя текущей |
|
(50) |
|
БАЗЫ ДАННЫХ |
SERVER_ERROR |
NUMBER |
SERVERERROR |
Принимает один числовой |
|
|
|
аргумент. Возвращает ошиб- |
|
|
|
ку на той позиции в стеке |
|
|
|
ошибок, которая была указа- |
|
|
|
на аргументом |
IS_SERVERERROR |
BOOLEAN |
SERVERERROR |
Принимает номер ошибки в |
|
|
|
качестве аргумента и воз- |
|
|
|
вращает TRUE, если указан- |
|
|
|
ная ошибка Oracle присутст- |
|
|
|
вует в стеке ошибок |
LOGIN_USER |
VARCHAR2 |
Все события |
Возвращает идентификатор |
|
(20) |
|
пользователя, активизирую- |
|
|
|
щего триггер |
DICTIONARY_OBJ_ |
VARCHAR2 |
CREATE, DROP, |
Возвращает тип объекта |
TYPE |
(30) |
ALTER |
словаря, над которым вы- |
|
|
|
полнялась операция DDL, |
|
|
|
активизировавшая триггер |
DICTIONARY_OBJ_ |
VARCHAR2 |
CREATE, DROP, |
Возвращает имя объекта |
NAME |
(30) |
ALTER |
словаря, над которым вы- |
|
|
|
полнялась операция DDL, |
|
|
|
активизировавшая триггер |
DICTIONARY_OBJ_ |
VARCHAR2 |
CREATE, DROP, |
Возвращает владельца того |
OWNER |
(30) |
ALTER |
объекта словаря, над кото- |
|
|
|
рым выполнялась операция |
|
|
|
DDL, активизировавшая |
|
|
|
триггер |
DES_ENCRYPTED_P |
VARCHAR2 |
CREATE USER, |
Возвращает зашифрованный |
ASSWORD |
(30) |
ALTER USER |
в стандарте DES пароль соз- |
|
|
|
даваемого или изменяемого |
|
|
|
пользователя |
Варианты заданий к лабораторной работе №6
Общие положения
В лабораторной работе в примерах тела триггеров написаны так, что их можно полностью копировать, вставлять в утилиту SQL *Plus Worksheet и запускать (F5) для их создания на сервере. Если создавать триггер в Enterprise MANAGER Console через мастер создания, то первая строка с конструкцией CREATE OR REPLACE TRIGGER имя_триггера не копиру- ется, а само имя_триггера заносится в поле Name.
Создайте примеры триггеров в вашем табличном пространстве. Про- верьте их работу.
78
По вариантам в утилите SQL *Plus Worksheet создайте триггеры, при- чем каждую программу сохранять на диске в отдельном файле с названием
ФамилияСтудента_ЛАб_6_№_варианта_№_задания.
Список заданий
Вариант 1
1.Создать строковый триггер, который будет фиксировать ФИО и код каждого сотрудника в отдельно организованной таблице, у которого изменяли данные его детей.
2.Создать строковый триггер, который будет фиксировать данные о подарках, которые удалили, с именем пользователя в отдельно орга- низованной таблице, который выполнил удаление.
3.Создать операторный триггер, который будет фиксировать операции добавления в любую из трех таблиц с указанием даты и времени опе- рации.
4.Создать системный триггер на уровне БД, который будет фиксиро- вать в отдельно организованной таблице подключения пользователей к Oracle.
Вариант 2
1.Создать строковый триггер, который будет фиксировать список при- боров с указанным старым и новым типом, при изменении типа при- бора в отдельно организованной таблице.
2.Создать строковый триггер, который будет фиксировать количество отремонтированных приборов и общую стоимость ремонтов с указа- нием имени мастера в отдельно организованной таблице у мастера, информация о котором удаляется.
3.Создать операторный триггер, который будет фиксировать операции добавления владельца прибора в таблицу владельцев и наименование прибора, с которым он пришел в отдельно организованной таблице, а также с указанием имени пользователя и даты операции.
4.Создать системный триггер на уровне схемы, который будет фикси- ровать в отдельно организованной таблице информацию о пользова- телях и объектах, структуру которых изменяют.
Вариант 3
Создать строковый триггер, который будет фиксировать старое и новое наименование цветка с типом листа в отдельно организованной таб- лице, если изменяется наименование цветка в таблице или удаляется цветок из таблицы.
Создать строковый триггер, который будет фиксировать коды продаж и даты продаж в отдельно организованной таблице при добавлении за- писи в таблицу продаж.
79