MySQL学习笔记-存储过程、存储函数、流程控制和游标

86 阅读3分钟

一、存储过程

1、语法结构

存储过程语法

create procedure 存储过程名(in|out|inout 参数名称 参数类型, ...)
[characteristics ...]
begin
    存储过程体
end

设置新的结束标记

delimiter 新的结束标记

为了避免与存储过程体里的sql结束符冲突,需要使用delimiter改变存储过程的结束符。
存储过程定义完毕后,需要用delimiter ;改回默认结束符

定义变量以及给变量赋值

declare 变量名 变量类型;
set 变量名 = 值;

while循环

while 条件 do
    循环体
end while;

存储过程调用

call 存储过程名;
call dbname.存储过程名 -- 调用其他数据库的存储过程

-- 调用in参数的存储过程
call sp1(值);

-- 调用out参数的存储过程
set @name;
call sp1(@name);
select @name;

-- 调用inout参数的存储过程
set @name = 值;
call sp1(@name);
select @name;

2、实例

按天创建下个月的表

知识点:

date_add(last_day(date_format(now(),'%Y-%m-%d')),interval 1 day)

date_add加1天

last_day获取指定时间对应的月的最后一天

date_format时间格式转换

loop循环

prepare预编译

execute执行

drop procedure if exists xhjb;
create procedure xhjb()
begin
		declare ksrq varchar(20) default date_add(last_day(date_format(now(),'%Y-%m-%d')),interval 1 day);
		declare ts int default timestampdiff(day,ksrq,last_day(ksrq)) + 1;
		
		xhjb_loop:loop
				if ts > 0 then
						set ts = ts - 1;
						set @create_yj = concat('create table if not exists comp_',replace(date_add(ksrq,interval ts day),'-','_'),' ( zd1 int,zd2 varchar(36))');
						prepare stmt_name from @create_yj;
						execute stmt_name;
						deallocate prepare stmt_name;
						iterate xhjb_loop;
				else
						leave xhjb_loop;
				end if;
		end loop xhjb_loop;
end//
delimiter ;

call xhjb();

二、函数

1、语法结构

函数语法

create function 函数名(参数名 参数类型, ...)
return 返回值类型
[characteristics ...]
begin
    函数体 -- 函数体中必定包含return子句
end

注: function总是默认参数为in类型,不支持指定参数的输入输出类型

函数调用

select 函数名(实参列表);

三、流程控制

1、分支结构

if语句

if 条件1 then 操作1
[elseif 条件2 then 操作2]
[else 操作n]
end if 

case语句

case 表达式1
when1 then 结果1或语句1(如果是语句,需要加分号)
when2 then 结果2或语句2
...
else 结果n或语句n
end [case] (如果是在begin end中,需要加case,在select中不需要)
case
when 条件1 then 结果1或语句1
when 条件2 then 结果2或语句2
...
else 结果n或语句n
end [case]

2、循环结构

loop _ leave

  • 结构
[loop_label:] loop
    循环体
end loop [loop_label]
-- loop_label是loop语句的标识名称,可省略,使用了循环控制语句(leave等)时,不能省略
-- 循环体中需要包含leave语句,用来退出循环
  • 示例
declare id int default 0;
add_loop: loop
    set id = id + 1;
    if id >= 10 then leave add_loop;
    end if;
end loop add_loop;

while

  • 结构
[while_label:] while 循环条件 do
    循环体
end while [while_label]
-- while_label是while循环的标识名称,可省略
-- while执行时,先对循环条件进行判断,为真时才执行循环体,直到条件为假退出循环

repeat

  • 结构
[repeat_label:] repeat
    循环体
until 条件
end repeat [repeat_label]
-- repeat_label时repeat循环的标识名称,可省略
-- repeat循环执行时,会先执行一次循环体,然后判断条件,知道条件为假时退出循环

三种循环的对比

  • 1、三种循环都可以省略标识名称,但是使用了循环控制语句(leave或iterate)后,不可以省略标识名称
  • 2、loop一般用于实现简单的"死"循环
  • 3、while先判断条件后执行循环
  • 4、repeat先执行循环再判断条件,至少执行一次

循环控制语句

  • leave:作用等同于break,可用于循环或者begin end
delimiter $
create procedure leave_begin()
leave_label:begin
    select 1;
    leave leave_label;
    select 2;
end $
delimiter $
  • iterate:作用等同于continue,只能用于循环

四、游标

什么是游标?

  • 能定位查询结果集的每一条记录,并使用记录中的数据进行操作的数据结构

使用方法

  • 步骤一:声明游标