15天学习MySQL计划-存储过程/变量/判断/循环/游标/函数/触发器(进阶篇)-第九天
存储过程
1.介绍
存储过程是事先经过编译并存储是数据库中的一段SQL语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。
存储过程思路上很简单,就是数据库SQL语言层面的代码封装与重用。
特点
- 封装,复用
- 可以接受参数,也可以返回数据
- 减少网络交互,效率提升
2.存储过程语法
1.创建
注意:在命令行中,执行创建存储过程的SQL时,需要通过关键字delimiter指定SQL语句的结束符
delimiter 结束符(默认为;)
create procedure 存储过程名称([参数列表])
begin
--SQL列表;
end;
2.调用
call 名称 ([参数]);
3.查看
select * from information_schema.routines where routine_schema = 'xxx' --查询指定数据库的存储过程及状态信息
show create procedure 存储过程名称; --查询某个存储过程的定义
4.删除
drop procedure [if exists] 存储过程名称;
3.变量
系统变量是MySQL服务器提供的,不是用户定义的,属于服务器层面。分为全局变量(GLOBAL),会话变量(SESSION)。
1.查看系统变量
show [session|global] variables; --查看所有系统变量
show [session|global] variables like '%'; --可以通过like模糊匹配方式查找变量
select @@[session|global] 系统变量名; --查看指定变量值
2.设置系统变量
set [session|global] 系统变量名 = 值;
set @@[session | global] 系统变量名 = 值;
注意:
- 如果没有指定session/global,默认是session,会话变量。
- MySQL服务重新启动之后,所有设置的全局参数会失效,要不想失效,可以在/etc/my.cnf中配置
3.用户变量
用户定义变量是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用“@变量名”就可以。其作用域为当前连接。
赋值(在变量名前加一个@,两个为系统变量)
set @var_name = expr [,@var_name=expr];
set @var_name := expr [,@var_name:=expr];
select 字段名 into @变量名 from 表名;
使用
select @var_name;
注意:
用户定义的变量无需对其进行声明或初始化,只不过获取到的值为NULL。
4.局部变量
局部变量是根据需要定义的局部生效的变量,访问之前,需要declare声明。可用作存储内的局部变量和输入参数,局部变量的范围是在其内声明的begin…end块中。
1.声明
declare 变量名 变量类型 [default ...];
变量类型:int,bigint,char,varchar,date,time等。
2.赋值
set 变量名=值;
select 字段名 into 变量名 from 表名;
4.判断/循环/多分支/游标
1.if判断
语法:
if 条件1 then
...
elseif 条件2 then --可选
...
else --可选
...
end if;
例子:
mysql> delimiter $
mysql> create procedure test()
begin
declare sal int default 80;
declare result varchar(10);
if sal>=90 then
set result='A';
elseif sal >=80 then
set result='B';
else
set result='C';
end if;
select result;
end;$
mysql> delimiter ;
mysql> call test;
2.参数
类型 | 含义 | 备注 |
---|---|---|
in | 该类参数作为输入,也就是需要调用时传入值 | 默认 |
out | 该类参数作为输出,也就是该参数可以作为返回值 | |
inout | 既可以作为输入参数,也可以作为输出参数 | 需要定义变量,进入参数之后进行加工,然后再进行返回 |
例子1:
mysql> delimiter $
mysql> create procedure test1(in sal int,out result varchar(10))
begin
if sal>=90 then
set result='A';
elseif sal >=80 then
set result='B';
else
set result='C';
end if;
end;$
mysql> delimiter ;
mysql> call test1(100,@result);
mysql> select @result;
+---------+
| @result |
+---------+
| A |
+---------+
1 row in set (0.00 sec)
例子2:
mysql> delimiter $
mysql> create procedure test2(inout sal int)
begin set sal=sal*0.5;
end$
mysql> set @sal=100;
mysql> call test2(@sal);
mysql> select @sal$
+------+
| @sal |
+------+
| 50 |
+------+
1 row in set (0.00 sec)
3.流程控制(case)
语法一:
case case_value
when when_value1 then statement_list1
[when when_value2 then statement_list2]
[else statement_list]
end case;
语法二:
case case_value
when search_condition then statement_list1
[when search_condition then statement_list2]
[else statement_list]
end case;
create procedure quarter(in num int)
begin
case
when num<=3 then
select '1';
when num<=6 then
select '2';
when num<=9 then
select '3';
when num<=12 then
select '4';
else
select 'error';
end case;
end$
4.循环结构
1.while
while循环是有条件的循环控制语句,满足条件后,再执行循环体中的SQL语句,具体语法为:
#先判定条件,如果条件为true,则执行逻辑,否则,不执行逻辑
while 条件 do
SQL逻辑
end while;
例子n数的总分:
mysql> delimiter $
mysql> create procedure test1(in num int)
begin
declare sum int default 0;
while num>0 do
set sum=sum+num;
set num=num-1;
end while;
select sum;
end$
mysql> delimiter ;
mysql> call test1(10);
+------+
| sum |
+------+
| 55 |
+------+
1 row in set (0.00 sec)
2.repeat
repeat是条件的循环控制逻辑,先循环一次,然后判定逻辑是否满足,如果满足则退出,如果不满足,则进行下一次循环
repeat
SQL逻辑
until 条件
end repeat;
例子n数的总分:
mysql> delimiter $
mysql> create procedure test2(in num int)
begin
declare sum int default 0;
repeat
set sum=sum+num;
set num=num-1;
until num<=0
end repeat;
select sum;
end$
mysql> delimiter ;
mysql> call test2(10);
+------+
| sum |
+------+
| 55 |
+------+
1 row in set (0.00 sec)
3.loop
loop实现简单的循环,如果不在SQL逻辑中增加退出循环的条件,可以用其实现简单的死循环。loop可以配合一下两个语句使用:
- leave:配合循环使用,退出循环。
- iterate:必须用在循环中,作用是跳过当前循环剩下的语句,直接进入下一次循环。
循环名:loop
SQL逻辑
leave 循环名
iterate 循环名
end loop 循环名;
例子求0-n的偶数之和
create procedure test3 (in num int)
begin
declare sum int default 0;
test3:loop
if num<=0 then
leave test3;
end if;
if num%2=0 then
set sum=sum+num;
end if;
set num=num-1;
end loop test3;
select sum;
end;
call test3(100);
5.游标
游标是用来存储查询结构集的数据类型,在存储过程和函数中可以使用游标对结果集进行循环的处理。游标的使用包括游标的声明,open,fetch和close,其语法分别如下:
1.声明游标
declare 游标名称 cursor for 查询语句;
2.打开游标
open 游标名称;
3.获取游标记录
fetch 游标名称 into 变量[,变量];
4.关闭游标
close 游标名称;
例子:
6.条件处理程序
条件处理程序可以用来定义在流程控制结构执行过程中遇到问题时响应的处理步骤。具体语法为:
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代码的简写
例子:解决游标循环插入表列的情况
5.存储函数
存储函数是有返回值的存储过程,存储函数的参数只能是in(输入)类型的。具体语法如下:
create function 存储函数名称([存储列表])
returns type [characteristic]
begin
--SQL语句
return ...;
end;
characteristic说明:
deterministic:相同的输入参数总是产生相同的结果
no sql:不包含SQL语言
reads sql data:包含读取数据的语句,但不包含写入数据的语句
6.触发器
1.介绍
触发器是与表有关的数据库对象,指在insert/update/delete之前或之后,触发并执行触发器中定义的SQL语句合集。触发器的这种特性可以协助应用在数据库端确保数据的完整性,日志记录,数据校验等操作。
使用别名old和now来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发还只是支持行级触发,不支持语句级别触发。
触发器类型 | new和old |
---|---|
insert型触发器 | new表示将要或者已经新增的数据 |
update型触发器 | old表示修改之前的数据,new表示将要或已经修改后的数据 |
delete型触发器 | old表示将要或者已经删除的数据 |
2.语法
1.创建
create trigger trigger_name
before/after insert/update/delete
on tbl_name for each row --行级触发器
begin
trigger_stmt;
end;
before:在操作之前触发
after:操作之后触发
insert/update/delete:操作类型
2.查看当前数据库的触发器
show triggers;
3.删除
drop trigger [schema_name.]trigger_name; --如果没有指定schema_name,默认为当前数据库
例子:
7.总结
1.视图(view)
- 虚拟存在的表,不保存查询结果,只保存查询的SQL逻辑
- 简单,安全,数据独立
2.存储过程(procedure)
- 事先定义并存储在数据库中的一段SQL语句的集合。
- 减少网络交互,提高性能,封装重用
- 变量,if,case,参数(in/out/inout),while,repeat,loop,cursor,handler
3.存储函数(function)
- 存储函数是有返回值的存储过程,参数类型只能为in类型
- 存储函数可以被存储过程替代
4.触发器(trigger)
- 可以在表数据进行insert,update,delete之前或之后触发
3.删除
drop trigger [schema_name.]trigger_name; --如果没有指定schema_name,默认为当前数据库
例子:
[外链图片转存中…(img-zcykqyUF-1682569241841)]
7.总结
1.视图(view)
- 虚拟存在的表,不保存查询结果,只保存查询的SQL逻辑
- 简单,安全,数据独立
2.存储过程(procedure)
- 事先定义并存储在数据库中的一段SQL语句的集合。
- 减少网络交互,提高性能,封装重用
- 变量,if,case,参数(in/out/inout),while,repeat,loop,cursor,handler
3.存储函数(function)
- 存储函数是有返回值的存储过程,参数类型只能为in类型
- 存储函数可以被存储过程替代
4.触发器(trigger)
- 可以在表数据进行insert,update,delete之前或之后触发
- 保证数据完整性,日志记录,数据校验