本次是一个示例,其中包含 参数声明、游标声明、查询结果赋值游标、查询结果循环遍历处理、if逻辑判断、日期比较等基本操作,参考此写法可满足常见业务需求
-- delimiter声明开始结束位置,否则执行创建时因为中间分号会报语法错误
delimiter //
CREATE DEFINER=`skip-grants user`@`skip-grants host` FUNCTION `f_get_asset_maintenance_month`(`assetId` int,`previousEndDate` date) RETURNS int(11)
BEGIN
DECLARE flag int DEFAULT 0;
DECLARE startDate date;
DECLARE endDate date;
DECLARE monthNum int DEFAULT 0;
-- 定义游标,并将sql结果集赋值到游标中,res为游标名
DECLARE res CURSOR FOR SELECT tm.START_DATE, tm.END_DATE FROM t_maintenance tm INNER JOIN t_asset_maintenance tam ON tm.MAINTENANCE_ID = tam.MAINTENANCE_ID AND tam.ASSET_ID = assetId AND tm.END_DATE>`previousEndDate` ORDER BY tm.START_DATE;
-- 声明当游标遍历完后将标志变量置为某个值
DECLARE CONTINUE HANDLER FOR NOT FOUND SET flag = 1;
-- 打开游标
OPEN res;
-- 将游标中的值赋值给变量,注意:变量名不要与sql返回的列名相同,变量顺序要和sql结果列的顺序一致
FETCH res INTO startDate, endDate;
-- 当flag不等于1时,也就是未遍历完时,会一直循环
WHILE flag <> 1 DO
-- if条件判断(包含时间加减法)
if previousEndDate-startDate > -2 AND endDate > previousEndDate
THEN
set previousEndDate = endDate;
-- 当满足下面条件时,证明维保时间不连续,直接结束循环
elseif previousEndDate-startDate <= -2
THEN
RETURN previousEndDate;
END if;
FETCH res INTO startDate, endDate;
END WHILE;
-- 关闭游标
CLOSE res;
-- 计算月份差值
set monthNum = TIMESTAMPDIFF(month,now(),previousEndDate);
RETURN monthNum;
END
//