目录
一、存储过程
1.概述
前面介绍的大多数MySQL语句都是针对一个或多个表使用的单条语句,而存储过程是一组为了完成某个特定功能的SQL语句集,实质就是一段存放在数据库中的代码
存储过程可由声明式的SQL语句(CREATE、UPDATE、SELECT等)和过程式的SQL语句(IF-THEN-ELSE控制结构语句)组成
一个存储过程是一个可编程的函数,同时可看作是在数据库编程中对面向对象方法的模拟,它允许控制数据的访问方式
存储过程的优点:
- 可增强SQL语言的功能和灵活性
- 良好的封装性
- 高性能
- 可减少网络流量
- 存储过程可作为一种安全机制来确保数据库的安全性和数据的完整性
2.创建存储过程
DELIMITER $$:
- $$是用户自定义的结束符,这个符号可以是一些特殊的符号(¥¥、;;、$$等)
- 使用DELIMITER命令时,应避免使用 “ \ '”字符
- 执行上面这条SQL语句后,任何命令、语句或程序的结束标志就换为两个美元符号了,希望换回默认的分号作为结束标志,可如下这样做:
格式:
CREATE PROCEDURE 存储过程名([参数类型 参数名 参数数据类型...])
[存储过程的特征]
BEGIN
存储过程体
END
参数类型:IN | OUT | INOUT
- IN:输入参数,使数据可以传递给一个存储过程
- OUT:输出参数,使存储过程返回一个操作结果
- INOUT:输入/输出参数,即可传递也可返回
参数名:尽量不要与数据表的列名相同
存储过程的特征:
COMMENT 'String' | LANGUAGE SQL | [NOT] DETERMINISTIC |
CONTAINS SQL | NO SQL | READS SQL DATA |
MODIFIES SQL DATA| SQL SECURITY | DEFINER |
INVOKER
COMMENT 'String':对存储过程的一些描述,可用SHOW CREATE PROCEDURE来显示
LANGUAGE SQL:指明编写这个存储过程的语言为SQL语言
[NOT] DETERMINISTIC:
- DETERMINISTIC:表示存储过程对同样的输入参数产生相同的结果
- NOT DETERMINISTIC:表示会产生不确定的结果
- 默认为DETERMINISTIC
CONTAINS SQL:表示存储过程包含读或写数据的语句【默认】
NO SQL:表示存储过程不包含SQL语句
READS SQL DATA:表示存储过程只包含读数据的语句
MODIFIES SQL DATA:表示存储过程只包含写数据的语句
SQL SECURITY:指定存储过程使用创建该存储过程的用户(DEFINER【默认】)的许可来执行,还是使用调用者(INVOKER)的许可来执行
存储过程体:请看第4小节
Example:
- 无参存储过程:
- 有参存储过程
3.查看存储过程
3.1.查看数据库中存在哪些存储过程
格式:
SHOW PROCEDURE STATUS [\G];
Example:
3.2.查看某个存储过程的具体信息,
格式:
SHOW CREATE PROCEDURE 存储过程名 [\G];
Example:
4.存储过程体
4.1.局部变量
格式:
DECLARE 局部变量名 数据类型 [DEFAULT value]
- DEFAULT子句:为局部变量指定一个默认值,若没有指定,则默认值为NULL
局部变量只能在存储过程体的BEGIN...END语句块中声明
局部变量必须在存储过程体的开头处声明
局部变量的作用范围仅限于声明它的BEGIN...END语句块
局部变量不同于用户变量,两者区别:局部变量声明时,其前面没有使用“@”符号,并且它只能在声明它的BEGIN...END语句块中的语句所使用;而用户变量在声明时,会在其名称前面使用“@”符号,已声明的变量存在于整个会话之中
Example:
4.2.SET语句
格式:
SET 局部变量名=值
Example:
4.3.SELECT...INTO语句
- 把选定列的值直接存储到局部变量/存储过程参数
格式:
SELECT 列名... INTO 变量/参数
Example:
4.4.流程控制语句
4.4.1.条件判断语句
- IF-ELSEIF-ELSE语句
格式:
CREATE PROCEDURE 存储过程名()
BEGIN
IF 条件
THEN SQL语句[一条或多条]
[ELSEIF 条件
THEN SQL语句]
[ELSE
SQL语句]
END IF;
END
Example:
- CASE语句(1)
格式:
CREATE PROCEDURE 存储过程名()
BEGIN
CASE 要判断的值或表达式
WHEN 要比较的值 THEN SQL语句;
[WHEN 要比较的值 THEN SQL语句;]
[ELSE SQL语句;]
END CASE;
END
Example:
- CASE语句(2)
格式:
CREATE PROCEDURE 存储过程名()
BEGIN
CASE
WHEN 比较表达式 THEN SQL语句;
[WHEN 比较表达式 THEN SQL语句;]
[ELSE SQL语句;]
END CASE;
END
Example:
4.4.2.循环语句
- WHILE语句
- 先判断后执行,条件为真,继续执行,反之,结束循环
格式:
CREATE PROCEDURE 存储过程名()
BEGIN
[标注:]WHILE 条件语句 DO
SQL语句
END WHILE[标注];
END
Example:
- REPEAT语句
- 先执行后判断,条件为真,结束循环,反之,继续执行
格式:
CREATE PROCEDURE 存储过程名()
BEGIN
[标注:]REPEAT
SQL语句
UNTIL 条件语句
END REPEAT[标注];
END
Example:
- LOOP语句
- LEAVE 标注名:表示离开当前循环(结束循环)
- LOOP语句允许重复执行某个特定语句或语句块
- LOOP语句的标注必须使用相同名字,且成对出现
格式:
CREATE PROCEDURE 存储过程名()
BEGIN
[标注:]LOOP
SQL语句
END LOOP[标注];
END
Example:
- loop_leave为一个标注
4.5.游标
啰嗦一下:
- 在MySQL中,一条SELECT...INTO语句执行后,返回的是带值的一行数据,并且这行数据可以被读取到存储过程中进行处理。然而,使用SELECT语句进行数据检索时,返回的是一组称为结果集的数据行,该结果集可能拥有多行数据,此时就需要游标对一行行数据进行处理
- 游标是一个被SELECT语句检索出来的结果集
注意事项:
- MySQL对游标的支持是从MySQL5.0开始的
- 游标只能用于存储过程或存储函数中,不能单独在查询操作中使用
- 在存储过程或存储函数中可以定义多个游标,但在单个BEGIN...EDN语句块中每一个游标的名字必须是唯一的
- 游标不是一条SELECT语句,而是SELECT语句检索出来的结果集
格式:
CREATE PROCEDURE 存储过程名([参数类型 参数名 参数数据类型])
BEGIN
[局部变量声明]
DECLARE done INT DEFAULT 1;
DECLARE 游标名 CURSOR FOR 查询语句;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=0;
OPEN 游标名;
[参数初始化]
FETCH 游标名 INTO 变量名;
CLOSE 游标名;
END
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=0:
- 用于捕捉系统抛出的NOT FOUND异常,如果捕捉到,则将done设置为0【使用前需先声明并赋值】
- 游标(cursor)必须在声明处理程序之前被声明,并且变量和条件必须在声明游标或处理程序之前被声明。
详解:
- ① 声明游标
-
DECLARE 游标名 CURSOR FOR 查询语句;
- 查询语句:会返回一行或多行的数据,且该查询语句不能有INTO子句
- ② 打开游标
-
OPEN 游标名;
- 实质:将游标连接到SELECT语句返回的结果集中
- ③ 读取数据
-
FETCH 游标名 INTO 变量名...
- FETCH语句:将游标指向的一行数据赋给一些变量,这些变量的数目必须等于声明游标时SELECT语句中选择列的数目
- ④ 关闭游标
-
CLOSE 游标名
Example:
- 问题描述:统计student数据表的行数
相信到这,可能还不太明白游标的作用,以下例子或许能帮助到你更好的理解游标
- 问题描述:输出student数据表每一行的指定列数据
好像出了点问题,不过关系不大,意思表达到位即可
相信你对游标已经有了一定的认识...继续加油
5.调用存储过程
格式:
CALL 存储过程名([参数]);
Example:
6.删除存储过程
格式:
DROP PROCEDURE [IF EXISTS] 存储过程名;
Example:
存储函数见九章!
参考:存储过程之流程控制语句 - GeaoZhang - 博客园 (cnblogs.com)https://www.cnblogs.com/geaozhang/p/6808867.html