SET 变量名 = 值; SET 变量名 := 值; SELECT 字段名 INTO 变量名 FROM 表名 ...;
存储过程
存储过程 - if 判断
语法
IF 条件1 THEN ... ELSE IF 条件2 THEN --可选 ... ELSE --可选 ... END IF;
无参数的存储过程样例
-- 判定分数对应的分数等级。 -- score >= 85分,等级为优秀。 -- score >= 60分且score < 85分,等级为及格。 -- score < 60分,等级为不及格。 create procedure p1() begin declare score int default 58; declare result varchar(10); if score >= 85 then set result := '优秀'; elseif score >= 60 then set result := '及格'; else set result := '不及格'; end if; select result; end;
call p1();
运行结果:
参数
类型
含义
备注
IN
该类参数作为输入,也就是需要调用时传入值
默认
OUT
该类参数作为输出,也就是该参数可以作为返回值
/
INOUT
既可以作为输入参数,也可以作为输出参数
/
语法
CREATE PROCEDURE 存储过程名称 ([IN / OUT / INOUT 参数名 参数类型]) BEGIN --SQL语句 END;
有参数的存储过程样例
-- 根据传入(in)参数score,判定当前分数对应的分数等级,并返回(out)。 -- score >= 85分,等级为优秀。 -- score >= 60分且score < 85分,等级为及格。 -- score < 60分,等级为不及格。 create procedure p1(in score int, out result varchar(10)) begin if score >= 85 then set result := '优秀'; elseif score >= 60 then set result := '及格'; else set result := '不及格'; end if; end;
call p1(68, @result); select @result;
运行结果:
-- 将传入的 200分制的分数,进行换算,换算成百分制,然后返阿分数---> inout create procedure p2(inout score double) begin set score := score * 0.5; end;
set @score = 163; call p2(@score); select @score;
运行结果:
存储过程 - Case
语法一
CASE case_value WHEN when_value1 THEN statement_list1 [WHEN when_value2 THEN statement_Kist 2] ... [ELSE statement_list] END CASE;
语法二
CASE WHEN search_condition1 THEN statement_list1 [WHEN search_condition2 THEN statement_list2] ... [ELSE statemept tlist] END CASE;
样例
-- 根据传入的月份,判定月份所属的季节(要求采用case结构)。 -- 1.1-3月份,为第一季度 -- 2.4-6月份,为第二季度 -- 3.7-9月份,为第三季度 -- 4.10-12月份,为第四季度 create procedure p3(in month int) begin declare result varchar(10);
case when month >= 1 and month <= 3 then set result := '第一季度'; when month >= 4 and month <= 6 then set result := '第二季度'; when month >= 7 and month <= 9 then set result := '第三季度'; when month >= 10 and month <= 12 then set result := '第四季度'; else set result := '非法参数'; end case; select concat('您输入的月份为', month, '所属的季度为', result); end;
call p3(4)
运行结果:
存储过程循环 - while
while循环是有条件的循环控制语句。满足条件后,再执行循环体中的SQL语句。
语法
#先判定条件,如果条件为true,则执行逻辑,否则,不执行逻辑 WHILE 条件 DO SQL逻辑... END WHILE;
样例
-- 计算从1紧加到的值,n为传入的参数值。 -- 1. 定义局部变量,记录累加后的值 -- 2. 每新环一次,就会n进行减1,如果n减到0,则退出循环 create procedure p4(in n int) begin declare total int default 0; while n > 0 do set total := total + n; set n := n - 1; end while; select total; end;
call p4(10);
运行结果:
存储过程循环 - repeat
repeat是有条件的循环控制语句,当满足条件的时候退出循环。
语法
#先执行一次逻辑,然后判定逻辑是否满足,如果满足,则退出。如果不满足,则继续下一次循环 REPEAT SQL逻辑 ... UNTIL 条件 END REPEAT;
样例
-- 计算从1紧加到的值,n为传入的参数值。 -- 1. 定义局部变量,记录累加后的值 -- 2. 每新环一次,就会n进行减1,如果n减到0,则退出循环 create procedure p5(in n int) begin declare total int default 0; repeat set total := total + n; set n := n - 1; until n <= 0 end repeat; select total; end;
call p5(10);
运行结果:
存储过程循环 - loop
LOOP实现简单的循环,如果不在SQL逻辑中增加退出循环的条件,可以用其来实现简单的死循环。
OOP可以配合一下两个语句使用**
LEAVE:配合循环使用,退出循环。
ITERATE:必须用在循环中,作用是跳过当前循环剩下的语句,直接进入下一次循环。
语法
[begin_label:] LOOP SQL逻辑 ... END LOOP [end_label];
-- 计算从1紧加到的值,n为传入的参数值。 -- 1. 定义局部变量,记录累加后的值 -- 2. 每新环一次,就会n进行减1,如果n减到0,则退出循环 ---> leave xxx; create procedure p6(in n int) begin declare total int default 0; sum : loop if n <= 0 then leave sum; end if;
set total := total + n; set n := n - 1; end loop; select total; end;
call p6(10);
运行结果:
样例2
-- 计算从1到n之问的偶数累加的值,n为传入的参数值。 -- 1.定义局部变量,记录累加之后的值; -- 2.每循环一次,就会对n进行-1,如果n减到0,则退出循环 ---> leave xxx -- 3.如果当次累加的数据是奇数,则直接进入下一次循环 ---> iterate xxx create procedure p7(in n int) begin declare total int default 0; sum : loop if n <= 0 then leave sum; end if;
if n % 2 = 1 then set n := n - 1; iterate sum; end if;
set total := total + n; set n := n - 1; end loop; select total; end;
-- 逻辑 -- 1. 声明游标,存储查询到的结果集 -- 2. 准备:创建表结构 -- 3. 开启游标 -- 4, 获取游标中的记录 -- 5. 将记录插入到新的表中 -- 6. 关闭游标 create procedure p8(in uage int) begin declare uname varchar(100); declare upro varchar(100); declare u_cursor cursor for select name, profession from tb_user where age <= uage;
drop table if exists tb_user_pro; create table if not exists tb_user_pro( id int primary key auto_increment, name varchar(100), profession varchar(100) );
open u_cursor;
while true do fetch u_cursor into uname, upro; insert into tb_user_pro values (null, uname, upro); end while;
close u_cursor;
end;
call p8(30);
注意while的循环退出条件为true,即死循环,产生如下bug
注意
普通变量的声明先与游标
循环中如何得知循环结束的条件?即游标什么时候遍历完?
条件处理程序
条件处理程序(Handler)可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤。
语法
DECLARE handler_action HANDLER FOR condition_value [,condition_value] ... statement;
handler_action cONTINUE:继续执行当前程序 EXIT:终止执行当前程序 condition_value SQLSTATE:sqlstate_value:状态码,如02000 SQLWARNING:所有以01开头的SQLSTATE代码的简写 NOT FOUND:所有以02开头的SQLSTATE代码的简写 SQLEXCEPTION:所有没有被SQLWARNING 或 NOT FOUND捕获的SQLSTATE代码的简写
-- 逻辑 -- 1. 声明游标,存储查询到的结果集 -- 2. 准备:创建表结构 -- 3. 开启游标 -- 4, 获取游标中的记录 -- 5. 将记录插入到新的表中 -- 6. 关闭游标 create procedure p8(in uage int) begin declare uname varchar(100); declare upro varchar(100); declare u_cursor cursor for select name, profession from tb_user where age <= uage;
-- 声明条件处理程序,当状态码为 02000 时关闭游标 -- 也可以写为 declare exit handler for not found close u_cursor; declare exit handler for sqlstate '02000' close u_cursor;
drop table if exists tb_user_pro; create table if not exists tb_user_pro( id int primary key auto_increment, name varchar(100), profession varchar(100) );
open u_cursor;
while true do fetch u_cursor into uname, upro; insert into tb_user_pro values (null, uname, upro); end while;