MySQL ------ 触发器(TRIGGER)(二十七)
MySQL 语句在需要时被执行,存储过程也是,但是你要是想要某条(或某些语句)在事件发生时自动执行,该怎么办触发器由此而来
触发器:某个表发生更改时自动处理。触发器是MySQL响应delete,insert,update(增加,删除,修改)时,自动执行的一条MySQL语句,或位于begin和end语句之间的一组语句,
ALTER:触发器将在(delete,insert,update) 语句成功后执行,
BEFORE:触发器将在(delete,insert,update) 语句前执行。
版本:于MySQL5 中增加,适用于MySQL5或之后的版本
如以下情景: 1、每当增加一个顾客到某个数据库表时,都检查其电话号码格式是否正确,州的缩写是否为大写 2、每当订购一个产品时,都从库存数量中减去订购数量 3、无论何时删除一行,都在某个存档表中保留一个副本
创建触发器的主要步骤、
1、唯一的触发器名
2、触发器关联的表
3、触发器应该响应的活动(delete,insert,update)
4、触发器何时执行(处理之前或之后)
注意:在mysql 5中触发器名必须在每个表中唯一,但不是在每个数据库中唯一,虽然允许在同一个库中的两个表,有相同名字的触发器,但是最好在数据库范围内使用唯一的触发器名。
-- create trigger 触发器名 create trigger tri_vendors after insert on vendors for each row select ‘add a vendor‘;
11
CREATE TRIGGER 用来创建名为 tri_vendors 的新触发器。触发器可在一个操作发生前或之后执行,这里给出了ALTER INSERT,所以此触发器将在INSERT 语句成功后执行。这个触发器还指定FOR EACH ROW,因此代码对每个插入行执行,文本 add a vendor 将对每个插入的行显示一次。
为了测试这个触发器,使用insert 语句添加一行或多行到 vendors中,当成功插入后显示add a vendor
只有表才支持触发器,视图不支持(临时表也不支持)
触发器按每个表每个事件每次的定义,每个表每个事件每次只允许一个触发器。因此每个表最多支持6个触发器(每条insert,update,delete之前和之后)
单一触发器不能与多个事件或多个表关联,所以如果你需要对一个insert 和update 操作执行的触发器,则应该定义两个触发器。
如果BEFORE 触发器失败,则MySQL将不执行请求的操作。此外如果before 触发器或语句本身失败,MySQL将不执行AFTER 触发器
删除触发器(DROP TRIGGER)
drop trigger 触发器名字
触发器不能更新或覆盖,为了修改一个触发器,必须删除它,然后再重新创建
使用触发器
ONE、INSERT 触发器
insert 触发器在insert 语句之前或之后执行。
1、在insert 触发器代码内,可引用一个名为 NEW 的虚拟表,访问被插入的行
2、在before insert 触发器,new中的值也可以被更新(允许更改被插入的值)
3、对于auto_increment 列,new 在insert 执行之前含0,在inset 执行之后包含新的自动生成值。
create trigger tri_neworder after insert on orders for each row select new.order_num;
111
创建一个名为tri_neworders的触发器,他按照after insert on orders 执行。在插入一个新订单到orders 表时,MySQL生成一个新的订单号并保存到order_num 中,触发器从 NEW.order_num 取得这个值并返回他,此触发器必须按照after insert 执行,因为在before insert 语句执行之前,新order_num 还没有生成,对于orders 的每次插入使用这个触发器将总是返回新的订单号。
将defore 用于数据验证和净化(目的是保证插入表中的数据确实是需要的数据),
TWO、DELETE 触发器
delete 触发器在delete 语句执行之前或之后执行
在delete 触发器代码内,你可以引用一个名为old 的虚拟表,访问被删除的行
old 中的值全部都是只读的,不能更新
mysql> create trigger trideleteorder before delete on archive_orders for each row -> begin -> insert into test_orders(order_num,order_date,cust_id) -> values(old.order_num,old.order_date,old.cust_id); -> end $$
在任意订单删除前将执行此触发器。它使用一条insert语句将old 中的值(即要删除的订单),保存到一个名为 test_orders 的表中
注意: test_orders 和 archive_orders这两个表的列和列的数据类型要一致
使用before delete 触发器相对于after delete 触发器的优点为:
如果(before delete 触发器)由于某种原因订单不能存档,delete 本身将被放弃
上述,触发器(trigger) 使用begin 和end 语句标记触发器体,的好处是触发器能容纳多条sql 语句。
Three、UPDATE 触发器
update 触发器在update 语句执行之前或之后执行
1、在update 触发器代码中,你可以引用一个名为old的虚拟表访问以前(update 语句前) 的值,引用一个名为new 的虚拟表访问新更新的值
2、在before update 触发器中,new 中的值可能被更新(允许更改将要用于update 语句中的值)
3、old 中的值全都是只读的,不能更新。
mysql> create trigger updatevendor before update on vendors for each row -> set new.vend_state = upper(new.vend_state)
任何数据净化都需要在update语句之前进行,就想这个例子中一样,每次更新一个行时,new.vend_state中的值(将用来更新表行的值)都用upper(new.vend_state)替换。
end!!!
1、与其他DBMS 相比,MySQL 5 中支持的触发器相当初级,未来的MySQL版本中有一些改进和增强触发器支持的计划。
2、创建触发器可能需要特殊的安全访问权限,但是触发器的执行时是自动的。如果insert、update和 delete语句能够执行,则相关的触发器也能执行
3、应该用触发器来保证数据的一致性(大小写、格式等),在触发器中执行这种类型的处理的优点是他总是进行这种处理,而且是透明地进行,与客户机应用无关。
4、触发器的一种非常有意义的使用是创建审计跟踪。使用触发器,把更改(如果需要,甚至还有之前和之后的状态)记录到另一个表非常容易。
5、遗憾的是,MySQL触发器中不支持call 语句,这表示不能从触发器内调用存储过程,所需的存储过程代码需要复制到触发器内。