注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

@fc_lamp

关注Web应用解决方案MySql/PHP/Python一盏名为"飞川"的灯~

 
 
 

日志

 
 

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

2010-10-19 11:51:00|  分类: Web技术-Mysql |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
简单说说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'字段,用于记录用户总的消费金额)

简单说说MYSQL的触发器(例子包括了存储过程) - fc-lamp - fc-lamp的博客

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

简单说说MYSQL的触发器(例子包括了存储过程) - fc-lamp - fc-lamp的博客

看了这两个表后,想必大家都明白了。对,我们的要求就是“当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) 起到的是一种指定“表与条件”的作用。


  评论这张
 
阅读(234)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017