MySQL存储过程:in、out与inout参数详解与实操
本文深入讲解MySQL存储过程中核心参数类型(in、out、inout)的语法定义、使用场景及代码实现。结合emp表操作案例,详细说明局部变量、系统变量与用户变量的区别及赋值方法,提供完整的创建、调用与结果获取步骤。
什么是存储过程?
MySQL 从 5.0 版本开始支持存储过程。本质上,它是一组预先编译好的 SQL 语句集,用于实现复杂的业务逻辑,类似于编程语言中的函数。
核心特点:
- 功能强大:支持声明变量、if/else 条件判断、case 分支、while 循环等控制结构。
- 模块化复用:将常用的数据库操作封装起来,提高代码可读性与维护性。
- 执行效率高:存储过程在第一次执行时需经过编译和优化,后续调用直接执行已缓存的计划,省去了解析和优化开销。
基础语法与变量声明
第1步:定义存储过程骨架
在MySQL中,默认的语句结束符是分号(;),但在定义包含多条SQL语句的存储过程时,需要临时修改结束符,以免提前结束定义。
-- 自定义结束符号为 $$
delimiter $$
create procedure proc01()
begin
-- SQL语句体
select empno,ename from emp;
end $$
-- 恢复默认结束符号
delimiter ;
-- 调用存储过程
call proc01();
第2步:声明局部变量
局部变量仅在 begin...end 块内有效,适用于存储过程内部的临时数据存储。
- 声明语法:
declare var_name type [default value]; - 赋值方式1:使用
set命令:set var_name = 'value'; - 赋值方式2:使用
SELECT ... INTO从表中查询并赋值:
select col_name into var_name from table_name where condition;
注意:SELECT ... INTO 查询结果必须是单行单列,否则会产生错误。
-- 示例:使用 SELECT INTO 赋值
delimiter $$
create procedure proc03()
begin
declare my_ename varchar(20);
-- 将查询结果赋值给变量
select ename into my_ename from emp where empno=1001;
select my_ename;
end $$
delimiter ;
call proc03();
第3步:了解用户变量与系统变量
用户变量:以 @ 开头,不需要显式声明,在当前会话(连接)期间有效,生命周期超出存储过程作用域。
delimiter $$
create procedure proc04()
begin
set @var_name01 = 'ZS';
end $$
delimiter;
call proc04() ;
select @var_name01 ;
系统变量:分为全局变量(Global)和会话变量(Session)。全局变量影响整个服务器,会话变量仅影响当前连接。
-- 查看并修改全局变量
show global variables;
set global sort_buffer_size = 40000;
-- 查看并修改会话变量
show session variables;
set session sort_buffer_size = 50000;
输入参数 (IN)
IN 参数用于向存储过程传入值。在过程内部可以读取或修改该参数,但修改后的值不会返回给调用者。若参数名与字段名相同,建议在查询时使用表名限定(如 t.col)以避免歧义。
第4步:创建并使用 IN 参数
以下示例演示传入员工编号查询信息,以及传入部门名和薪资进行多条件筛选。
-- 简单参数传递
delimiter $$
create procedure dec_param01(in param_empno varchar(20))
begin
select * from emp where empno = param_empno;
end $$
delimiter ;
call dec_param01('1001');
-- 多参数传递
-- 查询指定部门(dname)下薪资(sal)大于指定值的员工
delimiter $$
create procedure dec_param0x(in dname varchar(50), in sal decimal(7,2))
begin
select * from dept a, emp b
where b.sal > sal and a.dname = dname;
end $$
delimiter ;
call dec_param0x('学工部',20000);
输出参数 (OUT)
OUT 参数用于从存储过程内部向外部返回值。必须在过程内部对其进行赋值(通常使用 INTO 或 SET),才能在过程结束后被调用者获取。
第5步:创建并使用 OUT 参数
调用时,必须传入用户变量(@var_name)来接收输出的值。
-- 传入编号,返回员工名字
delimiter $$
create procedure proc08(in empno int , out out_ename varchar(50) )
begin
select ename into out_ename from emp where emp.empno = empno;
end $$
delimiter ;
-- 调用:传入用户变量 @o_ename 接收结果
call proc08(1001, @o_ename);
select @o_ename;
-- 多输出参数示例:返回名字和薪资
delimiter $$
create procedure proc09(in empno int , out out_ename varchar(50) , out out_sal decimal(7,2))
begin
select ename,sal into out_ename,out_sal from emp where emp.empno = empno;
end $$
delimiter ;
call proc09(1001, @o_dname,@o_sal);
select @o_dname;
select @o_sal;
输入输出参数 (INOUT)
INOUT 兼具 IN 和 OUT 的特性。调用时传入值进入过程,过程内部可修改该值,修改后的值会自动传回给调用者。
第6步:创建并使用 INOUT 参数
此示例演示传入员工名和月薪,过程内部拼接部门号并将月薪转为年薪,最终返回修改后的值。
-- 传入员工名,拼接部门号;传入薪资,计算年薪
delimiter $$
create procedure proc10(inout inout_ename varchar(50),inout inout_sal int)
begin
-- 修改字符串参数
select concat(deptno,"_",inout_ename) into inout_ename from emp where ename = inout_ename;
-- 修改数值参数
set inout_sal = inout_sal * 12;
end $$
delimiter ;
-- 初始化用户变量
set @inout_ename = '关羽';
set @inout_sal = 3000;
-- 调用并自动接收修改后的值
call proc10(@inout_ename, @inout_sal) ;
-- 查看结果
select @inout_ename ;
select @inout_sal ;
总结
- IN:只进不出,适合做查询条件的过滤。
- OUT:只出不进,适合获取过程内部的计算结果或状态码。
- INOUT:既进又出,适合需要对原始数据进行转换并返回的场景。
以上就是MySQL存储过程in、out与inout参数用法的详细内容,更多关于MySQL存储过程开发优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













