作者:天山老妖S
链接:http://blog.51cto.com/9291927
一、自定义函数简介
自定义函数(user-defined function UDF)是一种对MySQL扩展的途径,其用法和内置函数相同。
自定义函数的两个必要条件:
A、参数
B、返回值(必须有)。函数可以返回任意类型的值。
二、自定义函数的使用
1、自定义函数语法
CREATE FUNCTION function_name(parameter_nametype,[parameter_name type,...])RETURNS {STRING|INTEGER|REAL}
runtime_body
在函数体中可以使用更为复杂的语法,比如复合结构/流程结构/任何SQL语句/定义变量等。
带复合结构的函数体的自定义函数的创建语法如下:
DELIMITER //CREATE FUNCTION function_name(parameter_nametype,[parameter_name type,...])RETURNS {STRING|INTEGER|REAL}BEGIN//bodyEND// /* 此处的”//“为告诉系统函数定义结束 */
当函数体内需要执行的是多条语句时,要使用BEGIN...END语句;且当编写函数体内容的时候,需要使用DELIMITER关键字将分隔符先修改为别的,否则编写语句的时候写到';'的时候会直接执行,导致函数编写失败。
2、创建带复合结构的函数体的自定义函数
在函数体中,如果包含多条语句,需要把多条语句放到BEGIN...END语句块中。
复合结构可以包括声明、循环、控制结构。
3、自定义函数中定义的语法:
declare var_name[,varname]...date_type [default value];
为变量赋值的语法:
SET parameter_name = value[,parameter_name = value...]SELECT INTO parameter_name
实例:
DECLARE x int;SELECT COUNT(id) FROM tdb_name INTO x;SET @x = 100;
4、流程控制
自定义函数中可以使用流程控制来控制语句的执行。
MySQL中可以使用IF语句、CASE语句、LOOP语句、LEAVE语句、ITERATE语句、REPEAT语句和WHILE语句来进行流程控制。
A、IF语句
IF语句用来进行条件判断。根据是否满足条件,将执行不同的语句。其语法的基本形式如下:
IF search_condition THEN statement_list
[ELSEIF search_condition THEN statement_list] ...
[ELSE statement_list]
END IF
search_condition参数表示条件判断语句;statement_list参数表示不同条件的执行语句。IF语句都需要使用END IF来结束。
IF语句实例:
IF age > 20 THEN SET @count1 = @count1 + 1;
B、CASE语句
CASE语句也用来进行条件判断,其可以实现比IF语句更复杂的条件判断。CASE语句的基本形式如下:
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] ...
[ELSE statement_list]
END CASE
case_value参数表示条件判断的变量;
when_value参数表示变量的取值;
statement_list参数表示不同when_value值的执行语句。
CASE语句实例:
CASE age WHEN 20 THEN SET @count1=@count1+1;
ELSE SET @count2=@count2+1;
END CASE ;
CASE语句还有另一种形式,语法如下:
CASE
WHEN search_condition THEN statement_list
[WHEN search_condition THEN statement_list] ...
[ELSE statement_list]
END CASE
search_condition参数表示条件判断语句;
statement_list参数表示不同条件的执行语句。
CASE语句实例:
CASE
WHEN age=20 THEN SET @count1=@count1+1;
ELSE SET @count2=@count2+1;
END CASE ;
C、LOOP语句
LOOP语句可以使某些特定的语句重复执行,实现一个简单的循环。但LOOP语句本身没有停止循环的语句,必须是遇到LEAVE语句等才能停止循环。
LOOP语句的语法的基本形式如下:
[begin_label:] LOOP statement_list END LOOP [end_label]
begin_label参数和end_label参数分别表示循环开始和结束的标志,两个标志必须相同,而且都可以省略;statement_list参数表示需要循环执行的语句。
LOOP语句实例:
add_num: LOOP SET @count=@count+1; END LOOP add_num ;
D、LEAVE语句
LEAVE语句主要用于跳出循环控制。其语法形式如下:
LEAVE lable
label参数表示循环的标志。
LEAVE语句实例:
add_num: LOOP SET @count=@count+1;
IF @count=100 THEN
LEAVE add_num ;
END LOOP add_num ;
E、ITERATE语句
ITERATE语句也是用来跳出循环的语句。但是,ITERATE语句是跳出本次循环,然后直接进入下一次循环。
ITERATE语句只可以出现在LOOP、REPEAT、WHILE语句内。
ITERATE语句的基本语法形式如下:
ITERATE label
其中,label参数表示循环的标志。
ITERATE语句实例:
add_num: LOOP SET @count=@count+1;
IF @count=100 THEN
LEAVE add_num ;
ELSE IF MOD(@count,3)=0 THEN
ITERATE add_num;
SELECT * FROM employee ;
END LOOP add_num ;
LEAVE语句是跳出整个循环,然后执行循环后面的程序。而ITERATE语句是跳出本次循环,然后进入下一次循环。
F、REPEAT语句
REPEAT语句是有条件控制的循环语句。当满足特定条件时,就会跳出循环语句。REPEAT语句的基本语法形式如下:
[begin_label:] REPEAT statement_list UNTIL search_condition END REPEAT [end_label]
REPEAT循环都用END REPEAT结束。
其中,statement_list参数表示循环的执行语句;search_condition参数表示结束循环的条件,满足该条件时循环结束。
REPEAT SET @count=@count+1;
UNTIL @count=100 END REPEAT ;
G、WHILE语句
WHILE语句也是有条件控制的循环语句。但WHILE语句和REPEEAT语句是不一样的。
WHILE语句和REPEAT语句是不一样的。
WHILE语句是当满足条件时,执行循环内的语句。
WHILE语句的基本语法形式如下:
[begin_label:] WHILE search_condition DO statement_list
END WHILE [end_label]
WHILE循环需要使用END WHILE来结束。
其中,search_condition参数表示循环执行的条件,满足该条件时循环执行;
statement_list参数表示循环的执行语句。
WHILE @count<100 DO
SET @count=@count+1;
END WHILE ;
5、删除自定义函数
DROP FUNCTION functionName;
6、自定义函数实例
SELECT function_name(parameter_value,...);
三、自定义函数实例
1、根据学生成绩判断学生成绩是否优秀
以下函数能够根据输入值范围输出成绩是否优良差。
小于60 不及格
60-69 需要努力
70-79 成绩中等
80-89 成绩优秀
90-100 成绩良好
create function getGrade(mark int) returns VARCHAR(20)
beginreturn (
case FLOOR(mark/10)
when 5 then '不及格'
when 6 then '继续努力'
when 7 then '成绩良好'
else '成绩优秀'
end);END
2、汉字转拼音函数
需要先创建一张表,存储字符集GBK的代码和拼音之间对应关系。
CREATE TABLE IF NOT EXISTS `t_base_pinyin` ( `pin_yin_` varchar(255) CHARACTER SET gbk NOT NULL, `code_` int(11) NOT NULL,
PRIMARY KEY (`code_`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
插入数据:INSERT INTO t_base_pinyin (pin_yin_,code_) VALUES ("a", 20319),("ai", 20317),("an", 20304),("ang", 20295),("ao", 20292),("ba", 20283),("bai", 20265),("ban", 20257),("bang", 20242),("bao", 20230),("bei", 20051),("ben", 20036),("beng", 20032),("bi", 20026),("bian", 20002),("biao", 19990),("bie", 19986),("bin", 19982),("bing", 19976),("bo", 19805),("bu", 19784),("ca", 19775),("cai", 19774),("can", 19763),("cang", 19756),("cao", 19751),("ce", 19746),("ceng", 19741),("cha", 19739),("chai", 19728),("chan", 19725),("chang", 19715),("chao", 19540),("che", 19531),("chen", 19525),("cheng", 19515),("chi", 19500),("chong", 19484),("chou", 19479),("chu", 19467),("chuai", 19289),("chuan", 19288),("chuang", 19281),("chui", 19275),("chun", 19270),("chuo", 19263),("ci", 19261),("cong", 19249),("cou", 19243),("cu", 19242),("cuan", 19238),("cui", 19235),("cun", 19227),("cuo", 19224),("da", 19218),("dai", 19212),("dan", 19038),("dang", 19023),("dao", 19018),("de", 19006),("deng", 19003),("di", 18996),("dian", 18977),("diao", 18961),("die", 18952),("ding", 18783),("diu", 18774),("dong", 18773),("dou", 18763),("du", 18756),("duan", 18741),("dui", 18735),("dun", 18731),("duo", 18722),("e", 18710),("en", 18697),("er", 18696),("fa", 18526),("fan", 18518),("fang", 18501),("fei", 18490),("fen", 18478),("feng", 18463),("fo", 18448),("fou", 18447),("fu", 18446),("ga", 18239),("gai", 18237),("gan", 18231),("gang", 18220),("gao", 18211),("ge", 18201),("gei", 18184),("gen", 18183),("geng", 18181),("gong", 18012),("gou", 17997),("gu", 17988),("gua", 17970),("guai", 17964),("guan", 17961),("guang", 17950),("gui", 17947),("gun", 17931),("guo", 17928),("ha", 17922),("hai", 17759),("han", 17752),("hang", 17733),("hao", 17730),("he", 17721),("hei", 17703),("hen", 17701),("heng", 17697),("hong", 17692),("hou", 17683),("hu", 17676),("hua", 17496),("huai", 17487),("huan", 17482),("huang", 17468),("hui", 17454),("hun", 17433),("huo", 17427),("ji", 17417),("jia", 17202),("jian", 17185),("jiang", 16983),("jiao", 16970),("jie", 16942),("jin", 16915),("jing", 16733),("jiong", 16708),("jiu", 16706),("ju", 16689),("juan", 16664),("jue", 16657),("jun", 16647),("ka", 16474),("kai", 16470),("kan", 16465),("kang", 16459),("kao", 16452),("ke", 16448),("ken", 16433),("keng", 16429),("kong", 16427),("kou", 16423),("ku", 16419),("kua", 16412),("kuai", 16407),("kuan", 16403),("kuang", 16401),("kui", 16393),("kun", 16220),("kuo", 16216),("la", 16212),("lai", 16205),("lan", 16202),("lang", 16187),("lao", 16180),("le", 16171),("lei", 16169),("leng", 16158),("li", 16155),("lia", 15959),("lian", 15958),("liang", 15944),("liao", 15933),("lie", 15920),("lin", 15915),("ling", 15903),("liu", 15889),("long", 15878),("lou", 15707),("lu", 15701),("lv", 15681),("luan", 15667),("lue", 15661),("lun", 15659),("luo", 15652),("ma", 15640),("mai", 15631),("man", 15625),("mang", 15454),("mao", 15448),("me", 15436),("mei", 15435),("men", 15419),("meng", 15416),("mi", 15408),("mian", 15394),("miao", 15385),("mie", 15377),("min", 15375),("ming", 15369),("miu", 15363),("mo", 15362),("mou", 15183),("mu", 15180),("na", 15165),("nai", 15158),("nan", 15153),("nang", 15150),("nao", 15149),("ne", 15144),("nei", 15143),("nen", 15141),("neng", 15140),("ni", 15139),("nian", 15128),("niang", 15121),("niao", 15119),("nie", 15117),("nin", 15110),("ning", 15109),("niu", 14941),("nong", 14937),("nu", 14933),("nv", 14930),("nuan", 14929),("nue", 14928),("nuo", 14926),("o", 14922),("ou", 14921),("pa", 14914),("pai", 14908),("pan", 14902),("pang", 14894),("pao", 14889),("pei", 14882),("pen", 14873),("peng", 14871),("pi", 14857),("pian", 14678),("piao", 14674),("pie", 14670),("pin", 14668),("ping", 14663),("po", 14654),("pu", 14645),("qi", 14630),("qia", 14594),("qian", 14429),("qiang", 14407),("qiao", 14399),("qie", 14384),("qin", 14379),("qing", 14368),("qiong", 14355),("qiu", 14353),("qu", 14345),("quan", 14170),("que", 14159),("qun", 14151),("ran", 14149),("rang", 14145),("rao", 14140),("re", 14137),("ren", 14135),("reng", 14125),("ri", 14123),("rong", 14122),("rou", 14112),("ru", 14109),("ruan", 14099),("rui", 14097),("run", 14094),("ruo", 14092),("sa", 14090),("sai", 14087),("san", 14083),("sang", 13917),("sao", 13914),("se", 13910),("sen", 13907),("seng", 13906),("sha", 13905),("shai", 13896),("shan", 13894),("shang", 13878),("shao", 13870),("she", 13859),("shen", 13847),("sheng", 13831),("shi", 13658),("shou", 13611),("shu", 13601),("shua", 13406),("shuai", 13404),("shuan", 13400),("shuang", 13398),("shui", 13395),("shun", 13391),("shuo", 13387),("si", 13383),("song", 13367),("sou", 13359),("su", 13356),("suan", 13343),("sui", 13340),("sun", 13329),("suo", 13326),("ta", 13318),("tai", 13147),("tan", 13138),("tang", 13120),("tao", 13107),("te", 13096),("teng", 13095),("ti", 13091),("tian", 13076),("tiao", 13068),("tie", 13063),("ting", 13060),("tong", 12888),("tou", 12875),("tu", 12871),("tuan", 12860) ,("tui", 12858),("tun", 12852),("tuo", 12849),("wa", 12838),("wai", 12831),("wan", 12829),("wang", 12812),("wei", 12802),("wen", 12607),("weng", 12597),("wo", 12594),("wu", 12585),("xi", 12556),("xia", 12359),("xian", 12346),("xiang", 12320),("xiao", 12300),("xie", 12120),("xin", 12099),("xing", 12089),("xiong", 12074),("xiu", 12067),("xu", 12058),("xuan", 12039),("xue", 11867),("xun", 11861),("ya", 11847),("yan", 11831),("yang", 11798),("yao", 11781),("ye", 11604),("yi", 11589),("yin", 11536),("ying", 11358),("yo", 11340),("yong", 11339),("you", 11324),("yu", 11303),("yuan", 11097),("yue", 11077),("yun", 11067),("za", 11055),("zai", 11052),("zan", 11045),("zang", 11041),("zao", 11038),("ze", 11024),("zei", 11020),("zen", 11019),("zeng", 11018),("zha", 11014),("zhai", 10838),("zhan", 10832),("zhang", 10815),("zhao", 10800),("zhe", 10790),("zhen", 10780),("zheng", 10764),("zhi", 10587),("zhong", 10544),("zhou", 10533),("zhu", 10519),("zhua", 10331),("zhuai", 10329),("zhuan", 10328),("zhuang", 10322),("zhui", 10315),("zhun", 10309),("zhuo", 10307),("zi", 10296),("zong", 10281),("zou", 10274),("zu", 10270),("zuan", 10262),("zui", 10260),("zun", 10256),("zuo", 10254);
汉字生成拼音的函数:
DROP FUNCTION IF EXISTS PINYIN;
CREATE FUNCTION PINYIN(NAME VARCHAR(255) CHARSET GBK)RETURNS VARCHAR(255) CHARSET gbkBEGIN
DECLARE mycode INT; DECLARE tmp_lcode VARCHAR(2) CHARSET gbk; DECLARE lcode INT; DECLARE tmp_rcode VARCHAR(2) CHARSET gbk; DECLARE rcode INT; DECLARE mypy VARCHAR(255) CHARSET gbk DEFAULT ''; DECLARE lp INT;
SET mycode = 0;
SET lp = 1;
SET NAME = HEX(NAME); WHILE lp < LENGTH(NAME) DO
SET tmp_lcode = SUBSTRING(NAME, lp, 2);
SET lcode = CAST(ASCII(UNHEX(tmp_lcode)) AS UNSIGNED);
SET tmp_rcode = SUBSTRING(NAME, lp + 2, 2);
SET rcode = CAST(ASCII(UNHEX(tmp_rcode)) AS UNSIGNED);
IF lcode > 128 THEN
SET mycode =65536 - lcode * 256 - rcode ;
SELECT CONCAT(mypy,pin_yin_) INTO mypy FROM t_base_pinyin WHERE CODE_ >= ABS(mycode) ORDER BY CODE_ ASC LIMIT 1;
SET lp = lp + 4; ELSESET mypy = CONCAT(mypy,CHAR(CAST(ASCII(UNHEX(SUBSTRING(NAME, lp, 2))) AS UNSIGNED)));
SET lp = lp + 2;
END IF;
END WHILE; RETURN LOWER(mypy);
END;
3、阿拉伯数字转汉字
create FUNCTION tohanzi (n_LowerMoney DECIMAL)
RETURNS VARCHAR(120)
BEGIN
Declare v_LowerStr VARCHAR(200) ;
Declare v_UpperPart VARCHAR(200) ;
Declare v_UpperStr VARCHAR(200) ;
Declare i_I int ; set v_LowerStr = LTRIM(RTRIM(ROUND(n_LowerMoney,2 ) ) ) ; set i_I = 1 ; set v_UpperStr = '' ; while ( i_I <=char_length(v_LowerStr ) ) do
set v_UpperPart = CONCAT( case substring(v_LowerStr,char_length(v_LowerStr) - i_I + 1,1 )
WHEN '.' THEN '元'
WHEN '0' THEN '零'
WHEN '1' THEN '壹'
WHEN '2' THEN '贰'
WHEN '3' THEN '叁'
WHEN '4' THEN '肆'
WHEN '5' THEN '伍'
WHEN '6' THEN '陆'
WHEN '7' THEN '柒'
WHEN '8' THEN '捌'
WHEN '9' THEN '玖'
END, case i_I
WHEN 1 THEN '分'
WHEN 2 THEN '角'
WHEN 3 THEN ''
WHEN 4 THEN ''
WHEN 5 THEN '拾'
WHEN 6 THEN '佰'
WHEN 7 THEN '仟'
WHEN 8 THEN '万'
WHEN 9 THEN '拾'
WHEN 10 THEN '佰'
WHEN 11 THEN '仟'
WHEN 12 THEN '亿'
WHEN 13 THEN '拾'
WHEN 14 THEN '佰'
WHEN 15 THEN '仟'
WHEN 16 THEN '万'
ELSE ''
END ); set v_UpperStr =CONCAT( v_UpperPart , v_UpperStr) ; set i_I = i_I + 1 ;
end while; set v_UpperStr = REPLACE(v_UpperStr,'零拾','零') ; set v_UpperStr = REPLACE(v_UpperStr,'零佰','零') ; set v_UpperStr = REPLACE(v_UpperStr,'零仟','零') ; set v_UpperStr = REPLACE(v_UpperStr,'零零零','零') ; set v_UpperStr = REPLACE(v_UpperStr,'零零','零') ; set v_UpperStr = REPLACE(v_UpperStr,'零角零分','整') ; set v_UpperStr = REPLACE(v_UpperStr,'零分','整') ; set v_UpperStr = REPLACE(v_UpperStr,'零角','零') ; set v_UpperStr = REPLACE(v_UpperStr,'零亿零万零元','亿元') ; set v_UpperStr = REPLACE(v_UpperStr,'亿零万零元','亿元') ; set v_UpperStr = REPLACE(v_UpperStr,'零亿零万','亿') ; set v_UpperStr = REPLACE(v_UpperStr,'零万零元','万元') ; set v_UpperStr = REPLACE(v_UpperStr,'万零元','万元') ; set v_UpperStr = REPLACE(v_UpperStr,'零亿','亿') ; set v_UpperStr = REPLACE(v_UpperStr,'零万','万') ; set v_UpperStr = REPLACE(v_UpperStr,'零元','元') ; set v_UpperStr = REPLACE(v_UpperStr,'零零','零') ; if ( '元' = substring(v_UpperStr,1,1)) then
set v_UpperStr = substring(v_UpperStr,2,(char_length(v_UpperStr) - 1));
end if; if ( '零' = substring(v_UpperStr,1,1)) then
set v_UpperStr = substring(v_UpperStr,2,(char_length(v_UpperStr) - 1)) ;
end if; if ( '角' = substring(v_UpperStr,1,1)) then
set v_UpperStr = substring(v_UpperStr,2,(char_length(v_UpperStr) - 1)) ;
end if; if ( '分' = substring(v_UpperStr,1,1)) then
set v_UpperStr = substring(v_UpperStr,2,(char_length(v_UpperStr) - 1)) ;
end if; if ('整' = substring(v_UpperStr,1,1)) then
set v_UpperStr = '零元整' ;
end if; return v_UpperStr;
END
4、随机产生姓名的函数
使用三个字符串,存放用户的姓名,使用随机函数从姓名中随机排列组合成人名。
create function CreateName()RETURNS varchar(3)beginDECLARE LN VARCHAR(300);DECLARE MN VARCHAR(500);DECLARE FN VARCHAR(500);DECLARE LN_N INT;DECLARE MN_N INT;DECLARE FN_N INT;
SET LN='李王张刘陈杨黄赵周吴徐孙朱马胡郭林何高梁郑罗宋谢唐韩曹许邓萧冯曾程蔡彭潘袁于董余苏叶吕魏蒋田杜丁沈姜范江傅钟卢汪戴崔任陆廖姚方金邱夏谭韦贾邹石熊孟秦阎薛侯雷白龙段郝孔邵史毛常万顾赖武康贺严尹钱施牛洪龚';
SET MN='伟刚勇毅俊云莲真环雪荣爱妹霞香月莺媛艳瑞凡佳嘉琼勤珍贞莉桂娣叶璧才发武丽琳轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德河哲江超浩璐娅琦晶裕华慧巧美婕馨影荔枝思心邦承乐绍功松善厚庆磊民友玉萍红娥玲芬芳燕彩兰凤洁梅秀娟英行时泰盛雄琛钧冠策腾楠榕风航弘峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩中茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛雄琛钧冠策腾楠榕风航弘';
SET FN='伟刚勇毅俊云莲真环雪荣爱妹霞香月莺媛艳瑞凡佳嘉琼勤珍贞莉桂娣叶璧才发武丽琳轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德河哲江超浩璐娅琦晶裕华慧巧美婕馨影荔枝思心邦承乐绍功松善厚庆磊民友玉萍红娥玲芬芳燕彩兰凤洁梅秀娟英行时泰盛雄琛钧冠策腾楠榕风航弘峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩中茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛雄琛钧冠策腾楠榕风航弘';
SET LN_N=CHAR_LENGTH(LN);
SET MN_N=CHAR_LENGTH(MN);
SET FN_N=CHAR_LENGTH(FN);return Concat(substring(LN,ceil(rand()*LN_N),1),substring(MN,ceil(rand()*MN_N),1),substring(FN,ceil(rand()*FN_N),1));
End
喜欢的小伙伴们可以搜索我们个人的微信公众号“程序员的成长之路”点击关注或扫描下方二维码