文章目录
- 变量
- 系统变量
- 全局变量
- 会话变量
- 自定义变量
- 用户变量
- 局部变量
- 对比用户变量和局部变量
- 存储过程
- 创建语法
- 调用语法
- 存储过程的创建与调用
- 存储过程的练习
- 存储过程的删除
- 存储过程的查看
- 存储过程的练习案例
- 函数
- 函数和存储过程的区别
- 函数创建和调用的语法
- 查看函数
- 删除函数
- 练习函数的使用
- 流程控制结构
- 分支结构
- if结构
- 循环结构
- while
- 循环结构的演示
- 循环结构总结
- 流程控制经典案例
- 复习变量,存储过程和函数,流程控制结构(分支结构,循环结构)
变量
- 分类
- 系统变量:系统提供的
- 全局变量
- 会话变量
- 自定义变量
- 用户变量
- 局部变量
系统变量
- 说明:变量由系统提供,不是用户定义,属于服务器层面.
- 注意:如果是全局级别,则需要加global,如果是会话级别,则需要加session,如果不写,则默认session.
- 使用的语法:
- 查看所有的系统变量:show session/global variables;session可省略
- 查看满足条件的部分系统变量:show global/session variables like ‘%char%’;
- 查看指定的某个系统变量的值:select @@global/session.系统变量名;
- 为某个系统变量赋值:set global/session 系统变量名 = 值; 或 set @@global/session.系统变量名=值;
全局变量
- 作用域:服务器每次启动将为所有的全局变量赋初始值,针对于所有的会话(连接)有效,但不能跨域重启.
演示全局变量
# 查看所有的全局变量
show global variables;
# 查看部分的全局变量
show global variables like '%char%';
# 查看指定的全局变量的值
select @@global.autocommit;
select @@global.tx_isolation;
# 为某个指定的全局变量赋值
set @@global.autocommit=0;
会话变量
- 作用域:仅针对于当前会话(连接)有效
# 查看所有的会话变量
show session variables;#session可以省略
# 查看部分的会话变量
show variables like '%char%';
show session variables like '%char%';
# 查看指定的某个会话变量
select @@tx_isolation;
select @@session.tx_isolation;
# 为某个会话变量赋值
# 方式一:
set @@session.tx_isolation='read-uncommitted';
# 方式二:
set session tx_isolation ='read-committed';
自定义变量
- 说明:变量是用户自定义的,不是由系统
- 使用步骤:声明,赋值,使用(查看,比较,运算等)
用户变量
- 作用域:针对于当前会话(连接) 有效,同于系统变量中会话变量的作用域
- 应用在任何地方,也就是begin end里面或begin end外面
# 赋值的操作符: =或:=
# 声明并初始化
set @用户变量名=值;
set @用户变量名:=值;
select @用户变量名:=值;
# 赋值(更新用户变量的值
# 方式一:通过set或select
set @用户变量名=值;
set @用户变量名:=值;
select @用户变量名:=值;
set @name='john';
set @name=100;
set @count=1;
# 方式二:通过select into
select 字段 into @变量名 from 表;
select count(*) into @count from 表;
# 使用(查看用户变量的值)
select @用户变量名;
select @count;
)
局部变量
- 作用域:仅仅在定义它的begin end中有效
- 应用在begin end中的第一句话.
# 声明
declare 变量名 类型;
declare 变量名 类型 default 值;
# 赋值
# 方式一:通过set或select
set 局部变量名=值;
set 局部变量名:=值;
select @局部变量名:=值;
# 方式二:通过select into
select 字段 into 局部变量名 from 表;
# 使用
select 局部变量名;
对比用户变量和局部变量
- 作用域:用户变量(针对当前会话),局部变量(begin end中的)
- 定义和使用的位置:用户变量(会话中的任何地方),局部变量(只能在begin end中,且为第一句话)
- 语法:用户变量(需要加上@符号,不用限定类型),局部变量(一般不用加@符号,需要限定类型)
# 声明两个变量并赋初始值,求和,并打印
# 用户变量
set @m=1;
set @n=2;
set @sum=@m+@n;
select @sum;
# 局部变量(报错,没有在begin end中)
declare m int default 1;
declare n int default 2;
declare sum int;
set sum=m+n;
select sum;
存储过程
- 存储过程:含义:一组预先编译好的sql语句的集合,理解成批处理语句
- 好处:(简单,安全,性能更高)
- 提高了代码的重用性
- 简化操作
- 减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率.
- 编写存储过程需要有很强大的经验.
创建语法
create procedure 存储过程名(参数列表)
begin
存储过程体(一组合法的sql语句)
end
- 注意:
- 参数列表包含三部分:参数模式 参数名 参数类型
- 参数模式:
- in:进,该参数可以作为输入,也就是说该参数需要调用方传入值
- out:出,该参数可以作为输出,也就是该参数可以作为返回值
- inout:进出,该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,又可以返回值.
- 如果存储过程体仅仅只有一句话,begin end可以省略
- 存储过程体中的每条sql语句的结尾要求必须加分号.
- 存储过程的结尾可以使用delimiter重新设置
# 举例
in stuname varchar(20)
delimiter 结束标记
delimiter $
调用语法
call 存储过程名(实参列表);
存储过程的创建与调用
# 1.空参列表
# 插入到admin表中五条记录(一般插入上万条)
select * from admin;
delimiter $
create procedure myp1()
begin
insert into admin(username,'password') values('john1','0000'),('joly','0000'),('joer','0000'),('jack','0000'),('tom','0000');
end $
# 调用
call myp1()$
# 2.创建带in模式参数的存储过程
# 创建存储过程实现:根据女生名,查询对应的男生信息
delimiter $
create procedure myp2(in beautyname varchar(20))
begin
select bo.* from boys bo right join beauty b on bo.id=b.id where b.name=beautyname;
end $
# 调用
call myp2('团子')$
# 创建存储过程,实现用户是否登录成功
delimiter $
create procedure myp3(in username varchar(20),in password varchar(20))
begin
declare result int default 0;# 声明并初始化变量
select count(*) into result # 赋值
from admin
where admin.username=username and admin.password=password;
select if(result>0,'成功','失败');# 使用
end $
# 调用
call myp3('张飞','8888')$
# 3.创建带out模式的存储过程
# 单个返回举例:根据女生名,返回对应的男生名
create procedure myp5(in beautyname varchar(20),out boyname varchar(20))
begin
select bo.name into boyname from boys bo inner join beauty b on bo.id=b.id where b.name=beautyname;
end$
# 调用
set @bname$
call myp5('小昭',@bname)$
select @bname$
# 返回多个:根据女生名,返回对应的男生名和魅力值
create procedure myp6(in beautyname varchar(20),out boyname varchar(20),out userCP int)
begin
select bo.name,bo.userCP into boyname,userCP from boys bo inner join beauty b on bo.id=b.id where b.name=beautyname;
end$
# 调用
call myp6('小昭',@bname,@userCP)$
select @bname,@userCP$
# 4.创建带inout模式参数的存储过程
# 传入a和b两个值,最终a和b都翻倍并返回
create procedure myp8(inout a int,inout b int)
begin
set a=a*2;
set b=b*2;
end$
# 调用
# 定义两个用户变量
set @m=10$
set @n=20$
call myp8(@m,@n)$
select @m,@n$
存储过程的练习
存储过程的删除
- 一次只能删除一个.
- 语法:
drop procedure 存储过程名
存储过程的查看
- 查看存储过程的信息,结构
show create procedure 存储过程名;
存储过程的练习案例
函数
- 含义:一组预先编译好的sql语句的集合,理解成批处理语句
- 好处:(简单,安全,性能更高)
- 提高了代码的重用性
- 简化操作
- 减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率.
函数和存储过程的区别
- 存储过程:可以有0个返回,也可以有多个返回,适合做批量插入,批量更新
- 函数:有且仅有1个返回,适合做处理数据后返回一个结果
函数创建和调用的语法
- 创建语法
create function 函数名(参数列表) returns 返回类型
begin
函数体
end
# 注意: 参数列表包含两部分:参数名 参数类型
# 函数体:肯定会有return语句,如果没有会报错,
# 如果return语句没有放在函数体的最后也不报错,但不建议
return 值;
# 函数体中仅有一句话时,则可以省略begin end
# 使用delimiter语句设置结束标记
- 调用语法
select 函数名(参数列表);
- 练习
# 无参有返回
# 返回公司的员工个数
create function myf1() returns int
begin
declare c int default 0;#定义变量
select count(*) into c#给变量赋值
from 表名;
return c;
end$
select myf1()$
# 有参有返回
# 根据员工名,返回他的工资
create function myf2(empname varchar(20)) returns double
begin
set @sal=0;#定义用户变量
select salary into @sal#赋值
from 表名
where last_name=empname;
return @sal;
end$
select myf2('k_ing')$
#根据部门名,返回该部门的平均工资
create function myf3(deptname varchar(20)) returns double
begin
declare sal double;
select avg(salary) into sal
from employees e
inner join departments d on e.id=d.id
where d.dname=deptname;
return sal;
end$
select myf3('IT')$
查看函数
show create function myf3;
删除函数
drop function myf3;
练习函数的使用
# 创建函数,实现传入两个float,返回二者之和
create function test_fun1(num1 float,num2 float) returns float
begin
declare sum float default 0;
set sum=num1+sum2;
return sum;
end$
select test_fun1(1,2)$
流程控制结构
- 顺序结构:程序从上往下依次执行
- 分支结构:程序从两条或多条路径中选择一条去执行
- 循环结构:程序在满足一定条件的基础上,重复执行一段代码
分支结构
- if函数
- 功能:实现简单的双分支
- 语法:
if(表达式1,表达式2,表达式3)
执行顺序,如果表达式1成立,则if函数返回表达式2的值,否则返回表达式3的值. - 应用:任何地方
- case结构
- 情况1 :类似于java中的switch语句,一般用于实现等值判断
- 语法:
case 变量/表达式/字段
when 要判断的值 then 返回的值1或语句1 ;
when 要判断的值 then 返回的值2或语句2;
…
else 要返回的值n或语句n;
end case; - 情况2: 类似于java中的多重if语句,一般用于实现区间判断
- 语法:
case
when 要判断的条件1 then 返回的值1或语句1;
when 要判断的条件2 then 返回的值2或语句2;
…
else 要返回的值n或语句n;
end case; - case结构特点:
- 可以做为表达式,嵌套在其他语句中使用,可以放在任何地方,begin end 中或begin end 的外面
- 可以作为独立的语句去使用,只能放在begin end中
- 如果when中的值满足或条件成立,则执行对应的then后面的语句,并且结束case
- 如果不满足,则执行else中的语句或值
- else可以省略,如果else省略了,并且所有then条件都不满足,则返回null
- case结构作为表达式
- case结构作为独立的语句
- 练习case结构
# 创建存储过程,根据传入的成绩,来显示等级,比如传入的成绩:90-100显示A,80-90显示B,60-80显示C,否则显示D
delimiter $
create procedure test_case(in score int)
begin
case
when score>=90 and score <=100 then select 'A';
when score>=80 then select 'B';
when score>=60 then select 'C';
else select 'D';
end case;
end$
call test_case(95)$
if结构
- 功能:实现多重分支
- 语法:
if 条件1 then 语句1;
elseif 条件2 then 语句2;
...
else 语句n;#最后这句可以省略
end if;
- 应用场合:应用在begin end中
# 案例
# 创建存储过程,根据传入的成绩,来显示等级,比如传入的成绩:90-100返回A,80-90返回B,60-80返回C,否则返回D
delimiter $
create function test_if(score int) returns char
begin
if score>=90 and score<=100 then return 'A';
elseif score>=80 then return 'B';
elseif score>=60 then return 'C';
else return 'D';
end if;
end $
循环结构
- 分类:while,loop,repeat
- 循环控制:
- iterate类似于 continue,继续,结束本次循环,继续下一次
- leave类似于break,跳出,结束当前所在的循环
while
- 语法:
标签:while 循环条件 do
循环体
end while 标签;
- loop语法:
标签:loop
循环体;
end loop 标签;
# 可以用来模拟简单的死循环,要跳出需要搭配leave
- repeat语法:
标签:repeat
循环体;
until 结束循环的条件
end repeat 标签;
# 类似于dowhile,先执行一次
循环结构的演示
# 没有添加循环控制语句
# 批量插入,根据次数插入到admin表中多条记录
create procedure pro_while1(in insertCount int)
begin
declare i int default 1;
while i<=insertCount do
insert into admin(username,`password`)values(count('rose',i),'666');
set i=i+1;
end while;
end $
call pro_while1(100)$
# 添加leave语句
# 批量插入,根据次数插入到admin表中多条记录,如果次数>20则停止.
truncate table admin$
drop procedure test_while1$
create procedure test_while1(in insertCount int)
begin
declare i int default 1;
a:while i<=insertCount do
insert into admin(username,`password`)values(count('xiaoli',i),0000);
if i>=20 then leave a;
end if;
set i=i+1;
end while a;
end$
call test_while1(100)$
# 添加iterate语句
# 批量插入,根据次数插入到admin表中多条记录,只插入偶数次
truncate table admin$
drop procedure test_while1$
create procedure test_while1(in insertCount int)
begin
declare i int default 0;
a:while i<=insertCount do
set i=i+1;
if mod(i,2)!=0 then iterate a;
end if;
insert into admin(username,`password`)values(count('xiaoli',i),0000);
end while a;
end$
call test_while1(100)$
循环结构总结
流程控制经典案例
复习变量,存储过程和函数,流程控制结构(分支结构,循环结构)