前言:
数据库里面有很多内置的函数,比如:LENGTH(string ),CHAR_LENGTH(string),SUBSTRING(str ,position [,length ]),Now(),current_timestamp(),Ceil(X)等。那么为什么官方会给我们内置这么多的函数呢?本文我们就学习下mysql里面的函数的优点,以及如何使用。
mysql里面的函数,是用来把有关表操作的SQL语句代码当做一个整体模块来执行。一个完整的操作可能会包含多条SQL语句,在执行过程中需要根据前面的SQL语句来执行结果有选择的执行后面的SQL语句,并且给你返回你想要的结果。其实函数可以简单的理解为一条或多条SQL语句的集合。它会事先经过一次编译并存储在数据库中的一段SQL语句集合。
正文:
1. 函数语法
create function function_name([function_parameter[,...]])
[characteristic...] routine_body
语句中,function_name参数表示所要创建的函数的名字;function_parameter参数表示创建函数的参数,可以有多个参数,
characteristic参数表示函数的特性,该参数的取值与存储过程中的取值相同。routine_body参数表示函数的sql语句代码,可以用begin…end来表示sql语句的开始和结束。入参用IN表示,int型无需指定长度,但是varchar型必须要指定参数长度。否则会报错。
2. 函数用法
创建表hydra_template_group:
表结构预览:
完整建表sql语句如下
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for hydra_template_group -- ---------------------------- DROP TABLE IF EXISTS `hydra_template_group`; CREATE TABLE `hydra_template_group` ( `id` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '主键ID', `template_id` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '附件模板ID', `template_group_code` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '附件模板分组编码', `template_group_name` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '附件模板分组名称', `template_group_lev` varchar(10) COLLATE utf8_bin DEFAULT NULL COMMENT '附件模板级别', `template_group_parent_id` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '上级附件模板分组ID', `deleted` bit(1) DEFAULT NULL COMMENT '是否删除', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='附件模板分组'; SET FOREIGN_KEY_CHECKS=1;
以上可以看出,id和template_group_parent_id是父子关系,我们要求是递归查询,如果给定id我们查出它下面所有的子id,子子id等。通过Function()函数实现。
3. 创建函数:
函数名:getSubTemplateGroup,完整创建函数代码如下,入参是主键id,长度跟表结构保持一致50位。
完整创建function代码如下:
delimiter // CREATE DEFINER=`root`@`%` FUNCTION `getSubTemplateGroup`(temId VARCHAR(50)) RETURNS varchar(4000) CHARSET utf8 DETERMINISTIC begin DECLARE result text default ''; DECLARE temp text; SET temp =cast(temId as CHAR); SET result = concat(result,',',temp); WHILE temp is not null DO SELECT group_concat(id) INTO temp FROM hydra_template_group where FIND_IN_SET(template_group_parent_id,temp)>0; if temp is not null THEN SET result = concat(result,',',temp); end if; end while; return substring(result,2); end //
放到mysql执行后,
查看输出结果:
往数据库插入三条测试数据:
INSERT INTO `hydra_dev`.`hydra_template_group` (`id`, `template_id`, `template_group_code`, `template_group_name`, `template_group_lev`, `template_group_parent_id`, `deleted`) VALUES ('f68351e020304250af73c6762e0312dh', 'sdfsdfsdfsdfsdfdsfdsfsdf', NULL, '测试-身份证类', '1', NULL, b'0'); INSERT INTO `hydra_dev`.`hydra_template_group` (`id`, `template_id`, `template_group_code`, `template_group_name`, `template_group_lev`, `template_group_parent_id`, `deleted`) VALUES ('fd1241e020304250af73c6762e3221dh', 'sdfsdfsdfsdfsdfdsfdsfsdf', NULL, '测试-正面照类', '2', 'f68351e020304250af73c6762e0312dh', b'0'); INSERT INTO `hydra_dev`.`hydra_template_group` (`id`, `template_id`, `template_group_code`, `template_group_name`, `template_group_lev`, `template_group_parent_id`, `deleted`) VALUES ('1234e1e020304250af73c6762e0325dh', 'sdfsdfsdfsdfsdfdsfdsfsdf', NULL, '测试-正面戴帽子类', '3', 'fd1241e020304250af73c6762e3221dh', b'0');
查询数据如图:
4. 验证递归查询:
SELECT id,template_group_parent_id,template_group_name,template_group_lev from hydra_template_group where FIND_IN_SET (id,getSubTemplateGroup_test('f68351e020304250af73c6762e0312dh'));
查询结果输出如下:
补充说明:
提到函数,肯定会有很多人想起存储过程。下面就补充下二者的区别:
- 对于存储过程来说可以返回参数,如记录集,而函数只能返回值或者表对象。
- 函数只能返回一个变量;而存储过程可以返回多个。
- 存储过程的参数可以有IN,OUT,INOUT三种类型,而函数只能有IN类。
- 存储过程一般是作为一个独立的部分来执行,函数则可以作为查询语句的一个部分来调用。
- 在SQL语句中不可用存储过程,但是可以使用函数。
- 存储过程声明时不需要返回类型,而函数声明时需要描述返回类型,并且函数体中必须包含一个有效的RETURN语句。