目录
触发器
类型
触发器设计原则
DML触发器
创建
触发事件
语句触发器
行触发器
INSTEAD_OF触发器
维护
删除
数据库触发器和存储过程之间的区别
触发器
- 是特殊的PL/SQL块或存储过程
- 是基于表、视图、方案、数据库的
- 是针对特定事件发生时触发的
- 是隐式执行的
能够更为复杂的控制用户的操作,例如:周末不允许进行离职手续等。
自动处理一些值,例如:账目低于多少钱自动发消息。
类型
应用程序触发器
在应用程序内发生特定DML事件时,将隐式触发它
数据库触发器
在表、视图、方案或数据库上发生特定事件时,将隐式触发它
触发器设计原则
设计触发器为了:
- 保证当一个指定的操作被执行时,执行相关的动作
- 集中全局操作
如果触发器的算法很长,将算法创建于存储过程中,再在触发器中调用它们,触发器的大小不能超过32K。过分地使用触发器可能导致复杂的依赖,这在大的应用程序中可能会产生维护困难。
DML触发器
一个触发器语句包含:
触发时间
- 对于表: BEFORE, AFTER
- 对于视图: INSTEAD OF
触发事件: INSERT, UPDATE或DELETE
表名: On table、view
触发器类型: Row或statement (只执行一次)
WHEN子句:限制条件,只能在行级触发器中使用
触发器体: PL/SQL块
部分 | 说明 | 可能值 |
触发器时机 | 当触发器涉及触发事件时的触发时机 | BEFORE、AFTER、INSTEAD OF |
触发事件 | 在表或视图上的哪一-个数据操纵操作引发了触发器触发 | INSERT、UPDATE、DELETE |
触发器类型 | 触发器体被执行多少次 | Sta tement、ROW |
触发器体 | 触发器执行的那些动作 | PL/SQL块 |
创建
语法:
1
2
3
4
5
6
7CREATE [OR REPLACE] TRIGGER trigger_name [ BEFOREI AFTER] [ INSERTI UPDATE [of column] | DELETE] ON table name Trigger_body
例子:
员工信息只有在工作日才能进行修改
1
2
3
4
5
6
7
8
9
10
11
12CREAT OR REPLACE TRIGGER sal_emp BEFORE INSERT ON emp BEGIN IF(to_char(sysdate),'DY') in ('星期六','星期日') then raise_application_error(-20001,'只有工作日才能录入数据'); END IF END; INSERT INTO emp(empno,ename,job,mgr,hiredate,sal) VALUES(1002,'ljs','clerk',7902,sysdate,2000);
触发事件
触发事件可以是表上的INSERT、UPDATE或DELETE语句。
当触发事件是一个UPDATE语句时,可以用一个字段列表来确定那些必需触发触发器自来改变的列。不能为INSERT或DELETE语句指定字段列表,因为它们总是影响整个行(...UPDATE OF sal...)。
对于语句触发器,触发事件对于触发器执行一次;对于行触发器,触发事件仅当行被修改时触发。
例如:
语句触发器
例子:
1
2
3
4
5
6
7
8create or replace trigger trg_empl_ins after insert on empl begin INSERT INTO empl_new (empno, ename,sal) VALUES (999, '张三', 3000) ; end trg_empl_ins;
1
2
3
4
5
6
7CREATE TABLE empl_new AS SELECT *FROM emp WHERE empno IS NULL INSERT INTO empl ( empno, ename, sal) VALUES (888,'李四',4000)
这样就实现了在两张表同时添加数据了,做成了两张表的同步。一条是insert的一条是触发器添加的。
行触发器
使用关键字for each row
创建语法:
1
2
3
4
5
6
7
8
9CREATE [OR REPLACE] TRIGGER trigger_ name [BEFORE | AFTER ] [ INSERT | UPDATE [of column] | DELETE] ON table_name [ REFERENCING OLD as old | NEW as new] FOR EACH ROW [WHEN (condition)] Trigger_body
NEW代表新加的数据,OLD代表老数据。灵活使用,例如删除的时候没有新值,修改时old,new都有。
例子:
1
2
3
4
5
6
7
8
9
10
11CREATE OR REPLACE TRIGGER sal_emp BEFORE UPDATE OF sal ON emp FOR EACH ROW BEGIN IF(:new.sal >:old.sa1) THEN raise_application_error(-20001,薪水太高了); END IF; END; UPDATE emp SET sal=5000;
在BEGIN之前不用加冒号,在BEGIN内的语句体内需要加冒号(表示外部变量)
例子:
1
2
3
4
5
6
7
8create or replace trigger trg_emp1_ins_row after insert on emp1 for each row begin INSERT INTO emp_new(empno, ename,sal) VALUES ( :NEW. empno, :NEW. ename, :NEW.sal); end trg_empl_ins_row;
这样也能做成两张相同的表。
注意:回滚时两张表的数据均会回滚掉。COMMIT命令不能出现在触发器中。
INSTEAD_OF触发器
视图上是不能插入数据的,但是如果创建一个instead_of触发器,就可以实现在视图中向表中插入数据。
语法:
1
2
3
4
5
6
7
8CREATE OR REPLACE TRIGGER trigger_name INSTEAD OF [INSERT | UPDATE [OF column] | DELETE] ON view_ ame [REFERENCING OLD as old | NEW as new] FOR EACH ROW Trigger_body
维护
1
2ALTER TRIGGER trigger name DISABLE| ENABLE
例如在提前编好触发器,先禁用掉,等需要的时候上线使用。
删除
1
2DROP TRIGGER trigger_name ;
另外,当表被删除时,表上的所有触发器都被删除。
数据库触发器和存储过程之间的区别
触发器 | 过程 |
用CREATE TRIGGER定 义 | 用CREATE PROCEDURE定义 |
在数据字典USER TRIGGERS中包含源代码 | 在数据字典USER_SOURCE中包含源代码 |
隐式调用 | 显式调用 |
不允许COMMIT,SAVEPOINT和ROLLBACK | 允许COMMIT,SAVEPOINT和ROLLBACK |
最后
以上就是小巧百合最近收集整理的关于数据库程序设计8 触发器触发器的全部内容,更多相关数据库程序设计8内容请搜索靠谱客的其他文章。
发表评论 取消回复