1. 存储过程和函数的概念
- 存储过程和函数是事先经过编译并存储在数据库中的一段 SQL 语句的集合
- 存储过程和函数可以重复使用,减轻开发人员的工作量,类似于java中方法可以多次调用
- 函数必须有返回值,存储过程的返回值可有可无
2. 数据准备
-- 创建db_procedure数据库
CREATE DATABASE db_procedure;
-- 使用数据库
USE db_procedure;
-- 创建学生表
CREATE TABLE student(
id INT PRIMARY KEY AUTO_INCREMENT, -- 学生id
s_name VARCHAR(20), -- 学生姓名
age INT, -- 学生年龄
gender VARCHAR(5), -- 学生性别
score INT -- 学生成绩
);
-- 添加数据
INSERT INTO student VALUES (NULL,'张三',23,'男',95),(NULL,'李四',24,'男',98),
(NULL,'王五',25,'女',100),(NULL,'赵六',26,'女',90);
2. 存储过程的创建、调用、查看、删除
-- 创建stu_group()存储过程,按性别分组查询总成绩,并按照总成绩升序排序的功能
DELIMITER $ -- 修改结束标志为$
CREATE PROCEDURE stu_group()
BEGIN
SELECT gender,SUM(score) getSum FROM student GROUP BY gender ORDER BY getSum ASC;
END$
DELIMITER ;
/*
调用存储过程
CALL 存储过程名称(实际参数);
*/
-- 调用stu_group()存储过程
CALL stu_group();
-- 查看db_procedure数据库中所有的存储过程
SELECT * FROM mysql.proc WHERE db='db_procedure';
-- 删除存储过程
DROP PROCEDURE IF EXISTS stu_group;
3. 存储过程定义变量
-- 创建存储过程pro_test1,定义一个int类型变量,并赋默认值为10
DELIMITER $
CREATE PROCEDURE pro_test1()
BEGIN
DECLARE num INT DEFAULT 10;
SELECT num;
END$
DELIMITER ;
-- 调用存储过程pro_test1
CALL pro_test1();
-- 创建存储过程pro_test2,定义一个varchar类型变量并赋值
DELIMITER $
CREATE PROCEDURE pro_test2()
BEGIN
-- 定义变量
DECLARE decribe VARCHAR(10);
-- 为变量赋值
SET decribe = '存储过程';
-- 使用变量
SELECT decribe;
END$
DELIMITER ;
-- 调用pro_test2存储过程
CALL pro_test2();
-- 创建存储过程pro_test3,定义两个int变量,用于存储男女同学的总分数
DELIMITER $
CREATE PROCEDURE pro_test3()
BEGIN
-- 定义两个变量
DECLARE men,women INT;
-- 查询男同学的总分数,为men赋值
SELECT SUM(score) INTO men FROM student WHERE gender='男';
-- 查询女同学的总分数,为women赋值
SELECT SUM(score) INTO women FROM student WHERE gender='女';
-- 使用变量
SELECT men,women;
END$
DELIMITER ;
-- 调用存储过程pro_test3
CALL pro_test3();
4. 存储过程的if语句
/*
定义一个int变量,用于存储班级总成绩
定义一个varchar变量,用于存储分数描述
根据总成绩判断:
380分及以上 学习优秀
320 ~ 380 学习不错
320以下 学习一般
*/
DELIMITER $
CREATE PROCEDURE pro_test4()
BEGIN
-- 定义变量
DECLARE total INT;
DECLARE info VARCHAR(10);
-- 查询总成绩,为total赋值
SELECT SUM(score) INTO total FROM student;
-- 对总成绩判断
IF total > 380 THEN
SET info = '学习优秀';
ELSEIF total >= 320 AND total <= 380 THEN
SET info = '学习不错';
ELSE
SET info = '学习一般';
END IF;
-- 查询总成绩和描述信息
SELECT total,info;
END$
DELIMITER ;
-- 调用pro_test4存储过程
CALL pro_test4();
5. 存储过程的参数传递
/*
参数传递
CREATE PROCEDURE 存储过程名称([IN|OUT|INOUT] 参数名 数据类型)
BEGIN
SQL 语句列表;
END$
*/
/*
IN:代表输入参数,需要由调用者传递实际数据。默认的
OUT:代表输出参数,该参数可以作为返回值
INOUT:代表既可以作为输入参数,也可以作为输出参数
*/
/*
输入总成绩变量,代表学生总成绩
输出分数描述变量,代表学生总成绩的描述信息
根据总成绩判断:
380分及以上 学习优秀
320 ~ 380 学习不错
320以下 学习一般
*/
DELIMITER $
CREATE PROCEDURE pro_test5(IN total INT,OUT info VARCHAR(10))
BEGIN
-- 对总成绩判断
IF total > 380 THEN
SET info = '学习优秀';
ELSEIF total >= 320 AND total <= 380 THEN
SET info = '学习不错';
ELSE
SET info = '学习一般';
END IF;
END$
DELIMITER ;
-- 调用pro_test5存储过程
CALL pro_test5(300,@info);
CALL pro_test5((SELECT SUM(score) FROM student),@info);
SELECT @info;
/*
@变量名: 这种变量要在变量名称前面加上“@”符号,叫做用户会话变量,代表整个会话过程他都是有作用的,这个类似于全局变量一样。
@@变量名: 这种在变量前加上 "@@" 符号, 叫做系统变量
*/
6. 存储过程的while循环
-- 计算1~100之间的偶数和
DELIMITER $
CREATE PROCEDURE pro_test6()
BEGIN
-- 定义求和变量
DECLARE result INT DEFAULT 0;
-- 定义初始化变量
DECLARE num INT DEFAULT 1;
-- while循环
WHILE num <= 100 DO
IF num % 2 = 0 THEN
SET result = result + num;
END IF;
SET num = num + 1;
END WHILE;
-- 查询求和结果
SELECT result;
END$
DELIMITER ;
-- 调用pro_test6存储过程
CALL pro_test6();
7. 游标
- 游标可以遍历返回的多行结果,每次拿到一整行数据
- 在存储过程和函数中可以使用游标对结果集进行循环的处理
- 简单来说游标就类似于集合的迭代器遍历
- MySQL中的游标只能用在存储过程和函数中
8. 存储函数
存储函数和存储过程是非常相似的。存储函数可以做的事情,存储过程也可以做到,存储函数有返回值。
-- 定义存储函数,获取学生表中成绩大于95分的学生数量
DELIMITER $
CREATE FUNCTION fun_test1()
RETURNS INT
BEGIN
-- 定义变量
DECLARE s_count INT;
-- 查询成绩大于95分的数量,为s_count赋值
SELECT COUNT(*) INTO s_count FROM student WHERE score > 95;
-- 返回统计结果
RETURN s_count;
END$
DELIMITER ;
-- 调用函数
SELECT fun_test1();
-- 删除函数
DROP FUNCTION fun_test1;
如有错误欢迎留言评论,2021年7月11日 羽露风