简单说说MYSQL的触发器(例子包括了存储过程)

MYSQL的触发器 语法:

CREATE  TRIGGER <触发器名称>   
(1)                     
{ BEFORE | AFTER } 
(2)
{ INSERT | UPDATE | DELETE } 
(3)
ON <表名称> 
(4)
FOR EACH ROW 
(5)
<触发器SQL语句>
(6)

 解析:
   (1)名称:触发器必须有名字,最多64个字符,可能后面会附有分隔符. 它和MySQL中其他对象的命名方式基本相象.
(2 )时间:触发器有执行的时间设置:可以设置为事件发生前或后。
(3)事件:同样也能设定触发的事件:它们可以在执行insert、update或delete的过程中触发。
(4)作用表:触发器是属于某一个表的: 当在这个表上执行插入、更新或删除操作的时候就导致触发器的激活. 我们 不能给同一张表的同一个事件安排两个触发器。
(5)触发间隔:触发器的执行间隔:FOR EACH ROW 子句通知触发器每隔一行执行一次动作,而不是对整个表 执行一次。
(6)SQL语句:触发器包含所要触发的SQL语句:这里的语句可以是任何合法的语句,包括复合语句,但是这里的语句受的限制和函数的一样。在这个地方,写的语句有点类似于存储过程语句(但注意:触发器就是触发器,而存储过程还是存 储过程),当然与存储过程一样,以下语句是合法的。
  复合语句 (BEGIN / END) 是合法的. 
流控制(Flow-of-control)语句 (IF, CASE, WHILE, LOOP, WHILE, REPEAT, LEAVE, 
ITERATE) 也是合法的. 
变量声明 (DECLARE) 以及指派(SET) 是合法的. 
允许条件声明. 
异常处理声明也是允许的.

相关例子
  例一问题描述:
我们来看一个相对复杂的例子(这里只是为了说明触发器,因此例子中的表字段可能创建的不太合理),在这个例子中我们将会使用到两个表。

表一 user表(有一个'total_payment'字段,用于记录用户总的消费金额)



表二 user_detail表(
有一个‘payment'字段,用于记录用户每笔的消费金额



看了这两个表后,想必大家都明白了。对,我们的要求就是“当user_detail表中的payment字段更新时,user表的total_payment能够相应的更新。
解决方法:
对于上述问题,我们有多种解决方法。1 使用外键(需要InnoDB) 2 使用应用程序 3 使用触发器等。当然,这里我们讨论的是触发器,就采用MYSQL触发器方法来解决。
具体代码如下:
DELIMITER //
CREATE TRIGGER `auto_update`
AFTER UPDATE ON `user_detail` FOR EACH ROW 
BEGIN
Declare var_payment int(10) default 0;
Declare total_payment int(10) default 0;
Declare stop_flag tinyint(1) default 0;
Declare curl CURSOR FOR SELECT  `payment`  FROM  `user_detail` where `user_id` = old.user_id;
Declare  CONTINUE HANDLER FOR NOT FOUND SET stop_flag = 1;
OPEN curl;
REPEAT
fetch curl into var_payment;
IF (stop_flag = 0)  then
SET total_payment = total_payment + var_payment;
end     IF;
UNTIL stop_flag = 1
END REPEAT;
CLOSE curl;
UPDATE `user` SET  `total_payment` = total_payment where `id` = old.user_id;
end //
DELIMITER ;


运行代码后,其结果上面两张图已经呈现了。对于,上述"BEGIN"以后的代码不太明白的可查看此处说明《MYSQL存储过程语句简单解释》或者GOOGLE相关文档资料。

对于“
where `id` = old.user_id; ”语句中的“old”是什么意思?再看一个简单的例子后,稍作解释。

例二问题描述:我们还是使用这两个表,现问题变成了“ 当我们删除user表中的数据时,user_detail表中的相关数据也应自动被删除。 ”比如,我们把user.id = 1的数据删除后,user_detail表中所有user_id =1的数据也都被删除了。
解决方法:
   由于有前面一个例子,所以直接上代码:
DELIMITER //
create  Trigger `auto_delete` before  delete on `user` for each row
BEGIN
delete from `user_detail` where `user_id` = old.id;
END //
DELIMITER ;


其结果,可自行运行一下看。OK,这里再次出现了"old"这个词,那么到底是什么意思呐?手册上如此说:

“在触发器的SQL语句中,你可以关联表中的任意列。但你不能仅仅使用列的名称去标识,那会使 系统混淆,因为那里可能会有列的新名(这可能正是你要修改的,你的动作可能正是要修改列名), 还有列的旧名存在。因此你必须用这样的语法来标识: "NEW . column_name" 或者 "OLD . column_name". 这样在技术上处理(NEW | OLD . column_name) 新和旧的列名属于创建了过渡变量("transition variables")。
对于INSERT语句, 只有NEW是合法的;对于DELETE语句,只有OLD才合法;而UPDATE语句可以在 和NEW以及OLD同时使用。下面是一个UPDATE中同时使用NEW和OLD的例子。”;

恩,对于这段话,我个人理解是(NEW | OLD) 起到的是一种指定“表与条件”的作用。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值