本文介绍
触发器是特殊的存储过程
执行增删改语句后的操作监听
应用场景
1.复杂的安全性检查
2.数据确认
3.数据审计功能
4.完成数据的备份和同步
触发器语法
代码举例
CREATE OR REPLACE TRIGGER tr_hyz_dept
AFTER INSERT OR DELETE OR UPDATE ON hyz_dept
DECLARE
BEGIN
IF inserting THEN
dbms_output.put_line('插入成功');
ELSIF updating THEN
dbms_output.put_line('更新成功');
ELSIF deleting THEN
dbms_output.put_line('删除成功');
END IF;
END;
--测试监听器
insert into hyz_dept (DEPTNO, DNAME, LOC)
values (70, '运动员', '浙江');
delete hyz_dept s where s.deptno='70';
commit;
结果:
触发器类型
复杂的安全性检查代码举例
--禁止hyz_dept表在21点前插入数据
CREATE OR REPLACE TRIGGER tr_hyz_dept
AFTER INSERT OR DELETE OR UPDATE ON hyz_dept
DECLARE
BEGIN
IF to_char(SYSDATE, 'hh24') <= 21 THEN
ROLLBACK;
raise_application_error(-20900, '禁止21点前插入数据');
END IF;
END;
INSERT INTO hyz_dept (deptno, dname, loc) VALUES (70, '运动员', '浙江');
输出结果
数据确认代码举例
CREATE OR REPLACE TRIGGER tr_hyz_dept
AFTER UPDATE ON hyz_dept
FOR EACH ROW
DECLARE
BEGIN
IF :new.dname = :old.dname THEN
ROLLBACK;
raise_application_error(-20901, '修改无效,没有发生变化');
END IF;
dbms_output.put_line('原数据:' || :old.dname || ',现数据:' || :new.dname);
END;
--测试
UPDATE hyz_dept s SET s.dname = '会计' WHERE s.deptno = '10';
输出结果
数据审计功能代码举例
CREATE OR REPLACE TRIGGER tr_hyz_emp
AFTER UPDATE ON hyz_emp
FOR EACH ROW
DECLARE
max_hisal NUMBER;
BEGIN
SELECT MAX(s.hisal) INTO max_hisal FROM hyz_salgrade s;
IF :new.sal >= max_hisal THEN
INSERT INTO hyz_salgrade
(grade, losal, hisal)
VALUES
('6', '9999', '99999');
END IF;
dbms_output.put_line('原数据:' || :old.sal || ',现数据:' || :new.sal || ',最大值' ||
max_hisal);
END;
--测试
select * from hyz_emp s where s.empno='4418';
update hyz_emp s set s.sal=10000 where s.empno='4418';
commit;
select * from hyz_salgrade;
输出结果
完成数据的备份和同步代码举例
SQL> grant select any table to erciyuan;
SQL> grant insert any table to erciyuan;
CREATE OR REPLACE TRIGGER tr_hyz_dept
AFTER INSERT OR DELETE OR UPDATE ON hyz_dept
DECLARE
BEGIN
INSERT INTO scott.dept
SELECT s.deptno, s.dname, s.loc
FROM hyz_dept s
WHERE NOT EXISTS
(SELECT o.deptno FROM scott.dept o WHERE s.deptno = o.deptno);
END;
--测试
insert into hyz_dept (DEPTNO, DNAME, LOC)
values (70, '运动员', '浙江');
select * from scott.dept;--查询结果,原scott.dept并没有50,60,70