MySQL存储过程:in、out与inout参数详解与实操

宋时安
宋时安
发布时间:2026-10-15 | 5人浏览过
原创

本文深入讲解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存储过程开发优化的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表