概述
目录
触发器
类型
触发器设计原则
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块 |
创建
语法:
CREATE [OR REPLACE] TRIGGER
trigger_name
[ BEFOREI AFTER]
[ INSERTI UPDATE [of column] | DELETE]
ON table name
Trigger_body
例子:
员工信息只有在工作日才能进行修改
CREAT 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...)。
对于语句触发器,触发事件对于触发器执行一次;对于行触发器,触发事件仅当行被修改时触发。
例如:
语句触发器
例子:
create 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;
CREATE TABLE empl_new
AS SELECT *FROM emp
WHERE empno IS
NULL
INSERT INTO empl ( empno, ename, sal)
VALUES (888,'李四',4000)
这样就实现了在两张表同时添加数据了,做成了两张表的同步。一条是insert的一条是触发器添加的。
行触发器
使用关键字for each row
创建语法:
CREATE [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都有。
例子:
CREATE 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内的语句体内需要加冒号(表示外部变量)
例子:
create 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触发器,就可以实现在视图中向表中插入数据。
语法:
CREATE 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
维护
ALTER TRIGGER trigger name DISABLE| ENABLE
例如在提前编好触发器,先禁用掉,等需要的时候上线使用。
删除
DROP TRIGGER trigger_name ;
另外,当表被删除时,表上的所有触发器都被删除。
数据库触发器和存储过程之间的区别
触发器 | 过程 |
用CREATE TRIGGER定 义 | 用CREATE PROCEDURE定义 |
在数据字典USER TRIGGERS中包含源代码 | 在数据字典USER_SOURCE中包含源代码 |
隐式调用 | 显式调用 |
不允许COMMIT,SAVEPOINT和ROLLBACK | 允许COMMIT,SAVEPOINT和ROLLBACK |
最后
以上就是小巧百合为你收集整理的数据库程序设计8 触发器触发器的全部内容,希望文章能够帮你解决数据库程序设计8 触发器触发器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复