数据库存储过程及触发器
存储过程和触发器
一.关键语法
- DELIMITER 声明语句结束符
- CREATE PROCEDURE 声明存储过程
- BEGIN … END 储存过程开始和结束符号
- SET 变量赋值
- DECLARE 变量定义
- DEFINER 存储过程的权限
二.入门实例
1 | DELIMITER $$ |
三.存储过程使用
1 | CALL test(); 调用存储过程 |
四.参数
- IN 输入参数,表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
- OUT 输出参数,该值可在存储过程内部被改变,并可返回
- INOUT 输入输出参数,调用时指定,并且可被改变和返回
1.IN参数实例
1 | set @ip=1; |
外影响内,内并不影响外的值
2.OUT参数实例
1 | set @ip=1; |
存储过程内的会影响外部的变量,但是外部的不会影响存储过程内的变量
3.INOUT参数实例
1 | set @ip=1; |
内外都能影响
五.变量
1.变量定义
1 | 局部变量声明一定要放在存储过程体的开始 |
2.变量赋值
1 | set ip = value; |
3.用户变量
1 | SELECT 'Hello World' into @x; |
注意:
- 用户变量名一般以@开头
- 滥用用户变量会导致程序难以理解及管理
六.注释
1 | DELIMITER $$ |
七.存储过程的增删改查
1.创建
1 | CREATE DEFINER=`root`@`localhost` PROCEDURE 存储过程名; |
2.删除
1 | DROP PROCEDURE 存储过程名; |
3.修改
1 | ALTER PROCEDURE 存储过程名 |
4.查看
1 | SELECT NAME FROM mysql.proc WHERE db='数据库名'; |
八.存储过程的控制语句
1.变量的作用域
1 | DELIMITER // |
只在自已的定义域中有效,出了定义域无效,可以通过out参数或者将其值指派给会话变量来保存其值。
2.if -then -else语句
1 | DELIMITER // |
3.case语句
1 | DELIMITER // |
4.while 条件 DO … end while;语句
1 | DELIMITER // |
在执行循环体之前进行判断
5.repeat …until 条件 end repeat;语句
1 | DELIMITER // |
在执行循环体之后进行判断
6.loop … leave end loop;语句
1 | DELIMITER // |
leave语句的意义是离开循环,LOOP_LABEL是自定义的标号
7.LABLES 标号:
在使用loop的时候,使用到的labels标号,对于labels可以用到while,loop,rrepeat等循环控制语句中。
1 | create procedure pro13() |
8.ITERATE迭代
ITERATE只能出现在LOOP,REPEAT和WHILE语句中,它的意思是“再次循环”,类似于continue
1 | DELIMITER // |
首先i的值为0,条件判断语句if i=3 then判断为假,跳过if语段,向数据库中插入0,然后i+1,同样后面的if i>=5 then判断也为假,也跳过;继续循环,同样插入1和2;在i=3的时候条件判断语句if i=3 then判断为真,执行i=i+1,i值为4,然后执行迭代iterate loop_label;,即语句执行到iterate loop_label;后直接跳到if i=3 then判断语句,执行判断,这个时候由于i=4,if i=3 then判断为假,跳过IF语段,将4添加到表中,i变为5,条件判断if i>=5 then判断为真,执行leave loop_label;跳出loop循环,然后执行end;//,结束整个存储过程。
九.存储过程中的基本函数
1.字符串类
1 | CHARSET(str) //返回字串字符集 |
2.数学类
1 | ABS (number2 ) //绝对值 |
3.日期时间类
1 | ADDTIME (date2 ,time_interval)//将time_interval加到date2 |
十.分页存储过程
1 | DELIMITER // |
十一.存储过程的优点
1 | 1.存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。 |
补充:触发器
1.语法
1 | CREATE TRIGGER 触发器名 |
2.触发事件
- MySQL除了对INSERT、UPDATE、DELETE基本操作进行定义外,还定义了LOAD DATA和REPLACE语句,这两种语句也能引起上述6中类型的触发器的触发。
- LOAD DATA语句用于将一个文件装入到一个数据表中,相当与一系列的 INSERT 操作。
- REPLACE语句一般来说和 INSERT 语句很像,只是在表中有primary key **或unique索引时,如果插入的数据和原来primary key或unique**索引一致时,会先删除原来的数据,然后增加一条新数据,也就是说,一条 REPLACE 语句有时候等价于一条。
- INSERT语句,有时候等价于一条DELETE语句加上一条INSERT语句。
- INSERT型触发器:插入某一行时激活触发器,可能通过INSERT、LOAD DATA、REPLACE语句触发;
- UPDATE型触发器:更改某一行时激活触发器,可能通过UPDATE语句触发;
- DELETE型触发器:删除某一行时激活触发器,可能通过DELETE、REPLACE语句触发。
3.触发器程序体
statement_list代表一个或多个语句的列表,列表内的每条语句都必须用分号(;)来结尾。
1 | BEGIN |
4.触发器实例
1 | DELIMITER $ |
5.NEW和OLD详解
MySQL中定义了NEW和OLD,用来表示触发器的所在表中,触发了触发器的那一行数据。
- 在INSERT型触发器中,NEW用来表示将要(BEFORE)或已经(AFTER)插入的新数据;
- 在UPDATE型触发器中,OLD用来表示将要或已经被修改的原数据,NEW用来表示将要或已经修改为的新数据;
- 在DELETE型触发器中,OLD用来表示将要或已经被删除的原数据;
使用方法: NEW.columnName(columnName为相应数据表某一列名)
另外,OLD是只读的,而NEW则可以在触发器中使用SET赋值,这样不会再次触发触发器,造成循环调用(如每插入一个学生前,都在其学号前加“2013”)。
6.触发器的查找与删除
1 | -- 查找 |
7.触发器的执行顺序
建立的数据库一般都是InnoDB数据库,其上建立的表是事务性表,也就是事务安全的。这时,若SQL语句或触发器执行失败,MySQL会回滚事务,有:
- 如果BEFORE触发器执行失败,SQL无法正确执行。
- SQL执行失败时,AFTER型触发器不会触发。
- AFTER类型的触发器执行失败,SQL会回滚。