函数
函数:将一段代码封装到一个结构中,在需要执行代码块的时候,调用结构执行即可(代码复用)
函数分为两类:系统函数和自定义函数
系统函数:
系统定义好的函数,直接调用即可。任何函数都有返回值,因此函数的调用是通过select调用。
mysql中字符串基本操作单位(最常见的是字符)
常见的系统函数:
substring:字符串截取
-- 创建两个变量
set @cn = '世界你好';
set @en = 'hello world';
-- 字符串截取
select substring(@cn,1,1);
select substring(@en,1,1);
char_length:字符长度
length:字节长度
-- 字符串长度
select char_length(@cn),char_length(@en),length(@cn),length(@en);
instr:判断字符串是否在某一个具体的字符串中存在,存在返回位置。
-- 字符串查找
select instr(@cn,'界'),instr(@cn,'啦啦'),instr(@en,'ld'); -- 0代表找不到对应字符串
lpad:左填充,将字符串按照某个指定的填充方式填充到指定长度(字符)
-- 字符串填充
select lpad(@cn,10,'欢迎'),lpad(@en,10,'hello');
insert:替换,找到目标位置指定长度的字符串替换成目标字符串
-- 字符串替换
select insert(@en,3,3,'y'),@en;
strcmp:字符串比较
-- 创建变量
set @f = 'hello';
set @s = 'hey';
set @t = 'HEY';
-- 字符串比较
select strcmp(@f,@s),strcmp(@s,@t),strcmp(@s,@f);
自定义函数:
函数要素:函数名,参数列表(形参和实参),返回值,函数体(作用域)
创建函数:
创建语法:
create function 函数名([形参列表]) returns 数据类型 -- 规定要返回的数据
begin
-- 函数体,返回值:return类型(指定数据类型)
end
语法:select 函数名([实参列表]);
-- 调用函数
select display1();
查看函数
查看所有函数:show function status[like 'pattern'];
-- 查看所有函数
show function status\G
函数属于指定数据库,只有在对应的数据库下可以使用
查看函数的创建语句:
show create function display1\G
修改函数&删除函数:
函数只能先删除再新增。
函数参数:
函数的参数:定义时的参数叫形参,调用时的参数叫实参(实参可以是数值也可以是变量)
形参:要求必须指定数据类型
function 函数名(形参名字 字段类型) returns 数据类型
-- 创建函数:计算1-指定数之间的和
delimiter $$
create function display1(int_1 int) returns int
begin
-- 定义条件变量
set @i = 1; -- @定义的是全局变量,没有的可以理解为局部变量
set @res = 0; -- 保存求和结果
-- 循环求和
while @i <= int_1 do
-- 求和,任何变量修改要使用set关键字
-- mysql中没有+=和++这种运算符
set @res = @res + @i;
-- 修改循环变量
set @i = @i + 1;
end while;
-- 返回值
return @res;
end
$$ -- 函数结束
delimiter ;
在函数内部使用@定义的变量在函数外部也可以访问
作用域:
mysql中的作用域与js中的作用域完全一样
全局变量可以在任何地方使用,局部变量只能在函数内部使用。
全局变量:使用set关键字定义,使用@符号标识
局部变量:使用declare关键字声明,没有@符号,所有的局部变量的声明必须在函数体开始
-- 创建函数:计算1-指定数之间的和,5的倍数不加
delimiter $$
create function display2(int_1 int) returns int
begin
-- 声明变量:循环变量局部变量
declare i int default 1;
declare res int default 0; -- 定义局部变量可以有属性
-- 循环判断
mywhile:while i <= int_1 do
-- 相加:判断
if i % 5 = 0 then -- mysql中=是表示比较的意思,:=代表赋值
-- 修改循环条件,这里必须加循环条件不然当5的倍数进来会变成死循环
set i = i + 1;
-- 不符合条件循环直接重新来
iterate mywhile;
-- iterate相当于其他语言中的continue用法结束本次循环开始下一次循环,mywhile是循环的名字
end if;
-- 相加
set res = res + i;
-- 修改循环条件
set i = i + 1;
end while;
-- 返回结果
return res;
end
$$ -- 函数结束
delimiter ;
-- 调用查看函数结果
select display2(10);
存储过程:
存储过程简称过程,procedure,是一种用来处理数据的方式,存储过程是一种没有返回值的函数
创建过程:
create procedure 过程名字([参数列表])
begin
-- 过程体
end
-- 创建存储过程
create procedure pro1()
-- 这里只是一个例子,实际上查询一个数据再创建一个过程就没有必要了
select * from my_student;
查看过程:
函数的查看方式完全适用于过程,关键字换成procedure
查看所有过程:show procedure status[like 'pattern'];
查看过程创建语句:show create procedure 过程名字
调用过程:
过程没有返回值不可以使用select访问。
过程有一个专门的调用关键字:call
-- 调用过程
call pro1();
修改过程&删除过程
过程只可以先删除再新增。语法:
drop procedure 过程名字;
参数类型:
函数的参数需要数据类型指定,过程闭比函数更加严格,过程有自己的类型限定:三种类型
in:数据只是从外部传入给内部使用(值传递),可以是数值也可以是变量。
out:只允许过程内部使用(不用外部数据),给外部使用的(引用传递:外部的数据会被先清空才会进入到内部)只能是变量。
inout:外部可以在内部使用,内部修改也可以给外部使用,典型的引用传递,只能传递变量。
基本使用:create procedure 过程名字(in/out/inout 形参名字 数据类型)
-- 过程参数
delimiter $$
create procedure pro2(in int_1 int,out int_2 int,inout int_3 int)
begin
-- 先查看三个变量
select int_1,int_2,int_3; -- int_2的值一定是NULL,因为外部数据进入内部首先被清空
end
$$
delimiter ;
正确的调用:传入变量
-- 设置变量,set关键字已经告知mysql=号在这里是赋值的意思,所以在这里=和:=均可
set @int_1 := 1;
set @int_2 := 2;
set @int_3 := 3;
select @int_1,@int_2,@int_3;
call pro2(@int_1,@int_2,@int_3);
select @int_1,@int_2,@int_3;
存储过程对于变量的操作(返回)是滞后的,是在存储过程结束的时候,才会重新将内部修改的值赋值给外部传入的全局变量。
-- 过程参数
delimiter $$
create procedure pro3(in int_1 int,out int_2 int,inout int_3 int)
begin
-- 先查看三个变量,三个当前是局部变量
select int_1,int_2,int_3; -- int_2的值一定是NULL,因为外部数据进入内部首先被清空
-- 修改局部变量
set int_1 = 10;
set int_2 = 100;
set int_3 = 1000;
-- 查看局部变量
select int_1,int_2,int_3;
-- 查看全局变量
select @int_1,@int_2,@int_3;
-- 修改全局变量
set @int_1 = 'a';
set @int_2 = 'b';
set @int_3 = 'c';
-- 查看全局变量
select @int_1,@int_2,@int_3;
end
$$
delimiter ;
测试:
-- 设置变量
set @int_1 := 1;
set @int_2 := 2;
set @int_3 := 3;
call pro3(@int_1,@int_2,@int_3);