MySQL函数
一、理解函数与存储过程
1、相同点
-
存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合。
2、区别
-
函数必须有返回值,而存储过程没有。
-
存储过程的参数可以是IN、OUT、INOUT类型,函数的参数只能是IN。
- 对自定义函数进行调用不需要使用 CALL 语句,而对存储过程的调用需要使用 CALL 语句。
3、使用场景
- 并发量少的情况下,很少使用存储过程。并发量高的情况下,为了提高效率,用存储过程比较多。
- 函数经常和存储过程搭配使用
二、自定义函数
在使用 MySQL 的过程中,MySQL 自带的函数可能完成不了我们的业务需求,这时候就需要自定义函数。自定义函数是一种与存储过程十分相似的过程式数据库对象。它与存储过程一样,都是由 SQL 语句和过程式语句组成的代码片段,并且可以被应用程序和其他 SQL 语句调用。
1、语法格式
CREATE FUNCTION <函数名> ( [ <参数1> <类型1> [ , <参数2> <类型2>] ] … )
RETURNS <类型>
<函数主体>
语法说明如下:
<函数名>
:指定自定义函数的名称。注意,自定义函数不能与存储过程具有相同的名称。<参数><类型>
:用于指定自定义函数的参数。这里的参数只有名称和类型,不能指定关键字 IN、OUT 和 INOUT。RETURNS<类型>
:用于声明自定义函数返回值的数据类型。其中,<类型>
用于指定返回值的数据类型。<函数主体>
:自定义函数的主体部分,也称函数体。所有在存储过程中使用的 SQL 语句在自定义函数中同样适用,包括前面所介绍的局部变量、SET 语句、流程控制语句、游标等。除此之外,自定义函数体还必须包含一个RETURN<值>
语句,其中<值>
用于指定自定义函数的返回值。在 RETURN VALUE 语句中包含 SELECT 语句时,SELECT 语句的返回结果只能是一行且只能有一列值。
2、示例
(1)无参自定义函数
-- 自定义无参数函数 DELIMITER $$ #使用DELIMITER是因为MySQL中默认是使用分号来结束一个命令的,函数体中一条命令写完时会用分号来结束,而MySQL会误以为函数体已经定义完成,因为需要定义一个新的标识符来标识一个命令的结束,因为就可以使用DELIMITER。 DROP FUNCTION IF EXISTS func_get $$ CREATE FUNCTION func_get() RETURNS VARCHAR(255) BEGIN RETURN 'hello world!'; END $$ DELIMITER ; -- 调用自定义函数 SELECT func_get();
(2)有参自定义函数
-- 自定义有参数函数 DELIMITER $$ DROP FUNCTION IF EXISTS func_add $$ CREATE FUNCTION func_add ( a INT, b INT ) RETURNS INT BEGIN DECLARE c INT DEFAULT 0;#c就是局部变量 SET c=a+b; RETURN c; END $$ DELIMITER ; -- 调用函数 SELECT func_add(1,2);
3、自定义函数相关语法及变量
(1)变量声明
变量声明的语法如下:
DECLARE var_name[,...] type [DEFAULT value]
要给变量提供一个默认值,请包含一个DEFAULT子句。值可以被指定为一个表达式,不需要为一个常数。如果没有DEFAULT子句,初始值为NULL。使用语序使用 set 和 select into语句为变量赋值。例如:
DECLARE c INT DEFAULT 0;#c就是局部变量
(2)IF条件语句
示例一:
-- 自定义有参数函数 DELIMITER $$ DROP FUNCTION IF EXISTS func_get $$ CREATE FUNCTION func_get ( cj INT ) RETURNS VARCHAR(255) BEGIN DECLARE text VARCHAR(255) DEFAULT ''; IF cj>90 THEN SET text='优秀'; ELSEIF cj>60 THEN SET text='良好'; ELSE SET text='不及格'; END IF; RETURN text; END $$ DELIMITER ; -- 调用函数 SELECT func_get(70);
示例二:if 里面的多条件 and or
-- 自定义有参数函数 DELIMITER $$ DROP FUNCTION IF EXISTS func_get $$ CREATE FUNCTION func_get ( num INT ) RETURNS VARCHAR(255) BEGIN DECLARE text VARCHAR(255) DEFAULT ''; IF num>10 AND num<20 THEN SET text='大于10小于20'; ELSEIF num>20 OR num<10 THEN SET text='小于10或者大于20'; END IF; RETURN text; END $$ DELIMITER ; -- 调用函数 SELECT func_get(70);
(3)CASE语句
-- 自定义有参数函数 DELIMITER $$ DROP FUNCTION IF EXISTS func_get $$ CREATE FUNCTION func_get ( cj INT ) RETURNS VARCHAR(255) BEGIN DECLARE text VARCHAR(255) DEFAULT ''; CASE WHEN cj>10 AND cj<20 THEN SET text='大于10小于20'; WHEN cj>20 OR cj<10 THEN SET text='小于10或者大于20'; ELSE SET text='其他'; END CASE; RETURN text; END $$ DELIMITER ; -- 调用函数 SELECT func_get(5);
(4)循环语句
/*创建自定义函数,求指定数之间的和*/ delimiter $$ /*修改临时语句结束符*/ DROP FUNCTION IF EXISTS func_sum; CREATE FUNCTION func_sum(num int) RETURNS INT BEGIN /*定义条件变量,注意用@符号定义的变量是全局的,也就是说在外面也可以访问*/ SET @flg = 1; /*循环结束变量开关*/ SET @res = 0; /*用来保存最终结果*/ WHILE @flg <= num DO /*当条件满足时进入循环*/ SET @res = @res + @flg; /*注意:mysql里没有+= -=这种概练*/ SET @flg := @flg + 1; /*只能用这种方式赋值*/ /* 【备注】 := 符号的说明 在mysql中 := 才是真正意义上的赋值操作,把右边的值赋给左边的变量 = 则只在一种情况下作为赋值用, 就是在SET语句里面,如: SET id = 50 除此之外 = 则是作为比较操作符使用的 当然我这里完全可以用 = 来进行赋值,但人家Mysq已经专门设计了一个专门的赋值符号 := 所以我只要是赋值操作都是使用 := 来完成,这样可避免出错 */ END WHILE; /*结束循环*/ RETURN @res; /*返回结果*/ END /*语句结束*/ $$ /*将临时语句结束符改回成 ; */ delimiter ; /*函数查看语句*/ SELECT func_sum(100);
4、修改自定义函数
修改命令规范:
ALTER FUNCTION func_name [characteristic ...] characteristic: COMMENT 'string' | LANGUAGE SQL | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER }
5、删除自定义函数
DROP FUNCTION [IF EXISTS] <自定义函数名>
三、常用系统函数汇总
可以参考:MySQL函数大全