MySQL存储过程手册,及创建存储过程:循环为所有表添加字段

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介: MySQL存储过程手册,及创建存储过程:循环为所有表添加字段

存储过程

有时候仅凭 sql 语句可能达不到想要的数据操作目的,有可能需要写一些方法体,通过循环判断等操作最终达到目的。那么在数据库里实现这种方法体就需要存储过程了,


存储过程简单来说,就是为以后的使用而保存的一条或多条 MySQL 语句的集合。可将其视为批处理文件。虽然他们的作用不仅限于批处理。


本文将通过一个实例初步掌握存储过程,当然要深入学习了解的话还是要看教程文档了。

示例

  • 写一个函数,对一个库里所有的表全部添加一个“status”状态字段
  • 删除存储过程
-- 删除之前存在的存储过程
DROP PROCEDURE IF EXISTS proc_init_status;
  • 创建存储过程
-- 1、创建名为proc_init_status的存储过程
CREATE PROCEDURE proc_init_status()
-- 开始存储过程
BEGIN
-- 自定义变量,控制游标循环变量
DECLARE end_flag int DEFAULT 0;
-- 自定义变量my_name
DECLARE my_name VARCHAR(100);
--  定义游标并输入结果集
DECLARE album_curosr CURSOR FOR 
          -- 该sql为查询dindo_custom库中满足custom_form_表前缀,且不存在status字段的所有表名
          SELECT DISTINCT table_name FROM 
          information_schema.columns 
          WHERE 
          table_schema = 'dindo_custom' 
          AND table_name LIKE 'custom_form_%'  
          AND table_name NOT IN (SELECT table_name FROM  
          information_schema.columns 
          WHERE table_schema = 'dindo_custom' 
          AND table_name LIKE 'custom_form_%'  
          AND column_name = 'status');
-- 绑定控制变量到游标,游标循环结束自动转1
DECLARE CONTINUE HANDLER FOR NOT FOUND SET end_flag=1;
--  打开游标
OPEN album_curosr;
-- 遍历游标
REPEAT
-- 获取当前游标指针记录,取出值赋给自定义的变量my_name
FETCH album_curosr INTO my_name;
-- 利用取到的值进行数据库的操作
SET @stmt = CONCAT("ALTER TABLE ",my_name ," ADD COLUMN `status` varchar(20) DEFAULT NULL COMMENT '状态'");
-- 定义预处理语句
prepare stmt FROM @stmt;
-- 执行预处理语句
EXECUTE  stmt;
 -- 输出sql
SELECT @stmt;
-- 删除(释放)定义
DEALLOCATE PREPARE stmt;
-- 根据 end_flag 判断是否结束
UNTIL end_flag END REPEAT;
-- 关闭游标
close album_curosr;
-- 结束
END;

注意: 这里有一个坑,我也是排查了好久才发现:变量的定义不要和你的select的列的键同名!不然,fetch into 会失败!!!


我之前定义的变量DECLARE table_name VARCHAR(100);和SELECT DISTINCT table_name同名,都叫table_name ,导致我一度怀疑我整个存储过程写的有问题,排查两天才发现,特此记录。

如果你也遇到fetch into不生效问题,也请长个记性!!!


  • 调用存储过程
-- 2、调用
CALL proc_init_status();

存储过程语法解析

  • 再来一个简单示例
-- 创建存储过程 
create procedure mypro(in a int,in b int,out sum int) 
begin 
set sum = a+b; 
end;

create procedure 用来创建过程;


mypro 用来定义过程名称;


(in a int,in b int,out sum int) 表示过程的参数,其中 in 表示输入参数,out 表示输出参数。类似于 Java 定义方法时的形参和返回值;


begin 与end 表示过程主体的开始和结束,相当于 Java 定义方法的一对大括号;


call用来调用过程,@s 是用来接收过程输出参数的变量

存储过程的参数

MySQL 存储过程的参数用在存储过程的定义,共有三种参数类型:


IN 输入参数:表示调用者向过程传入值(传入值可以是字面量或变量);

OUT 输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量);

INOUT输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)。


存储过程根据参数可分为四种类别:


1).没有参数的过程;

2).只有输入参数的过程;

3).只有输出参数的过程;

4).包含输入和输出参数的过程。

变量

MySQL 中的存储过程类似 java 中的方法。


既然如此,在存储过程中也同样可以使用变量。java 中的局部变量作用域是变量所在的方法,而 MySQL 中的局部变量作用域是所在的存储过程。

变量定义

DECLARE variable_name [,variable_name...] datatype [DEFAULT value];
  • declare用于声明变量;
  • variable_name表示变量名称;
  • datatype为 MySQL 的数据类型;
  • default用于声明默认值;
  • 例如:
declare name varchar(20) default ‘macw’;

变量赋值

SET 变量名 = 表达式值 [,variable_name = expression ...]

如上面例子的:

SET @stmt = CONCAT("ALTER TABLE ",my_name ," ADD COLUMN `status` varchar(20) DEFAULT NULL COMMENT '状态'");

流程控制语句

if 条件语句

IF 语句包含多个条件判断,根据结果为 TRUEFALSE执行语句,与编程语言中的 ifelse ifelse 语法类似。

定义存储过程,输入一个整数,使用 if 语句判断是正数还是负数,代码如下所示:

-- 创建过程
create procedure mypro2(in num int)
begin
if num<0 then -- 条件开始
select '负数';
elseif num=0 then
select '不是正数也不是负数';
else
select '正数';
end if;-- 条件结束
end;
-- 调用过程
call mypro2(-1);

运行结果

case 条件语句

case是另一个条件判断的语句,类似于编程语言中的 choosewhen语法。MySQL 中的 case语句有两种语法

格式。

定义存储过程,输入一个整数,使用 case 语句判断是正数还是负数,代码如下所示:

-- 创建过程
create procedure mypro3(in num int)
begin
case -- 条件开始
when num<0 then select '负数';
when num=0 then select '不是正数也不是负数';
else select '正数';
end case; -- 条件结束
end;
-- 调用过程
call mypro3(1);

运行结果

定义存储过程,输入一个整数,使用 case 语句判断是 1 还是 2,代码如下所示:

-- 创建过程
create procedure mypro4(in num int)
begin
case num -- 条件开始
when 1 then select '数值是 1';
when 2 then select '数值是 2';
else select '不是 1 也不是 2';
end case; -- 条件结束
end;
-- 调用过程
call mypro4(3);

两种 case 语法都可以实现条件判断,但第一种适合范围值判断,而第二种适合确定值判断。

while 循环语句

while语句的用法和 java中的 while循环类似。

定义存储过程,使用 while 循环输出 1 到 10 的累加和,代码如下所示:

-- 创建过程
create procedure mypro5(out sum int)
begin
declare num int default 0;
set sum = 0;
while num<10 do -- 循环开始
set num = num+1;
set sum = sum+num;
end while; -- 循环结束
end;
-- 调用过程
call mypro5(@sum);
-- 查询变量值
select @sum;

运行结果

repeat 循环语句

repeat语句的用法和 java中的 do…while 语句类似,都是先执行循环操作,再判断条件,区别是 repeat表达

式值为 false时才执行循环操作,直到表达式值为 true停止。


定义存储过程,使用 repeat 循环输出 1 到 10 的累加和,代码如下所示:

-- 创建过程
create procedure mypro6(out sum int)
begin
declare num int default 0;
set sum = 0;
repeat-- 循环开始
set num = num+1;
set sum = sum+num;
until num>=10
end repeat; -- 循环结束
end;
-- 调用过程
call mypro6(@sum);
-- 查询变量值
select @sum;

运行结果

loop 循环语句

循环语句,用来重复执行某些语句。

执行过程中可使用 leave语句或 iterate 跳出循环,也可以嵌套 IF等判断语句。

  • leave语句效果相当于 java 中的 break,用来终止循环;
  • iterate语句效果相当于 java 中的 continue,用来结束本次循环操作,进入下一次循环。

定义存储过程,使用 loop 循环输出 1 到 10 的累加和,代码如下所示:

-- 创建过程
create procedure mypro7(out sum int)
begin
declare num int default 0;
set sum = 0;
loop_sum:loop-- 循环开始
set num = num+1;
set sum = sum+num;
if num>=10 then
leave loop_sum;
end if;
end loop loop_sum; -- 循环结束
end;
-- 调用过程
call mypro7(@sum);
-- 查询变量值
select @sum;

运行结果

代码中的 loop_sum 相当于给循环贴个标签,方便多重循环时灵活操作。

存储过程的管理

存储过程的管理主要包括:显示过程、显示过程源码、删除过程。

比较简单的方式就是利用 navicat 客户端工具进行管理,鼠标点击操作即可,如下图所示:

显示存储过程

SHOW PROCEDURE STATUS;

显示特定数据库的存储过程

SHOW PROCEDURE status where db = 'schooldb';

显示特定模式的存储过程,要求显示名称中包含“my”的存储过程

SHOW PROCEDURE status where name like '%my%';

显示存储过程“mypro1”的源码

SHOW CREATE PROCEDURE mypro1;

删除存储过程“mypro1”

drop PROCEDURE mypro1;
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
存储 Java 关系型数据库
java调用mysql存储过程
在 Java 中调用 MySQL 存储过程主要借助 JDBC(Java Database Connectivity)。其核心原理是通过 JDBC 与 MySQL 建立连接,调用存储过程并处理结果。具体步骤包括:加载 JDBC 驱动、建立数据库连接、创建 CallableStatement 对象、设置存储过程参数并执行调用。此过程实现了 Java 程序与 MySQL 数据库的高效交互。
|
9月前
|
关系型数据库 MySQL
MySQL数据表添加字段(三种方式)
本文解析了数据表的基本概念及字段添加方法。在数据表中,字段是纵向列结构,记录为横向行数据。MySQL通过`ALTER TABLE`指令支持三种字段添加方式:1) 末尾追加字段,直接使用`ADD`语句;2) 首列插入字段,通过`FIRST`关键字实现;3) 指定位置插入字段,利用`AFTER`指定目标字段。文内结合`student`表实例详细演示了每种方法的操作步骤与结构验证,便于理解与实践。
|
存储 关系型数据库 MySQL
【YashanDB知识库】MySQL返回结果集的存储过程的改写方法
本文介绍了将MySQL存储过程改写至YashanDB的解决方案。由于MySQL存储过程可直接返回结果集,而YashanDB需通过返回SYS_REF_CURSOR的函数实现类似功能,因此需要对代码进行转换。示例中展示了如何将MySQL存储过程`proc1`改写为YashanDB函数,并调整JDBC应用代码以适配REF_CURSOR输出参数,从而正确获取查询结果。此方法确保了跨数据库场景下的兼容性与功能性。
|
分布式计算 关系型数据库 MySQL
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
346 8
|
存储 SQL NoSQL
|
存储 关系型数据库 MySQL
MySQL 存储过程返回更新前记录
MySQL 存储过程返回更新前记录
274 3
|
存储 SQL 关系型数据库
MySQL 存储过程错误信息不打印在控制台
MySQL 存储过程错误信息不打印在控制台
327 1
|
关系型数据库 MySQL 索引
MySQL的group by与count(), *字段使用问题
正确使用 `GROUP BY`和 `COUNT()`函数是进行数据聚合查询的基础。通过理解它们的用法和常见问题,可以有效避免查询错误和性能问题。无论是在单列分组、多列分组还是结合其他聚合函数的场景中,掌握这些技巧和注意事项都能大大提升数据查询和分析的效率。
1472 0
|
关系型数据库 MySQL Java
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
346 0
|
SQL 存储 关系型数据库
MySQL新增字段/索引会不会锁表?
MySQL新增字段/索引会不会锁表?
1540 0

推荐镜像

更多