MySQL自定义函数的方式
MySQL 有两种方式自定义函数:
- 使用 Function
- 使用 Procedure
MySQL的Function
开启函数功能
在使用之前,必须要确保 MySQL 已经开启了函数功能:
-- 先查看函数功能是否开启:
show variables like '%func%';
-- 若是未开启则:
SET GLOBAL log_bin_trust_function_creators=1;
-- 关闭则是:
SET GLOBAL log_bin_trust_function_creators=0;
使用 Function 的方法
-
function基本语法
-- 修改语句结束符为 $$ ,可以不使用这个方法 delimiter $$ create function fun(value int) returns int begin -- 声明局部变量,必须在函数体最开始声明 declare num int default 0; end -- 语句结束 $$ -- 修改语句结束符为 ; delimiter ;
-
创建一个函数
-------------------- demo1 ------------------- create function myfun2(x int,y int) returns int begin declare a SMALLINT UNSIGNED DEFAULT 10; -- 定义变量 declare b SMALLINT UNSIGNED DEFAULT 20; set a=x; -- 给变量赋值 set b=y; return a+b; -- return 语句 end -------------------- demo2 ------------------- CREATE FUNCTION func1(name1 VARCHAR(10)) RETURNS int BEGIN DECLARE a int DEFAULT 7; SELECT age INTO a -- 把得到的 age 赋值给 a FROM student WHERE `name` = name1; RETURN a; END
-
选中自建的 function 语句,然后运行,函数就会被创建
-
操作自定义函数
-- 使用自定义函数 SELECT myfun2(7,8) as 'val'; SELECT func1('柯基1') as '年龄'; -- 显示 创建自定义函数的语句 show create function myfun2; -- 查看有哪些自定义函数 show function status; -- 修改自定义函数 alert function -- 删除 drop function myfun2;
Function 中的流程语句
-
IF 条件判断
--------------------- 基本语法1 ----------------- if 条件判断 then -- 满足条件时,要执行的代码 end if; --------------------- 基本语法2 ----------------- if 条件判断 then -- 满足条件,要执行的代码 else -- 不满足条件,要执行的代码 if 条件判断 then -- 如果需要 -- 满足条件,要执行的代码 end if; end if;
-
while 循环
--------------------- 基本语法 ----------------- while 条件 do -- 循环执行的代码 end while; --------------------- demo ----------------- CREATE function myfun2(x int,y int) RETURNS int begin declare j int; set j=0; while j<y do insert INTO student values(x+j,'测试',21,'男'); set j=j+1; end while; return j; end
在 MySQL 中没有 continue 和 break,但是有其替代的关键字
iterate
:迭代,类似于continue
,表示结束本次循环,开始下一次循环leave
:离开,类似于break
,直接结束整个循环
--------------------- 基本语法 ----------------- 循环名字:while 条件判断 do if 条件判断 then 循环控制 iterate/leave 循环名字; end if; end while;
-
综合实例
floor(1+190*rand())
:向下取整
substring(str1,floor(1+190*rand()),1)
:剪切字符串
concat('M','y','S','Q','L')
:拼接字符串----------------------------- 向表里批量添加数据 ----------------------------- create function myfun3(x int,y int) RETURNS int begin declare j int; declare str1 varchar(255) default '赵钱孙李周吴郑王冯陈诸卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻柏水窦章云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳酆鲍史唐费廉岑薛雷贺倪汤滕殷罗毕郝邬安常乐于时傅皮齐康伍余元卜顾孟平黄和穆萧尹姚邵堪汪祁毛禹狄米贝明臧计伏成戴谈宋茅庞熊纪舒屈项祝董粱杜阮蓝闵席季麻强贾路娄危江童颜郭梅盛林刁钟徐邱骆高夏蔡田樊胡凌霍虞万支柯咎管卢莫经房裘干解应宗丁宣贲邓郁单杭洪包诸左石崔吉钮龚'; declare str2 text default '明国华建文平志伟东海强晓生光林小民永杰军金健一忠洪江福祥中正振勇耀春大宁亮宇兴宝少剑云学仁涛瑞飞鹏安亚泽世汉达卫利胜敏群波成荣新峰刚家龙德庆斌辉良玉俊立浩天宏子松克清长嘉红山贤阳乐锋智青跃元武广思雄锦威启昌铭维义宗英凯鸿森超坚旭政传康继翔栋仲权奇礼楠炜友年震鑫雷兵万星骏伦绍麟雨行才希彦兆贵源有景升惠臣慧开章润高佳虎根远力进泉茂毅富博霖顺信凡豪树和恩向道川彬柏磊敬书鸣芳培全炳基冠晖京欣廷哲保秋君劲轩帆若连勋祖锡吉崇钧田石奕发洲彪钢运伯满庭申湘皓承梓雪孟其潮冰怀鲁裕翰征谦航士尧标洁城寿枫革纯风化逸腾岳银鹤琳显焕来心凤睿勤延凌昊西羽百捷定琦圣佩麒虹如靖日咏会久昕黎桂玮燕可越彤雁孝宪萌颖艺夏桐月瑜沛诚夫声冬奎扬双坤镇楚水铁喜之迪泰方同滨邦先聪朝善非恒晋汝丹为晨乃秀岩辰洋然厚灿卓杨钰兰怡灵淇美琪亦晶舒菁真涵爽雅爱依静棋宜男蔚芝菲露娜珊雯淑曼萍珠诗璇琴素梅玲蕾艳紫珍丽仪梦倩伊茜妍碧芬儿岚婷菊妮媛莲娟一'; declare a1 varchar(3); -- 用于存放随机生成的名字 declare a2 int; -- 用于存放随机生成的年龄 set j=1; while j<=y do set a1 = concat(substring(str1,floor(1+190*rand()),1),substring(str2,floor(1+400*rand()),1),substring(str2,floor(1+400*rand()),1)); set a2 = floor(18+6*rand()); if floor(2*rand())=1 then insert INTO student values(x+j,a1,a2,'男'); else insert INTO student values(x+j,a1,a2,'女'); end if; set j=j+1; end while; return j-1; end
SQL语句中的流程控制
-
case语句
------------------ demo1 -------------------- SELECT name, case when age>20 THEN '高龄' when age<=20 THEN '低龄' end as 等级 from student ------------------ demo2 -------------------- select name, CASE sex WHEN '男' THEN 1 WHEN '女' THEN 0 ELSE 2 END AS 性别 from student;
-
IF 判断条件的正误,返回对应值
-- 判断条件的正返回 '大于',否则返回 '小于' select name, IF(age>20,'大于','小于') as 等级 from student;
-
IFNULL(expr1,expr2) 判断值是否为空
-- 判断值为空返回expr2,否则返回expr1 select IFNULL(go.amount,0) from t_goods go;
MySQL的 Procedure
为了快速入门,拿Procedure与Function做个对比:
- Function 不用声明形式参数类型,所有形参隐式为 in。Procedure 必须显示声明形参是in、out、还是 inout。
- Function 必须要有 Returns。Procedure 不能有 Returns
- Function 用 Returns 规定返回值类型。Procedure 用 out 类型的形参规定返回值类型。
- Function 函数用 select 调用,然后直接返回结果。
Procedure 函数用 call 调用,函数结果先返回给 out 参数,之后用 select 去拿 out 参数。 - Function 函数必须指定返回值。Procedure 函数可以不用返回值
- 销毁方法稍有差异
Procedure 的语法:
-- 修改语句结束符为 $$ ,可以不使用这个方法
delimiter $$
create procedure proctmp(in param1 int,out param2 varchar(30))
begin
-- 声明局部变量,必须在函数体最开始声明
declare num int default 0;
end
-- 语句结束
$$
-- 修改语句结束符为 ;
delimiter ;
Procedure 函数使用 out 类型的形参返回数据。但是如果 Procedure 函数不需要返回数据,就不需要设置 out 类型的形参。
一个demo
------------------------- procedure --------------------------
CREATE PROCEDURE proctmp(in param1 int,out param2 varchar(30))
begin
select name into param2 -- 把 name 赋值给 param2。最后会把 param2 返回
from student where id=param1;
end
------------------------- 使用 --------------------------
call proctmp(17, @asd); -- 这里 out 参数必须要有 '@' 标志
SELECT @asd;
------------------------- 销毁 --------------------------
DROP PROCEDURE proctmp;
另一个demo
-------------------- 这个 demo 没有返回值 ---------------------
CREATE PROCEDURE proctmp(in param1 int)
begin
DELETE FROM student WHERE id=param1;
end
------------------------- 使用 --------------------------
call proctmp(18);
结论:如果是不需要返回值的方法,就用 Procedure。