设为首页 收藏本站
查看: 627|回复: 0

[经验分享] 复习mysql触发器和存储过程的基本语法

[复制链接]

尚未签到

发表于 2016-10-17 08:24:59 | 显示全部楼层 |阅读模式
  很久不整天操作这些,有点遗忘了,复习并备忘一下 mysql 触发器,存储过程; 内容转自其他网站,版权归原作者所有。
  
  
  A 触发器
  
1. 语法:命名规则
CREATE TRIGGER <触发器名称> <--
{ BEFORE | AFTER }
{ INSERT | UPDATE | DELETE }
ON <表名称>
FOR EACH ROW
<触发器SQL语句>

触发器必须有名字,最多64个字符,可能后面会附有分隔符.它和MySQL中其他对象的命名方式基本相象.
这里我有个习惯:就是用表的名字+'_'+触发器类型的缩写.因此如果是表t26,触发器是在事件UPDATE(参考下面的点(2)和(3))之前(BEFORE)的,那么它的名字就是t26_bu。
2. 语法:触发时间
CREATE TRIGGER <触发器名称>
{ BEFORE | AFTER } <--
{ INSERT | UPDATE | DELETE }
ON <表名称>
FOR EACH ROW
<触发的SQL语句>
触发器有执行的时间设置:可以设置为事件发生前或后。
3. 语法:事件
CREATE TRIGGER <触发器名称>
{ BEFORE | AFTER }
{ INSERT | UPDATE | DELETE } <--
ON <表名称>
FOR EACH ROW
<触发的SQL语句>
同样也能设定触发的事件:它们可以在执行insert、update或delete的过程中触发。
4. 语法:表
CREATE TRIGGER <触发器名称>
{ BEFORE | AFTER }
{ INSERT | UPDATE | DELETE }
ON <表名称> <--
FOR EACH ROW
<触发的SQL语句>
触发器是属于某一个表的:当在这个表上执行插入、
更新或删除操作的时候就导致触发器的激活.
我们不能给同一张表的同一个事件安排两个触发器。
5. 语法:( 步长)触发间隔
CREATE TRIGGER <触发器名称>
{ BEFORE | AFTER }
{ INSERT | UPDATE | DELETE }
ON <表名称>
FOR EACH ROW <--
<触发的SQL语句>
触发器的执行间隔:FOR EACH ROW子句通知触发器
每隔一行执行一次动作,而不是对整个表执行一次。
6. 语法:语句
CREATE TRIGGER <触发器名称>
{ BEFORE | AFTER }
{ INSERT | UPDATE | DELETE }
ON <表名称>
FOR EACH ROW
<触发的SQL语句> <--
触发器包含所要触发的SQL语句:这里的语句可以是任何合法的语句,
包括复合语句,但是这里的语句受的限制和函数的一样。
Privileges权限
你必须拥有相当大的权限才能创建触发器(CREATE TRIGGER)。
如果你已经是Root用户,那么就足够了。这跟SQL的标准有所不同。
因此在下一个版本的MySQL中,
你完全有可能看到有一种叫做CREATE TRIGGER的新权限。
然后通过这样的方法赋予:
GRANT CREATE TRIGGER ON <表名称> TO <用户或用户列表>;
也可以通过这样收回权限:
REVOKE CREATE TRIGGER ON <表名称> FROM <用户或用户列表>;

关于旧的和新创建的列的标识
在触发器的SQL语句中,你可以关联表中的任意列。但你不能仅使用列的名称去标识,那会使系统混淆,因为那里可能会有列的新名(这可能正是你要修改的,你的动作可能正是要修改列名),还有列的旧名存在。因此你必须用这样的语法来标识: "NEW . column_name"或者"OLD . column_name".这样在技术上处理(NEW | OLD . column_name)新和旧的列名属于创建了过渡变量("transition variables")。 
对于INSERT语句,只有NEW是合法的;对于DELETE语句,只有OLD才合法;而UPDATE语句可以在和NEW以及OLD同时使用。下面是一个UPDATE中同时使用NEW和OLD的例子。
CREATE TRIGGER t21_au
BEFORE UPDATE ON t22
FOR EACH ROW
BEGIN
SET @old = OLD . s1;
SET @new = NEW.s1;
END;//
现在如果t21表中的s1列的值是55,那么执行了
"UPDATE t21 SET s1 = s1 + 1"之后@old的值会变成55,
而@new的值将会变成56。
Example of CREATE and INSERT CREATE和INSERT的例子
创建有触发器的表
这里所有的例程中我都假定大家的分隔符已经设置成//(DELIMITER //)。
CREATE TABLE t22 (s1 INTEGER)//
CREATE TRIGGER t22_bi
BEFORE INSERT ON t22
FOR EACH ROW
BEGIN
SET @x = 'Trigger was activated!';
SET NEW.s1 = 55;
END;//

在最开始我创建了一个名字为t22的表,然后在表t22上创建了一个触发器t22_bi,当我们要向表中的行插入时,触发器就会被激活,执行将s1列的值改为55的动作。
使用触发器执行插入动作 
mysql> INSERT INTO t22 VALUES (1)//
让我们看如果向表t2中插入一行数据触发器对应的表会怎么样? 这里的插入的动作是很常见的,我们不需要触发器的权限来执行它。甚至不需要知道是否有触发器关联。
mysql> SELECT @x, t22.* FROM t22//
+------------------------+------+
| @x | s1 |
+------------------------+------+
| Trigger was activated! | 55 |
+------------------------+------+
1 row in set (0.00 sec)

大家可以看到INSERT动作之后的结果,和我们预期的一样,x标记被改动了,同时这里插入的数据不是我们开始输入的插入数据,而是触发器自己的数据。
"check"完整性约束例子
什么是"check"约束
在标准的SQL语言中,我们可以在(CREATE TABLE)创建表的过程中使用"CHECK (condition)",
例如:
CREATE TABLE t25
(s1 INT, s2 CHAR(5), PRIMARY KEY (s1),
CHECK (LEFT(s2,1)='A'))
ENGINE=INNODB;

这里CHECK的意思是"当s2列的最左边的字符不是'A'时,insert和update语句都会非法",MySQL的视图不支持CHECK,我个人是很希望它能支持的。但如果你很需要在表中使用这样的功能,我建议大家使用触发器来实现。
CREATE TABLE t25
(s1 INT, s2 CHAR(5),
PRIMARY KEY (s1))
ENGINE=INNODB//
CREATE TRIGGER t25_bi
BEFORE INSERT ON t25
FOR EACH ROW
IF LEFT(NEW.s2,1)<>'A' THEN SET NEW.s1=0; END IF;//
CREATE TRIGGER t25_bu
BEFORE UPDATE ON t25
FOR EACH ROW
IF LEFT(NEW.s2,1)<>'A' THEN SET NEW.s1=0; END IF;//

我只需要使用BEFORE INSERT和BEFORE UPDATE语句就行了,删除了触发器不会对表有影响,同时AFTER的触发器也不能修改NEW的过程变量(transition variables)。为了激活触发器,我执行了向表中的行插入s1=0的数据,之后只要执行符合LEFT(s2,1) <> 'A'条件的动作都会失败:
INSERT INTO t25 VALUES (0,'a') /* priming the pump */ //
INSERT INTO t25 VALUES (5,'b') /* gets error '23000' */ //
Don't Believe The Old MySQL Manual

  
  
  
  B 存储过程
  
  
  
一.创建存储过程

1.基本语法:
 

create procedure sp_name()
begin
………
end

2.参数传递



二.调用存储过程

1.基本语法:call sp_name()
注意:存储过程名称后面必须加括号,哪怕该存储过程没有参数传递

三.删除存储过程

1.基本语法:
drop procedure sp_name//
2.注意事项
(1)不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程

四.区块,条件,循环


1.区块定义,常用
begin
……
end;
也可以给区块起别名,如:
lable:begin
………..
end lable;
可以用leave lable;跳出区块,执行区块以后的代码
2.条件语句
 

DSC0000.gif if 条件 then
statement
else
statement
end if;




3.循环语句
(1).while循环

[label:] WHILE expression DO

statements

END WHILE [label] ;





 



(2).loop循环
 

[label:] LOOP

statements

END LOOP [label];




 



(3).repeat until循环
 

[label:] REPEAT

statements

UNTIL expression

END REPEAT [label] ;




 



五.其他常用命令

1.show procedure status
显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过程名称,创建时间等
2.show create procedure sp_name
显示某一个存储过程的详细信息

 



 

mysql存储过程中要用到的运算符




  
  #结束!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-287186-1-1.html 上篇帖子: 【转】如何用MYSQL随机查询几条数据? 下篇帖子: 关于大型网站MYSQL数据库上层缓存的讨论
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表