- •Лекция 14 Хранимый код. Триггеры
- •14.1. Процедурные расширения языка sql
- •Операторы языка pl/sql
- •1. Оператор присваивания
- •2. Условный оператор
- •3. Операторы цикла
- •14.2. Использование команд sql в процедурном расширении. Курсоры
- •14.3 Хранимые процедуры и функции
- •Преимущества и недостатки хранимого кода
- •Создание хранимых процедур и функций
- •Примеры хранимых процедур и функций
- •14.4. Триггеры
- •Особенности триггеров
- •Команды sql для работы с триггерами
- •Примеры триггеров
- •1. Триггер на вставку нового студента
- •2. Триггеры на удаление студента
- •3. Триггер на изменение оценки
Примеры триггеров
1. Триггер на вставку нового студента
При вставке новой строки в таблицу триггеры часто используются для задания таких значений по умолчанию, которые нельзя определить при создании таблицы. В Oracle триггер на вставку чаще всего используется для автоматического задания значений первичного ключа. В стандарте SQL для этих целей имеется специальное ключевое слово IDENTITY, но в Oracle оно не поддерживается.
Вместо этого имеется специальный объект SEQUENCE, который предназначен для формирования последовательных целых чисел. Для обращения к значениям последовательности в выражении SQL используются псевдостолбцы currval и nextval. Currval возвращает текущее значение. NextVal инкрементирует текущее значение и возвращает результат, при этом он становится текущим значением. Триггер на вставку берет из последовательности очередное значение и помещает его в новую строку, используя предопределенную переменную :new.
Например, создадим последовательность для формирования кодов студентов:
CREATE SEQUENCE stud_seq
Теперь создадим триггер на вставку новой строки в таблицу students:
create trigger st_keys
before insert on students
for each row
begin
select stud_seq.nextval into :new.cod_st from dual;
end;
Аналогичный триггер можно написать и на таблицу subjects, поскольку при добавлении нового предмета его код должен формироваться также автоматически.
2. Триггеры на удаление студента
Триггер на удаление должен предусмотреть перенос удаляемых данных в архивную базу данных. При создании таблиц нашей базы данных вместе с удалением студента было предусмотрено и каскадное удаление оценок студента, поэтому мы можем написать аналогичные триггеры BEFORE DELETE на таблицы students и marks, используя возможность каскадирования триггеров. При удалении студента одна единственная команда удаления, полученная сервером, например:
DELETE FROM students WHERE cod_st=125
вызовет выполнение двух команд удаления (из таблиц marks и students) вместе с двумя триггерами, сохраняющими удаляемые данные в архиве.
Предположим, что уже созданы таблицы archive_students и archive_marks. Создадим триггер на удаление из таблицы students:
create trigger st_del
before DELetE on students
for each row
begin
INSERT INTO archive_students
VALUES(:OLD.cod_st, :OLD.name_st, :OLD.born, :OLD.phone);
end;
Триггер на удаление из таблицы оценок выглядит аналогично, фраза
for each row
вызовет его срабатывание при удалении каждой оценки студента.
3. Триггер на изменение оценки
Изменения, вносимые в данные, являющиеся важными в своей предметной обасти, обычно фиксируются в журналах изменений. В базах данных такие журналы могут представлять собой обычные таблицы и формироваться при помощи триггеров. Триггеры, предназначенные для контроля изменений в важных таблицах, могут быть написаны и на вставку, и на удаление, и на обновление.
В нашей демонстрационной базе данных, очевидно, имеет смысл контролировать изменение уже выставленной оценки. Поэтому создадим специальную таблицу change_mark_log (журнал изменений оценок), которая будет содержать столбы:
name_user (имя пользователя, изменившего оценку)
date_change (дата изменения оценки)
cod_st (код студента)
cod_sub (код предмета)
old_mark (старая оценка)
new_mark (новая оценка)
Теперь создадим триггер на обновление:
create trigger mark_change
AFTER UPDATE on marks (mark)
for each row
begin
IF :OLD.mark<> :NEW.mark THEN
INSERT INTO change_mark_log
VALUES(user, sysdate, :OLD.cod_st, :OLD.cod_sub, :OLD.mark, :NEW.mark);
END IF;
end;
Для проверки работоспособности триггера нужно выполнить команду, активизирующую триггер. Например, для последнего триггера:
UPDATE marks SET mark=3 WHERE mark=2
Если в таблице оценок были неудовлетворительные оценки, таблица change_mark_log будет содержать исчерпывающие сведения об их изменении.