MySQL数据库精研之旅第十八期:存储过程,数据处理的全能工具箱(一)
专栏:MySQL数据库成长记
个人主页:手握风云
目录
一、存储过程
1.1. 存储过程是什么
1.2. 特点
1.3. 优点
1.4. 缺点
1.5. 语法
1. 创建
2. 调用
3. 查看
4. 删除
1.6. 示例
二、变量
2.1. 系统变量
1. 查看系统变量
2. 设置系统变量
2.2. 用户自定义变量
1. 赋值
2. 使用
2.3. 局部变量
1. 声明
2. 赋值
3. 使用
三、SQL编程
3.1. 条件判断——IF语句
1. 语法
2. 示例
3.2. 参数
1. 分类
2. 语法
3. 示例
一、存储过程
1.1. 存储过程是什么
存储过程是⼀组为了完成特定功能的SQL语句集,经编译后存储在数据库中,⽤户通过指定存储过程的名字和参数来执行,并获取相应的结果。这里可以理解为用SQL语言实现的方法。
1.2. 特点
- 封装性:将业务逻辑封装在数据库内部,减少应用程序的复杂性。
- 可维护性:集中管理数据库操作,便于维护和更新。
- 可重用性:可以被多次调用,提高代码的重用性。
1.3. 优点
- 性能优化:存储过程在创建时编译并存储在数据库中,执行速度比单个SOL语句快。
- 代码重用:存储过程可以重复调用,减少重复代码,提高代码的可维护性。
- 安全性:可以限制用户直接访问数据库,通过存储过程间接访问,从而保证系统安全性。
- 事务管理:可以在存储过程中实现复杂的事务逻辑。
- 降低耦合:当表结构发生变化时,只需要修改相应的存储过程,应用程序的改动较小。
1.4. 缺点
- 可移植性差:存储过程不能跨数据库移植,更换数据库时需要重新编写。
- 调试困难:只有少数数据库管理系统支持存储过程的调试,开发和维护困难。
- 不适合高并发场景:在高并发场景下,存储过程可能会增加数据库的压力,难以维护。
1.5. 语法
1. 创建
-- 修改SQL语句结束标识符为//
DELIMITER //-- 创建存储过程
CREATE PROCEDURE 存储过程名 (参数列表)
BEGIN-- SQL语句
END //
在命令行终端里面,SQL语句和END后面都跟一个分号,导致无法区分,所以我们可以使用DELIMITER修改结束标识符。
2. 调用
-- 调用存储过程
CALL 存储过程名 (参数列表);
3. 查看
-- 查看指定数据库中创建的存储过程
SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = '数据库名';-- 查看存储过程的定义
SHOW CREATE PROCEDURE 存储过程名;
4. 删除
DROP PROCEDURE [IF EXIST] 存储过程名;
1.6. 示例
create procedure p_calAvg()
beginselect `name`,chinese + math + english as total from exam;
endcall p_calAvg();-- 查看指定数据库中创建的存储过程
SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = 'teset3_26_1';show create table exam;show create procedure p_calAvg;
二、变量
在MySQL中变量可以分为三类:系统变量、⽤⼾⾃定义变量、以及局部变量。
2.1. 系统变量
系统变量是MySQL服务器的配置变量,控制着服务器的行为和性能。分为全局变量(GLOBAL)和会话变量(SESSION)。
系统变量所涉及到的配置文件在我们安装完MySQL之后,会在默认路径下生成对应的文件。
全局变量,就是启动时读取的值,比如启动微信时,微信名就是一个全局变量;会话变量,启动数据库时,每个链接就是一个会话,好比我们在每个群里会设置不同的群昵称。
1. 查看系统变量
-- 查看所有系统变量,不指定默认是会话变量
SHOW [GLOBAL|SESSION] VARIABLES;-- 查看指定的系统变量
SHOW [GLOBAL|SESSION] VARIABLES LIKE 'xxx';
-- 查看指定的系统变量,可以通过LKTE进行模糊查询
SHOW [GLOBALISESSION] VARIABLES like '%xxx%';-- 使用SELECT查看指定系统变量
SELECT @@[GLOBAL|SESSION].系统变量名;
show global variables like 'auto%';
show session variables like 'chars%';
select @@global.autocommit;
2. 设置系统变量
SET [GLOBAL|SESSION] 系统变量名 = 值;
SET @@SESSION.系统变量名=值;
修改会话变量,不会影响全局变量的值,下一个会话开启之后还是全局变量的值。MySQL重启后,设置的全局(GLOBAL)变量失效,如果想使全局系统变量永久生效,需要修改选项文件。
2.2. 用户自定义变量
用户自定义变量是在SQL会话中定义的变量,不用提前声明,作用域为当前会话。它的作用就是保存查询的中间结果,以便以后使用。
1. 赋值
-- 方式一
SET @var_name = expr [,@var_name]...;-- 方式二
SET @var name := expr [, @var_name]...;-- 方式三
SELECT var name := expr [, @var name]...;-- 方式四
SELECT 列名 INTO varname FROM 表名 WHERE...;
由于SQL中比较相等也是用等号(=),所以在为变量赋值的时候推荐使用(:=)。
2. 使用
-- 声明+赋值
set @age = 18;
select @age;select @age := 20;select count(*)into @stu_count from student;
select @stu_count;
set @age := 18;
select * from student where age = @age;
2.3. 局部变量
局部变量只在存储过程、函数或触发器的范围内有效。需要使用DECLARE声明,作用域的范围在声明的 BEGIN...END 块内。
1. 声明
变量可以是任何有效的MySQL数据类型,如INT、VARCHAR、DATETIME等。
DECLARE 变量名 变量类型[DEFAULT 默认值]..·;
2. 赋值
-- 方式一
SET var_name=值;-- 方式二
SET var_name := 值;-- 方式三:查询结果赋值给⾃定义变量
SELECT 列名 INTO var_name FROM 表名 WHERE ...;
3. 使用
delimiter //-- 创建存储过程
CREATE PROCEDURE p1()
BEGIN-- 定义局部变量DECLARE stu_count INT DEFAULT 0;-- 把查询结果赋值给局部变量SELECT count(*) INTO stu_count FROM student;-- 使用局部变量SELECT stu_count;END//
delimiter ;-- 调用存储过程
CALL p1;
在存储过程和函数中,局部变量必须在使用前声明。⽤户自定义变量在会话结束时失效,而局部变量在存储过程或函数结束时失效。
三、SQL编程
结构化查询语言(Structured Query Language),简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
3.1. 条件判断——IF语句
1. 语法
IF 条件1 THEN
……
[ELSEIF 条件2 THEN
……
ELSE
……]
END IF;
2. 示例
-- 根据分数的值,判定当前分数对应的等级
-- 分数>=90分等级为优秀
-- 分数>=80且分数<90分等级为良好
-- 分数>=60分且分数<80分等级为及格
-- 分数<60分等级为不及格delimiter //-- 创建存储过程
CREATE PROCEDURE p2()
BEGIN-- 定义初始分数变量DECLARE score INT DEFAULT 86;DECLARE ret VARCHAR(10);-- 判断IF score >= 90 THEN-- 为变量赋值SET ret := '优秀';ELSEIF score >= 80 AND score < 90 THENSET ret := '良好';ELSEIF score >= 60 AND score < 80 THENSET ret := '及格';ELSESET ret := '不及格';END IF;-- 查询结果SELECT ret;
END//delimiter ;CALL p2;
3.2. 参数
上面传入的值是固定的,要想进行动态传入,就需要定义一些参数。
1. 分类
类型 | 描述 |
IN | 输入类型,调用存储过程时要传入的值,默认参数类型 |
OUT | 输出类型,可以作为存储过程的返回值 |
INOUT | 输入输出类型,即可以作为输入类型也可以做为输出类型 |
2. 语法
DELIMITER //CREATE PROCEDURE 存储过程名 ([IN/OUT/INOUT 参数名 参数类型] [,...])
BEGIN-- SQL语句
END // DELIMITER;
3. 示例
-- 传入一个分数的值,判定当前分数对应的等级
-- 分数>=90分等级为优秀
-- 分数>=80且分数<90分等级为良好
-- 分数>=60分且分数<80分等级为及格
-- 分数<60分等级为不及格
delimiter //-- 1. 创建存储过程:接收输入分数(IN参数),输出等级结果(OUT参数)
CREATE PROCEDURE p3(IN score INT, OUT result VARCHAR(10))
BEGIN-- 条件判断分数对应的等级IF score >= 90 THENSET result := '优秀';ELSEIF score >= 80 AND score < 90 THENSET result := '良好';ELSEIF score >= 60 AND score < 80 THENSET result := '及格';ELSESET result := '不及格';END IF;
END//delimiter ;
-- 2. 调用存储过程:传入分数88,用用户自定义变量@result接收输出结果
CALL p3 (88, @result);-- 3. 查看结果:查询用户自定义变量@result的值
SELECT @result;
delimiter //-- 1. 创建存储过程:接收输入分数,累加10后返回(INOUT参数兼具输入/输出功能)
CREATE PROCEDURE p4(INOUT score INT)
BEGIN-- 业务逻辑:在原分数基础上加10分SET score := score + 10;
END//
delimiter ;-- 2. 定义用户自定义变量并赋值初始分数(98)
SET @score := 98;-- 3. 调用存储过程:传入变量@score(既作为输入,也接收更新后的值)
CALL p4 (@score);-- 4. 查看结果:查询更新后的分数
SELECT @score;