定义
- 自定义函数和存储过程很类似,但是必须要有返回值。
 - 与内置的 sum()、max() 等 MySQL 原生函数使用方法类似。
- select fun(val);
 - select * from t where col= fun(val);
 
 - 自定义函数可能在遍历每条记录中使用,注意性能损耗。
 
语法
CREATE[DEFINER = { user | CURRENT_USER }]FUNCTION sp_name ([func_parameter[,...]])RETURNS type -- 必须有返回值[characteristic ...] routine_bodyfunc_parameter:param_name typetype:Any valid MySQL data typecharacteristic:COMMENT 'string'| LANGUAGE SQL| [NOT] DETERMINISTIC| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }| SQL SECURITY { DEFINER | INVOKER }routine_body:Valid SQL routine statement-- 删除DROP FUNCTION fun_name;
示例
-- 老师给的例子,还是阶乘,用自定义函数的方式mysql> delimiter //mysql>mysql> create function fun_test_1(total int)-> returns int-> begin-> declare i int;-> declare res int;-> set i := 1;-> set res := 1;-> if total <= 0 then-> set total := 1;-> end if;-> while i <= total do-> set res := res * i;-> set i := i + 1;-> end while;-> return res;-> end;//ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)-- 报错,提示因为函数的声明中没有"DETERMINISTIC, NO SQL, or READS SQL DATA"等关键字 ,需要使用打开参数 log_bin_trust_function_creators-- 解决方法,set global log_bin_trust_function_creators=1; 开启该选项可能会引起主从服务器不一致-- 或者 增加 上述相应功能的关键字-- 使用 deterministic 关键字-- 当你声明一个函数的返回是确定性的,则必须显示的使用deterministic关键字,默认是 no deterministic的mysql> delimiter //mysql> create function fun_test_1(total int)-> returns int deterministic -- 这个只是告诉MySQL我这个函数是否会改变数据-- 即使我下面使用了insert,update等DML语句,MySQL不会检查-- 函数是否会改变数据,完全依赖创建函数的用户去指定的关键字-- 而非真的是否有修改数据-- 只是声明,而非约束-> begin-> declare i int;-> declare res int;-> set i := 1;-> set res := 1;-> if total <= 0 then-> set total := 1;-> end if;-> while i <= total do-> set res := res * i;-> insert into test_proc_1 values(i, res); -- 在自定义函数中,同样可以使用sql-- 并且该SQL是insert,其实和deterministic违背。-> set i := i + 1;-> end while;-> return res;-> end;//Query OK, 0 rows affected (0.01 sec)mysql> delimiter ;mysql> truncate table test_proc_1;Query OK, 0 rows affected (0.11 sec)mysql> select fun_test_1(6); -- return了6的阶乘,720+---------------+| fun_test_1(6) |+---------------+| 720 |+---------------+1 row in set (0.02 sec)mysql> select * from test_proc_1;+------+------+| a | b |+------+------+| 1 | 1 || 2 | 2 || 3 | 6 || 4 | 24 || 5 | 120 || 6 | 720 | -- 使用了insert语句进行插入阶乘的历史记录+------+------+6 rows in set (0.00 sec)-- 关键字简单说明-- DETERMINISTIC:当给定相同的输入,产生确定的结果-- NOT DETERMINISTIC:默认值,认为产生的结果是不确定的-- READS SQL DATA:只是读取SQL数据-- MODIFIES SQL DATA:会修改数据-- NO SQL:没有SQL遇见-- CONTAINS SQL:包含SQL语句,但是没有读写语句,理论有select now()等
官方文档:https://dev.mysql.com/doc/refman/5.7/en/stored-programs-logging.html
作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/lzcosc 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
