存储过程
---类似于函数的思想
在操作数据库的时候,每条语句都会建立一次链接,这造成了很大的开销,我们可以把一些SQL存储到数据库本身,外部调用仅仅掉用这个SQL集合就可以实现一系列操作,我们把这个集合叫做存储过程。
特点:
1:封装,复用 2:可以接受参数,返回结果 3:减少网络开支
创建
create procedure procedure_name ([参数])
begin
存储体语句;
end;使用
call procedure_name([参数]);查询
# 根据主机名查看
select * from information_schema.ROUTINES
where ROUTINE_SCHEMA = '数据库名称';
# 根据存储过程名查看
show create procedure p1;删除
drop procedure if exists procedure_name;变量
系统变量
由mysql数据库创建,不是由用户定义的,属于服务器层面,分为全局变量【global】和回话变量【session】用 @@变量名 表示;
查看系统变量
show [global | session(默认)] variables [like ...];
# 也可以指定变量查找
select @@ [global | session] 系统变量名;设置系统变量
set [@@] [global | session] 系统变量名 = 值;用户变量
用户变量不需要提前声明,在使用的时候直接用 @变量名 就可以使用,作用域为当前会话
赋值
# 方法一
set @var_name [:]= 值 [,@var_name = 值];
# 方法二
select @var_name [:]= 值 [,@var_name = 值];
# 方法三
select 字段名 into @Var_name from table_name;使用
select @var_name [,@var_name];如果使用了一个没有初始化的变量,就会返回一个负值
局部变量
局部变量需要声明才能使用,生命周期在一段 begin和end中。
声明:
declare var_name 变量类型 [default];default:指定变量默认值;
赋值
# 方法一
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;参数

示例
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
结构
# 结构一:通过比较值是否相等,判断执行哪一条语句
case 值
when 值 SQL
[when 值 SQL]
[else SQL]
end case;
# 结构一:通过判断每条分支表达式的值,来决定执行哪一条语句
case
when 表达式 SQL
[when 表达式 SQL]
[else SQL]
end case;循环
while
while别看长得像do-while 其实就是while
while 条件 do
SQL...
end while;repeat
其实是do-while....不对!repeat是满足条件就退出,而不是满足条件就继续执行!!!
repeat
SQL...
until 条件
end repeat;loop + leave + iterate
loop:可以理解成简单的无限循环 leave:break iterate:continue
[标记名:]loop
SQL...
end loop [标记名];# 离开当前标记
leave 标记名
# 执行下一次标记
iterate 标记名游标 cursor
从目前看来,存储过程所返回的变量只有SQL基础的数据类型所创建的变量,但是很多时候,我们拿到的数据并不是单个的数据,通常作为一个表出现,这就出现了多对一的矛盾,为了解决这个矛盾,出现了游标
声明
declare 游标名称 cursor for 查询语句;注意,声明游标语句必须存在在变量之后
开启
open 游标名称获取
fetch 游标名称 into 变量 [,变量];关闭
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 类型
create function 存储函数名称(参数列表)
returns 返回值类型 [characteristic]
begin
SQL...
return 返回值;
end;characteristic: deterministic:相同的数据会产生相同的结果 no sql:不包含SQL语句 reads sql data:包含读取数据的语句,但不包含写入数据的语句