1、简介
触发器(trigger)是个特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表或者视图进行操作( insert,delete, update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。
触发器也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。然而,强制引用完整性的最好方法是在相关表中定义主键和外键约束。如果使用数据库关系图,则可以在表之间创建关系以自动创建外键约束。
在触发器中的操作可以是insert、update、delete、execute procedure或execute function操作。
在一个表或视图上,可以有多个insert、update、select或delete的触发器。
2、重要概念
1)触发器名称
标识一个触发器,并在在数据库中必须保持唯一性。
2)触发事件
i) 数据库语句能启动触发器。触发的事件可以是insert、update、delete或select语句;
ii)在update或select事件中,在触发时可加上一个多个字段作为触发条件;
iii)在insert或delete事件中,任何一个在表上的insert或delete操作都可以触发触发器;
iv)触发器创建在本地表或视图中。它不能被创建在远程数据库的表或视图中。
3)触发的动作
i) 触发的动作指的是当触发事件发生时,执行的一些SQL语句;
ii)有三种类型的触发动作:before、after和for each row;
iii)before触发动作在触发器事件发生之前执行;
iv)after触发动作在触发事件发生之后执行;
v)for each row触发动作影响触发事件发生的所有记录之上;
vi)触发动作可以是insert、update、delete、execute procedure或execute function语句。
3、触发器实例
1)delete触发器
CREATE TRIGGER delete_customer
DELETE ON customer -- 触发事件
BEFORE ( EXECUTE PROCEDURE log_customer_proc( ) ); -- 触发动作
上面的实例在customer表中创建了一个名为delete_customer的delete类型的触发器。这个触发器将在customer中的一条或者多条数据做删除操作时被执行。当这个触发器被触发时,在这之前需要执行log_customer_proc存储过程来记录日志。
2)update触发器
CREATE TRIGGER update_unit_price
UPDATE OF unit_price ON stock -- 触发事件 REFERENCING OLD AS pre NEW AS post
FOR EACH ROW WHEN (post.unit_price > pre.unit_price * 2)
( INSERT INTO warn_table VALUES(pre.stock_num, pre.manu_code,
pre.unit_price, post.unit_price, CURRENT) ); -- 触发动作
这个实例在stock表中创建了一个名为update_unit_price的update触发器。这个触发器会在unit_price字段被更新时执行。当这个触发器起作用的时候,触发器的动作将在每一条满足post.unit_price > pre.unit_price*2条件时的记录。
3)select的触发器
CREATE TRIGGER select_customer_num
SELECT OF num ON customer -- 触发事件
REFERENCING OLD AS pre
FOR EACH ROW
(INSERT INTO scn_log VALUES (pre.num, CURRENT, USER) ); -- 触发动作
这个实例在customer表上创建了一个名为select_customer的select触发器。这个触发器将在在num列被查询的时候被执行。对每条被影响的行都进行如下的操作:
INSERT INTO scn_log VALUES (pre.num, CURRENT, USER);
4)insert的触发器
CREATE TRIGGER insert_customer
INSERT ON customer -- 触发事件
REFERENCING NEW AS post
FOR EACH ROW
(INSERT INTO customer_summary VALUES (post.num, post.name)); -- 触发动作
这个实例在customer表中创建了一个名为insert_customer的insert类型的触发器。这个触发器影响在customer表中插入的每一行。在该表记录插入时,触发器附加执行了如下操作:
INSERT INTO customer_summary VALUES (post.num, post.name);
5)触发存储过程
在该实例中展示如何在触发器中调用存储过程,例如如下创建了items_trigger_proc的存储过程:
CREATE PROCEDURE items_trigger_proc()
REFERENCING OLD AS pre NEW AS post FOR items;
if (SELECTING) then
insert into log_records values (1, pre.quantity, -1);
end if
if (INSERTING) then
insert into log_records values (2, -1, post.quantity);
end if
if (DELETING) then
insert into log_records values (3, pre.quantity, -1);
end if
if (UPDATING) then
insert into log_records values (4, pre.quantity, post.quantity);
end if
END PROCEDURE;
接着创建update_quantity的触发器,调用item_trigger_proc存储过程,参考语句如下:
CREATE TRIGGER update_quantity
UPDATE OF quantity ON items
FOR EACH ROW
(EXECUTE PROCEDURE items_trigger_proc()
WITH TRIGGER REFERENCES);
4、触发器的优点
触发器可通过数据库中的相关表实现级联更改;不过,通过级联引用完整性约束可以更有效地执行这些更改。触发器可以强制比用 CHECK 约束定义的约束更为复杂的约束。与 CHECK 约束不同,触发器可以引用其它表中的列。例如,触发器可以使用另一个表中的 SELECT 比较插入或更新的数据,以及执行其它操作,如修改数据或显示用户定义错误信息。触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。一个表中的多个同类触发器(INSERT、UPDATE 或 DELETE)允许采取多个不同的对策以响应同一个修改语句。
posted on 2010-11-05 16:42
阿蜜果 阅读(2495)
评论(0) 编辑 收藏 所属分类:
database