Skip to content

存储过程

---类似于函数的思想

在操作数据库的时候,每条语句都会建立一次链接,这造成了很大的开销,我们可以把一些SQL存储到数据库本身,外部调用仅仅掉用这个SQL集合就可以实现一系列操作,我们把这个集合叫做存储过程。

特点

​ 1:封装,复用 ​ 2:可以接受参数,返回结果 ​ 3:减少网络开支

创建

sql
create procedure procedure_name ([参数])
begin
    存储体语句;
end;

使用

sql
call procedure_name([参数]);

查询

sql
# 根据主机名查看
select * from information_schema.ROUTINES
    where ROUTINE_SCHEMA = '数据库名称';
# 根据存储过程名查看
show create procedure p1;

删除

sql
drop procedure if exists procedure_name;

变量

系统变量

由mysql数据库创建,不是由用户定义的,属于服务器层面,分为全局变量【global】和回话变量【session】用 @@变量名 表示;

查看系统变量

sql
show [global | session(默认)] variables [like ...];
# 也可以指定变量查找
select @@ [global | session] 系统变量名;

设置系统变量

sql
set [@@] [global | session] 系统变量名 = 值;

用户变量

用户变量不需要提前声明,在使用的时候直接用 @变量名 就可以使用,作用域为当前会话

赋值

sql
# 方法一
set @var_name [:]= 值 [,@var_name = 值];
# 方法二
select @var_name [:]= 值 [,@var_name = 值];
# 方法三
select 字段名 into @Var_name from table_name;

使用

sql
select @var_name [,@var_name];

如果使用了一个没有初始化的变量,就会返回一个负值


局部变量

局部变量需要声明才能使用,生命周期在一段 begin和end中。

声明:

sql
declare var_name 变量类型 [default];

default:指定变量默认值;


赋值

sql
# 方法一
set @var_name [:]= 值 [,@var_name = 值];
# 方法二
select @var_name [:]= 值 [,@var_name = 值];
# 方法三
select 字段名 into @Var_name from table_name;

if

结构

if 条件 then
	结果
elseif 条件 then
	结果
else
	结果
end if;

参数

示例

sql
create procedure p2(in s int,out str varchar(10),inout teacher_name varchar(10))
begin
    set teacher_name := concat(substring(teacher_name,1,1),'老师');
    if s >= 60 then
        set str := '及格';
    else
        set str := '及格';
    end if;
end;

set @teacher_name = '王天正';
call p2(60,@str,@teacher_name);
select @str,@teacher_name;

case

结构

sql
# 结构一:通过比较值是否相等,判断执行哪一条语句
case
	whenSQL
	[when 值 SQL]
	[else SQL]
end case;
# 结构一:通过判断每条分支表达式的值,来决定执行哪一条语句
case
	when 表达式 SQL
	[when 表达式 SQL]
	[else SQL]
end case;

循环

while

while别看长得像do-while 其实就是while

sql
while 条件 do 
	SQL...
end while;

repeat

其实是do-while....不对!repeat是满足条件就退出,而不是满足条件就继续执行!!!

sql
repeat
	SQL...
	until 条件
end repeat;

loop + leave + iterate

loop:可以理解成简单的无限循环 leave:break iterate:continue

sql
[标记名:]loop
	SQL...
end loop [标记名];
sql
# 离开当前标记
leave 标记名
# 执行下一次标记
iterate 标记名

游标 cursor

从目前看来,存储过程所返回的变量只有SQL基础的数据类型所创建的变量,但是很多时候,我们拿到的数据并不是单个的数据,通常作为一个表出现,这就出现了多对一的矛盾,为了解决这个矛盾,出现了游标

声明

sql
declare 游标名称 cursor for 查询语句;

注意,声明游标语句必须存在在变量之后

开启

sql
open 游标名称

获取

sql
fetch 游标名称 into 变量 [,变量];

关闭

sql
close 游标名称

条件处理程序 handler

在读取游标数据时,一般情况下会用到无限循环去读取,当游标为空的时候,我们再去读取就会报错,有没有不报错解决办法呢, 答案是没有,但是我们可以对错误进行处理,不让错误出现

就诞生了条件处理程序,感觉和java和py的错误处理差不错

创建

declare handler_action handler for condition_value [,condition——value] statement;

handler_action:发现错误后执行的操作 exit:直接退出 continue:继续执行(?)

handler_action:捕捉错误 sqlstate + 状态码 sqlwarning 以01开头的状态码 not found 以02开头的状态码 sqlexception 上面二者的补集

对于上述的错误码,在SQL的官方文档有记载,不过让他先出错再修理可能更有效率(?

statement:执行的SQL


存储函数

存储函数是存储过程的特殊表现形式, 存储函数被要求是有返回值的存储过程,并且参数全部是 in 类型

sql
create function 存储函数名称(参数列表)
returns 返回值类型 [characteristic]
begin
	SQL...
    return 返回值;
end;

characteristicdeterministic:相同的数据会产生相同的结果 no sql:不包含SQL语句 reads sql data:包含读取数据的语句,但不包含写入数据的语句


Contact me: 1943284256@qq.com