MySQL存储过程传参(IN/OUT/INOUT)与流程控制实战
本文将深入解析MySQL存储过程的参数传递机制(IN、OUT、INOUT)以及核心的流程控制语句(IF判断、CASE分支、循环结构),通过具体的代码示例和截图演示,帮助用户理解如何在数据库中封装复杂的业务逻辑。
一、存储过程传参:IN(输入参数)
IN 表示传入的参数。在调用存储过程时,可以传入常量数值或变量。需要注意的是,即使在存储过程内部修改了 IN 参数变量的值,也不会影响外部传入的原始变量,其作用域仅限于存储过程内部。
第1步:基础传参查询
目的:根据传入的员工编号,查询对应的员工信息。
use test_procedure; -- 定义带有in参数的存储过程 delimiter $$ create procedure proc6(in in_empno int) begin select * from emp where emp.empno = in_empno; end $$ delimiter ; -- 调用测试 CALL proc6(1001);
第2步:多条件组合查询
目的:根据部门名称和薪资阈值,查询指定部门且薪资高于设定值的员工。
delimiter $$
create procedure proc7(in in_dname char(50),in in_sal int)
begin
SELECT * FROM dept,emp
WHERE dept.deptno = emp.deptno
AND (dept.dname=in_dname)
AND (in_sal < emp.sal);
end $$
delimiter ;
-- 调用:查询学工部中薪资大于20000的员工
CALL proc7('学工部', 20000); 二、存储过程传参:OUT(输出参数)
OUT 参数用于从存储过程内部向外部返回结果。调用存储过程后,外部变量将接收到存储过程执行结束后的最终值。通常配合用户变量(如 @var_name)使用。
第3步:返回单个字段
目的:传入员工编号,返回该员工的姓名。
delimiter $$ create procedure proc8(in in_empno int, out out_ename varchar(50)) begin -- 将查询结果赋值给out参数 SELECT ename INTO out_ename FROM emp WHERE emp.empno = in_empno; end $$ delimiter ; -- 调用并查看结果 CALL proc8(1001, @o_ename); -- 执行无直接输出 SELECT @o_ename;
第4步:返回多个字段
目的:传入员工编号,同时返回员工姓名和薪资。
delimiter $$ create procedure proc9(in in_empno int, out out_ename varchar(50), out out_sal int) begin SELECT emp.ename, emp.sal INTO out_ename, out_sal FROM emp WHERE emp.empno = in_empno; end $$ delimiter ; CALL proc9(1001, @o_ename, @o_sal); SELECT @o_ename, @o_sal;
三、存储过程传参:INOUT(双向参数)
INOUT 结合了 IN 和 OUT 的特性。它允许将外部变量的值传入存储过程,并在过程内部修改该变量,修改后的值在存储过程结束后会回传给外部变量。
第5步:数值计算与回传
目的:传入一个数字,将其乘以10后返回。
delimiter $$ create procedure proc10(inout num int) begin SET num = num * 10; end $$ delimiter ; -- 注意:INOUT参数必须使用用户变量传递 SET @inout_num = 10; CALL proc10(@inout_num); SELECT @inout_num;
第6步:字符串拼接与数值运算
目的:传入员工姓名和月薪,返回“部门号_姓名”格式的名字,并将月薪转换为年薪。
delimiter $$
create procedure proc11(inout inout_ename varchar(50), inout inout_sal int)
begin
-- 获取部门号并拼接名字
SELECT concat_ws('_', emp.deptno, emp.ename) INTO inout_ename
FROM emp WHERE emp.ename = inout_ename;
-- 计算年薪
SET inout_sal = inout_sal * 12;
end $$
delimiter ;
SET @ino_ename = '关羽';
SET @ino_sal = 20000;
CALL proc11(@ino_ename, @ino_sal);
SELECT @ino_ename, @ino_sal;
四、流程控制:IF判断语句
IF 语句类似于编程语言中的 if-elseif-else 结构,根据条件的真假执行不同的SQL块。
第7步:成绩等级评定
目的:根据分数返回对应的等级(不及格、及格、良好、优秀)。
delimiter $$ create procedure proc12(in in_score int) begin IF in_score < 60 THEN SELECT '不及格'; ELSEIF in_score <= 80 THEN SELECT '及格'; ELSEIF in_score <= 90 THEN SELECT '良好'; ELSEIF in_score <= 100 THEN SELECT '优秀'; ELSE SELECT '成绩错误'; END IF; end $$ delimiter ; CALL proc12(77);
第8步:薪资分类与变量处理
目的:根据员工姓名获取薪资,并划分为试用期、转正期或元老级。演示了局部变量(DECLARE)和用户变量(@)的不同处理方式。
-- 方法一:使用局部变量 DECLARE
delimiter $$
create procedure proc13(in in_ename varchar(50))
begin
declare de_sal decimal(7,2);
declare de_result varchar(50);
-- 查询薪资到局部变量
SELECT emp.sal INTO de_sal FROM emp WHERE emp.ename = in_ename;
IF de_sal < 10000 THEN
SET de_result='试用薪资';
ELSEIF de_sal < 20000 THEN
SET de_result='转正薪资';
ELSE
SET de_result='元老薪资';
END IF;
SELECT de_result; -- 返回分类结果
end $$
delimiter ;
CALL proc13('关羽');
-- 方法二:使用用户变量(无需DECLARE声明)
delimiter $$
create procedure proc14(in in_ename varchar(50))
begin
declare de_sal decimal(7,2);
-- 直接查询到用户变量
SELECT emp.sal INTO @de_sal FROM emp WHERE emp.ename = in_ename;
IF @de_sal < 10000 THEN
SET @de_result='试用薪资';
ELSEIF @de_sal < 20000 THEN
SET @de_result='转正薪资';
ELSE
SET @de_result='元老薪资';
END IF;
end $$
delimiter ;
CALL proc14('关羽');
SELECT @de_sal, @de_result; 五、流程控制:CASE分支
CASE 语句类似于编程语言中的 switch-case,适用于多值分支判断。支持两种语法格式。
第9步:支付方式转换
目的:根据数字类型返回对应的支付渠道名称。
-- 格式一:CASE expression WHEN value THEN ... delimiter $$ create procedure proc16(in in_type int) begin CASE in_type WHEN 1 THEN SELECT '微信支付'; WHEN 2 THEN SELECT '支付宝支付'; WHEN 3 THEN SELECT '银行卡支付'; WHEN 4 THEN SELECT '其他方式支付'; END CASE; end $$ delimiter ; CALL proc16(2); -- 格式二:CASE WHEN condition THEN ... delimiter $$ create procedure proc17(in in_type int) begin CASE WHEN in_type=1 THEN SELECT '微信支付'; WHEN in_type=2 THEN SELECT '支付宝支付'; WHEN in_type=3 THEN SELECT '银行卡支付'; WHEN in_type=4 THEN SELECT '其他方式支付'; END CASE; end $$ delimiter ; CALL proc17(4);
六、流程控制:循环结构
循环允许重复执行一段代码,直到满足特定条件。MySQL主要支持 WHILE、REPEAT 和 LOOP 三种循环,并使用 LEAVE(跳出循环)和 ITERATE(继续下一次)进行控制。
第10步:WHILE循环(先判断后执行)
目的:向表中插入数据,演示如何使用标签(Label)配合 LEAVE 提前终止循环。
注意:使用 LEAVE 或 ITERATE 时必须为循环定义标签。
delimiter $$
create procedure proc18(in in_count int)
begin
declare i int default 1;
label: WHILE i <= in_count DO
INSERT INTO user(id, name, password) VALUES(i, CONCAT('user-', i), 123456);
SET i = i + 1;
-- 当i等于5时跳出循环
IF i = 5 THEN LEAVE label;
END IF;
END WHILE label;
end $$
delimiter ;
CALL proc18(10);
第11步:REPEAT循环(先执行后判断)
目的:实现类似功能,但语法结构不同,它在循环末尾判断 UNTIL 条件。
TRUNCATE TABLE user;
delimiter $$
create procedure proc20(in in_count int)
begin
declare i int default 1;
a: REPEAT
INSERT INTO user(id, name, password) VALUES(i, CONCAT('user-', i), 123456);
SET i = i + 1;
UNTIL i > in_count
END REPEAT a;
end $$
delimiter ;
CALL proc20(10);
第12步:LOOP循环(需手动退出)
说明:LOOP 本身没有内部终止条件,通常需要结合 IF ... THEN LEAVE 来实现退出,这与 REPEAT 的 UNTIL 不同。
以上就是MySQL存储过程传参及流程控制的详细内容,更多关于MySQL存储过程进阶用法的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









