存储过程和函数
存储过程
存储过程和函数:类似于方法,
好处:
提高代码的重用性, 简化操作
减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
存储过程:一组预先编译号的sql语句的集合,理解成批处理语言
注意:
参数列表包含三部分:参数模式,参数名,参数类型
参数模式:
in:该参数修饰的参数可以作为输入,需要传值
out:该参数可以作为输出,也就是该参数可以作为返回值
inout:该参数既可以作为输入,又可以作为输出,也就是既需传入,又可返回值。
若存储过程仅仅只有一句话,begin end可以省略
存储过程体重的每条sql语句的结尾要求必须加分号。存储过程的结尾可以使用delimiter重新设置
delimiter 结束标记
一:创建
create procedure 存储过程名(参数列表){
begin
存储过程体(一组合法有效的sql语句)
end
}
二:调用
call 存储过程名(实参列表);
1.空参列表
case1:插入admin表中五条数据
delimiter $
create procedure myp1()
begin
insert into admin (username,‘password’) values (‘jone’,‘000’), (‘jsde’,‘000’), (‘jofse’,‘000’);
end $
call myp1()$
select * from admin$
2.in模式参数的存储过程
case2:根据女神名来查询对于的男神信息
create procedure myp2(in beautyname varchar(20))
begin
select bo.* from boys bo right join beauty b on bo.id=b.boyfriend_id where b.name=beautyname;
end $
set names gbk;
call myp2(‘柳岩’)$
case3:创建存储过程实现,用户是否成功登陆
create procedure myp5(in username varchar(20),password int)
begin
declare state int default 0;
select count(*) into state from admin where admin.username=username and admin.password = password;
select if(state >0,“成功”,“失败”);
end$
call myp5(“abc”,1234)$
3.out模式参数的存储过程
case4:根据女神名,返回对于的男神名
create procedure myp10(in name varchar(20),out boyName varchar(20))
begin
select bo.boyName into boyName from beauty b INNER JOIN boys bo on b.boyfriend_id = bo.id where b.name
=name;
end$
call myp10(“热巴”,@bname);
case5:根据女神名,返回对于的男神名和其魅力值
create procedure myp13(in beautyName VARCHAR(20),out boyName VARCHAR(20),out userCP int)
begin
select bo.boyName,bo.userCP into boyName,userCP from beauty b INNER JOIN boys bo on bo.id = b.boyfriend_id where b.name = “热巴”;
end$
call myp10(“热巴”,@bname,@userCP);
4.创建intout模式参数的存储过程
case5:传入a和b两个值,最终a和b都翻倍并返回
create procedure myp20(inout a int,inout b int)
begin
set a = a2;
set b = b2;
end$
set @m=10$
set @n=20$
call myp20(@m,@n)$
5.存储工程的删除
语法:
drop procedure 存储过程名 只能一次删除一个
6.存储过程的查看
语法:
show create procedure 存储过程名;
很少修改存储过程,存储过程快是无法修改的,若要该,就删除再重建
7.作业
case1:创建存储过程实现传入用户名和密码,插入到admin中
create procedure cast_1(in username varchar(20),in password VARCHAR(20))
begin
insert into admin value(null,username,password);
end$
call cast_1(“ming”,“zhe”)$
case2:创建存储过程或函数实现传入女神编号,返回女神名称和女神电话
create procedure cast_2(in beautyid int,out name VARCHAR(20),out phone VARCHAR(20))
begin
select bo.name,bo.phone into name,phone from beauty bo where bo.id = beautyid;
end$
call cast_2(2,@m,@n)$
select @m,@n$
case3:创建存储过程或函数实现传入两个女神生日,返回大小
create procedure cast_3(in date1 datetime,in date2 datetime,out days int)
begin
select datediff(date1,date2) into days;
end$
call cast_3("1937/2/2","1921/1/1",@days)
case4:穿件存储过程或函数实现出入一个日期,合适化为xx年xx月xx日并返回
create procedure cast_4(in date1 datetime, out date2 varchar(20))
begin
select DATE_FORMAT(date1," %Y年%c月%d日") into date2;
end$
call cast_4("1997/2/2",@date2)$
case5:创建存储过程或函数实现传入女神名称,返回女神and男神 格式化的字符串
create procedure cast_5(in beautyname varchar(20),out beautyandboy varchar(20))
begin
select CONCAT(b.name,"and",bo.boyName) into beautyandboy from beauty b INNER JOIN boys bo on bo.id = b.boyfriend_id where b.name = beautyname;
end$
call cast_5("热巴",@names)$
case6:创建存储过程或函数,根据传入的条目数和起始索引,查询beauty表的记录
create procedure cast_6(in startindex int,in numbers int)
begin
select * from beauty limit startindex,numbers;
end$
call cast_6(2,4)$
函数
存储过程:可以有0个返回,也可以有多个返回 批量插入 批量更新
函数:有且仅有一个返回 适合做处理数据后返回一个结果
语法:
create function 函数名(参数列表) returns 返回类型
begin
函数体
end
注意:
1.参数列表 包含两部分:参数名 参数类型
2. 函数体:肯定会有return语句,如果没有会报错,如果return语句没有放在函数体的最后也不会报错,但不建议
3.函数体中仅有一句话则可以省略begin end
4.使用delimiter语句设置结束标记 delimiter $
调用语法:
select 函数名(参数列表)
执行完函数体的语句 并返回返回值
错误1418:
原因是因为我们开启了bin-log
show variables like “log_bin_trust_function_creators”;
set global log_bin_trust_function_creators = 1;
案例:
1.无参有返回
case1:返回公司的员工个数
create function myf1() returns int
begin
declare ac int;
select count(*) into ac from employees;
return ac;
end$
select myf1();
2.有参有返回
case2:根据员工名返回工资
create function myf2(employname varchar(20)) RETURNS double
begin
declare money double default 0;
select salary into money from employees where last_name = employname limit 1;
return money;
end$
select myf2('K_ing')$
case3:根据部门名返回该部门的平均工资
create function myf3(department_name varchar(20)) RETURNS double
begin
declare money double default 0;
select avg(salary) into money from departments d inner join employees e on e.department_id = d.department_id where d.department_name = department_name;
return money;
end$
select myf3('Adm')$
case4: 传入两个float,返回两者之和;
create function myf4(num_1 float,num_2 float) returns float
begin
declare num_3 float default 0;
set num_3 = num_1 + num_2;
return num_3;
end$
select myf4(1.2,2.2)
查看:
show create function myf3;
删除:
drop function myf3;
流程控制结构
流程控制
顺序结构:
程序从上向下依次遵循
分支结构:
程序从两条或多条路径中选择一条去执行
循环结构:
程序在满足一定的条件基础之上,重复执行一段代码
分支结构:
1.if函数
功能:
实现简单的双分支
语法:
select if(表达式一,表达式二,表达式三)
执行顺序:
如果表达式一成立,则返回表达式二的值,不然返回表达式三的值
应用:
任何地方
2.case结构
语法一:
case 变量|表达式|字段
when 要判断的值 then 返回的值或语句,
when 要判断的值 then 返回的值或语句,
when 要判断的值 then 返回的值或语句,
…
else 要返回的值n或语句
end
语法二:
case
when 要判断的条件 then 返回的值或语句,
when 要判断的条件 then 返回的值或语句,
when 要判断的条件 then 返回的值或语句,
…
else 要返回的值n或语句
end
若为语句则,逗号要改为分号
特点:
可以作为表达式,嵌套在其他语句中使用,可以放在任何地方,bigin end 中或 bigin end 外面
可以作为独立的语句去使用,只能放在bigin end中;
满足条件后,执行后会跳出
若省略else,且条件都不满足返回null
案例:
case1:根据传进的参数来显示等级,90-100A 80-90B 60-80C 负责为D
3.if结构
功能:实现多重分支
语法:
if 条件1 then 语句1;
elseif 条件 then 语句;
else 语句;
end if;
应用:
begin end中
案例:
case2:根据传进的参数来显示等级,90-100A 80-90B 60-80C 负责为D 返回级别
循环结构:
分类:
while
loop
repeat
循环控制:
iterate 类似于continue
leave 类似于break
1.while
语法:
【标签:】while 循环条件 do
循环体;
end while【标签】;
先判断后执行
2.loop
语法:
【标签:】 loop
循环体
end loop 【标签】;
可以用来模拟死循环,
3.repeat
语法;
【标签:】repeat
循环体
until 结束循环条件
end repeat 【标签】;
先执行,在判断是否满足结束条件
这三种循环都在 begin end中
4.案例
case1 批量插入,根据次数插入到admin表多条记录
create procedure myp14(in num_1 int)
begin
declare i int default 0;
while i < num_1 do
insert into admin value(null,concat("aaa",i),"bbb");
set i = i +1;
end while;
end$
call myp14(5)$
case2 批量插入 ,若次数>20则停止
create procedure myp15()
begin
declare i int default 0;
while i < 20 do
insert into admin value(null,concat("ccc",i),"bbb");
set i = i +1;
end while;
end$
call myp15()$
case3 批量插入,根据次数插入admin表中多条记录,只插入偶数次
create procedure myp16(in num_1 int)
begin
declare i int default 0;
a:while i < num_1 do
set i = i +1;
if mod(i,2) != 0 then iterate a;
end if;
insert into admin value(null,concat("ddd",i),"bbb");
end while a;
end$
call myp16(20)$