Что такое триггер в PL / SQL?
TRIGGERS — это хранимые программы, которые запускаются механизмом Oracle автоматически, когда в таблицу выполняются такие операторы DML, как вставка, обновление, удаление или если происходят некоторые события. Код, подлежащий исключению в случае триггера, может быть определен согласно требованию. Вы можете выбрать событие, при котором должен быть запущен триггер, и время выполнения. Целью триггера является поддержание целостности информации в базе данных.
В этом уроке вы узнаете
- Преимущества триггеров
- Типы триггеров в Oracle
- Как создать триггер
- : NEW и: СТАРЫЙ пункт
- ВМЕСТО триггера
- Составной триггер
Преимущества триггеров
Ниже приведены преимущества триггеров.
- Генерация некоторых производных значений столбцов автоматически
- Обеспечение ссылочной целостности
- Регистрация событий и хранение информации о доступе к таблице
- Аудиторская проверка
- Синхронная репликация таблиц
- Внедрение авторизации безопасности
- Предотвращение недействительных транзакций
Типы триггеров в Oracle
Триггеры могут быть классифицированы на основе следующих параметров.
- Классификация на основе сроков
- ПЕРЕД триггером: срабатывает до наступления указанного события.
- ПОСЛЕ триггера: срабатывает после наступления указанного события.
- ВМЕСТО триггера: особый тип. Вы узнаете больше о дальнейших темах. (только для DML)
- Классификация на основе уровня
- Триггер уровня STATEMENT: запускается один раз для указанного оператора события.
- Триггер уровня ROW: срабатывает для каждой записи, которая была затронута в указанном событии. (только для DML)
- Классификация на основе события
- Триггер DML: срабатывает, когда указано событие DML (INSERT / UPDATE / DELETE)
- DDL Trigger: срабатывает, когда указано событие DDL (CREATE / ALTER)
- Триггер базы данных: срабатывает, когда задано событие базы данных (LOGON / LOGOFF / STARTUP / SHUTDOWN)
Таким образом, каждый триггер является комбинацией вышеуказанных параметров.
Как создать триггер
Ниже приведен синтаксис для создания триггера.
CREATE [ OR REPLACE ] TRIGGER <trigger_name> [BEFORE | AFTER | INSTEAD OF ] [INSERT | UPDATE | DELETE......] ON<name of underlying object> [FOR EACH ROW] [WHEN<condition for trigger to get execute> ] DECLARE <Declaration part> BEGIN <Execution part> EXCEPTION <Exception handling part> END;
Синтаксис Объяснение:
- Приведенный выше синтаксис показывает различные дополнительные операторы, которые присутствуют при создании триггера.
- ДО / ПОСЛЕ будет указывать время события.
- INSERT / UPDATE / LOGON / CREATE / и т.д.. будет указывать событие, для которого должен быть запущен триггер.
- Предложение ON будет указывать, на каком объекте действует указанное событие. Например, это будет имя таблицы, в которой может произойти событие DML в случае триггера DML.
- Команда «FOR EACH ROW» будет указывать триггер уровня ROW.
- В предложении WHEN будет указано дополнительное условие, при котором должен срабатывать триггер.
- Часть объявления, часть исполнения, часть обработки исключений такая же, как и в других блоках PL / SQL. Часть объявления и часть обработки исключений являются необязательными.
: NEW и: СТАРЫЙ пункт
В триггере уровня строки триггер срабатывает для каждой связанной строки. И иногда требуется знать значение до и после оператора DML.
Oracle предоставил два условия в триггере уровня RECORD для хранения этих значений. Мы можем использовать эти предложения для ссылки на старые и новые значения внутри тела триггера.
- : NEW — содержит новое значение для столбцов базовой таблицы / представления во время выполнения триггера.
- : OLD — содержит старое значение столбцов базовой таблицы / представления во время выполнения триггера
Это предложение следует использовать на основе события DML. Ниже в таблице будет указано, какое предложение действительно для какого оператора DML (INSERT / UPDATE / DELETE).
ВСТАВИТЬ | ОБНОВИТЬ | УДАЛЯТЬ | |
: NEW | ДЕЙСТВУЕТ | ДЕЙСТВУЕТ | НЕДЕЙСТВИТЕЛЬНЫМ. Нет нового значения в случае удаления. |
: OLD | НЕДЕЙСТВИТЕЛЬНЫМ. В случае вставки нет старого значения | ДЕЙСТВУЕТ | ДЕЙСТВУЕТ |
ВМЕСТО триггера
«INSTEAD OF trigger» — это специальный тип триггера. Он используется только в триггерах DML. Он используется, когда любое событие DML происходит в сложном представлении.
Рассмотрим пример, в котором представление составлено из 3 базовых таблиц. Когда какое-либо событие DML генерируется над этим представлением, оно становится недействительным, поскольку данные взяты из 3 разных таблиц. Так что в этом используется триггер INSTEAD OF. Триггер INSTEAD OF используется для непосредственного изменения базовых таблиц вместо изменения представления для данного события.
Пример 1 : В этом примере мы собираемся создать сложное представление из двух базовых таблиц.
- Таблица_1 является таблицей emp и
- Таблица_2 — таблица отдела.
Затем мы увидим, как триггер INSTEAD OF используется для выполнения UPDATE оператора детализации местоположения в этом сложном представлении. Мы также увидим, как: NEW и: OLD полезны в триггерах.
- Шаг 1: Создание таблицы emp и dept с соответствующими столбцами
- Шаг 2: заполнение таблицы примерами значений
- Шаг 3: Создание представления для созданной выше таблицы
- Шаг 4: Обновление представления перед триггером вместо
- Шаг 5: Создание триггера вместо
- Шаг 6: Обновление представления после триггера вместо
Шаг 1) Создание таблицы emp и dept с соответствующими столбцами
CREATE TABLE emp( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager VARCHAR2(50), dept_no NUMBER); / CREATE TABLE dept( Dept_no NUMBER, Dept_name VARCHAR2(50), LOCATION VARCHAR2(50)); /
Код Объяснение
- Строка кода 1-7 : создание таблицы emp.
- Строка кода 8-12 : создание таблицы dept.
Вывод
Таблица создана
Шаг 2) Теперь, когда мы создали таблицу, мы заполним эту таблицу примерами значений и созданием представлений для вышеуказанных таблиц.
BEGIN INSERT INTO DEPT VALUES(10,‘HR’,‘USA’); INSERT INTO DEPT VALUES(20,'SALES','UK’); INSERT INTO DEPT VALUES(30,‘FINANCIAL',‘JAPAN'); COMMIT; END; / BEGIN INSERT INTO EMP VALUES(1000,'XXX5,15000,'AAA',30); INSERT INTO EMP VALUES(1001,‘YYY5,18000,‘AAA’,20) ; INSERT INTO EMP VALUES(1002,‘ZZZ5,20000,‘AAA',10); COMMIT; END; /
Код Объяснение
- Строка кода 13-19 : вставка данных в таблицу «dept».
- Строка кода 20-26: вставка данных в таблицу emp.
Вывод
Процедура PL / SQL завершена
Шаг 3) Создание представления для созданной выше таблицы.
CREATE VIEW guru99_emp_view( Employee_name:dept_name,location) AS SELECT emp.emp_name,dept.dept_name,dept.location FROM emp,dept WHERE emp.dept_no=dept.dept_no; /
SELECT * FROM guru99_emp_view;
Код Объяснение
- Строка кода 27-32: создание представления «guru99_emp_view».
- Строка кода 33: запрос guru99_emp_view.
Вывод
Просмотр создан
ИМЯ СОТРУДНИКА | DEPT_NAME | РАСПОЛОЖЕНИЕ |
ZZZ | HR | Соединенные Штаты Америки |
YYY | ПРОДАЖИ | Великобритания |
XXX | ФИНАНСОВЫЙ | ЯПОНИЯ |
Шаг 4) Обновление представления перед триггером.
BEGIN UPDATE guru99_emp_view SET location='FRANCE' WHERE employee_name=:'XXX’; COMMIT; END; /
Код Объяснение
- Строка кода 34-38: измените местоположение «XXX» на «FRANCE». Возникло исключение, поскольку операторы DML не допускаются в сложном представлении.
Вывод
ORA-01779: невозможно изменить столбец, который сопоставляется с таблицей без сохранения ключа
ORA-06512: в строке 2
Шаг 5) Чтобы избежать ошибки при обновлении представления на предыдущем шаге, на этом шаге мы будем использовать «вместо триггера».
CREATE TRIGGER guru99_view_modify_trg INSTEAD OF UPDATE ON guru99_emp_view FOR EACH ROW BEGIN UPDATE dept SET location=:new.location WHERE dept_name=:old.dept_name; END; /
Код Объяснение
- Строка кода 39: создание триггера INSTEAD OF для события «UPDATE» в представлении «guru99_emp_view» на уровне ROW. Он содержит оператор update для обновления местоположения в базовой таблице «dept».
- Строка кода 44: оператор Update использует «: NEW» и «: OLD», чтобы найти значение столбцов до и после обновления.
Вывод
Триггер создан
Шаг 6) Обновление вида после вместо триггера. Теперь ошибка не возникнет, так как «вместо триггера» будет обрабатывать операцию обновления этого сложного представления. А после выполнения кода местоположение сотрудника XXX будет обновлено до «Франция» из «Японии».
BEGIN UPDATE guru99_emp_view SET location='FRANCE' WHERE employee_name='XXX'; COMMIT; END; /
SELECT * FROM guru99_emp_view;
Объяснение кода:
- Кодовая строка 49-53: Обновление местоположения «XXX» до «FRANCE». Это успешно, потому что триггер «INSTEAD OF» остановил фактический оператор обновления в представлении и выполнил обновление базовой таблицы.
- Строка кода 55: проверка обновленной записи.
Вывод:
Процедура PL / SQL успешно завершена
ИМЯ СОТРУДНИКА | DEPT_NAME | РАСПОЛОЖЕНИЕ |
ZZZ | HR | Соединенные Штаты Америки |
YYY | ПРОДАЖИ | Великобритания |
XXX | ФИНАНСОВЫЙ | ФРАНЦИЯ |
Составной триггер
Составной триггер — это триггер, который позволяет вам определять действия для каждой из четырех временных точек в одном теле триггера. Четыре различных момента времени, которые он поддерживает, как показано ниже.
- ДО ЗАЯВЛЕНИЯ — уровень
- ДО РЯДА — уровень
- ПОСЛЕ ROW — уровень
- ПОСЛЕ ЗАЯВЛЕНИЯ — уровень
Он предоставляет возможность объединять действия для разных временных интервалов в один и тот же триггер.
CREATE [ OR REPLACE ] TRIGGER <trigger_name> FOR [INSERT | UPDATE | DELET.......] ON <name of underlying object> <Declarative part> BEFORE STATEMENT IS BEGIN <Execution part>; END BEFORE STATEMENT; BEFORE EACH ROW IS BEGIN <Execution part>; END EACH ROW; AFTER EACH ROW IS BEGIN <Execution part>; END AFTER EACH ROW; AFTER STATEMENT IS BEGIN <Execution part>; END AFTER STATEMENT; END;
Синтаксис Объяснение:
- Приведенный выше синтаксис показывает создание триггера «СОЕДИНЕНИЕ».
- Декларативный раздел является общим для всего блока выполнения в теле триггера.
- Эти 4 блока синхронизации могут быть в любой последовательности. Не обязательно иметь все эти 4 блока синхронизации. Мы можем создать триггер СОЕДИНЕНИЯ только для того времени, которое требуется.
Пример 1 : В этом примере мы собираемся создать триггер для автоматического заполнения столбца зарплаты значением по умолчанию 5000.
CREATE TRIGGER emp_trig FOR INSERT ON emp COMPOUND TRIGGER BEFORE EACH ROW IS BEGIN :new.salary:=5000; END BEFORE EACH ROW; END emp_trig; /
BEGIN INSERT INTO EMP VALUES(1004,‘CCC’,15000,‘AAA’,30); COMMIT; END; /
SELECT * FROM emp WHERE emp_no=1004;
Объяснение кода:
- Строка кода 2-10 : создание составного триггера. Он создан для синхронизации до уровня ROW-ROW для заполнения зарплаты значением по умолчанию 5000. Это изменит зарплату на значение по умолчанию ‘5000’ перед вставкой записи в таблицу.
- Строка кода 11-14 : вставьте запись в таблицу emp.
- Строка кода 16 : проверка вставленной записи.
Вывод:
Триггер создан
Процедура PL / SQL успешно завершена.
EMP_NAME | EMP_NO | ЗАРПЛАТА | УПРАВЛЯЮЩИЙ ДЕЛАМИ | DEPT_NO |
CCC | 1004 | 5000 | AAA | 30 |
Включение и отключение триггеров
Триггеры могут быть включены или отключены. Чтобы включить или отключить триггер, необходимо указать инструкцию ALTER (DDL) для триггера, который отключает или включает его.
Ниже приведен синтаксис для включения / отключения триггеров.
ALTER TRIGGER <trigger_name> [ENABLE|DISABLE]; ALTER TABLE <table_name> [ENABLE|DISABLE] ALL TRIGGERS;
Синтаксис Объяснение:
- Первый синтаксис показывает, как включить / отключить один триггер.
- Второй оператор показывает, как включить / отключить все триггеры в определенной таблице.
Резюме
В этой главе мы узнали о триггерах PL / SQL и их преимуществах. Мы также изучили различные классификации и обсудили триггер INSTEAD OF и триггер COMPOUND.