定义
我们之前学习了MysqL的内置函数,传送门,非常丰富,满足了我们对数据操作的大部分需求。
但是如果有一些复杂的业务逻辑在数据库层面就可以完成,无需在程序层面完成的时候,这时候就可以写成MysqL自定义函数。
所以,函数是指 一组预编译好的sql语句集合,理解成批处理语句,类似于C# 中的方法,但是必须有返回值。调用函数等于一次性执行了这些语句,有利降低语句重复编写和调用。
作用
1、可以高度抽象业务逻辑,前置到数据库层面,而不是应用层面
2、相比于从数据库查询出来,然后程序操作数据,数据库操作一定程度上提高效率。
3、高度可复用性,数据库层面的方法封装,不只是应用在多个同样业务场景。还可以应用到多个不同语言中。
函数的使用
创建函数
1、param_list指的是参数列表,参数是可选的,可以不带参数,也可以带多个参数。参数 包含两部分:参数名 参数类型。
2、函数返回值是必选项,但是只允许返回一个值,不允许返回一个结果集(官方原文:Not allowed to return a result set from a function)。函数强调返回值,所以函数不允许返回多个值的情况,即使是查询语句。这是他会跟存储过程的区别。
3、函数体中如果有多个语句,使用begin end 包含
4、使用 delimiter语句设置结束标记 */
调用函数
SELECT func_name(param_list);
查看函数
1 SHOW FUNCTION STATUS;
查看函数创建脚本
FUNCTION func_name;
删除函数
DROP FUNCTION IF EXISTS func_name;
示例
数据基础
1 MysqL> select * from students; 2 +---------+-------------+-------+---------+ 3 | studentid | studentname | score | classid | 4 5 | 1 | brand | 105.5 | 6 2 | helen 98.5 7 3 | lyn 97 8 4 | sol 9 5 | b1 89 10 6 | b2 90 11 7 | c1 76 12 8 | c2 73.5 13 9 | lala 73 0 14 | 10 | A 100 15 16 | test1 16 17 | trigger2 107 17 22 | trigger1 18 19 13 rows in set
无参函数
获取有班级号的所有同学的平均成绩
1 /*如果存在函数func_test1,则删除*/ 2 EXISTS fun_test1; 3 声明结束符为$ 4 DELIMITER $ 5 创建函数 6 FUNCTION fun_test1() 7 RETURNS DECIMAL(10,2) 8 9 DECLARE avg_score 2) DEFAULT 0; 10 SELECT AVG(score) INTO avg_score FROM students where classid<>11 return avg_score; 12 END $ 13 重置结束符为;14 DELIMITER ;
使用 select 调用,无需传入参数
1 MysqLselect fun_test1(); 2 -----------+ 3 | fun_test1() 4 5 91.83 6 7 1 row set
有参函数
获取班级号为1的同学的平均成绩,参数cid 为班级号
使用 select 调用,传入参数1
select fun_test2(1); ------------+ | fun_test2(1) 99.5 set
查看函数信息
> SHOW STATUS; ----+-----------+----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+ | Db | Name | Type | Definer | Modified | Created | Security_type | Comment | character_set_client | collation_connection | Database Collation | test | fun_test FUNCTION | root@localhost 2021-0115 16:37:50 | DEFINER | utf8 | utf8_general_ci | latin1_swedish_ci | fun_test1 11:59:40 | fun_test2 12:00:27 8 9 3 rows set
查看函数创建脚本
> show create function---------+--------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+ Function | sql_mode Create Function | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `fun_test2`(cid INT) decimal( 7 8 10 END set
删除函数
2 Query OK,1)"> rows affected 3 4 MysqL1305 - FUNCTION test.fun_test2 does not exist
小结
存储过程和函数的区别
存储过程的关键字为procedure,返回值可以有多个,调用时用call,一般用于执行比较复杂的的过程体、更新、创建等语句。
函数的关键字为function,返回值必须有一个,调用用select,一般用于查询单个值并返回。
行为 | 存储过程 | 函数 |
---|---|---|
返回值 | 可以有0个或者多个 | 必须有一个 |
关键字 | procedure | function |
调用方式 | call | select |