create
    definer = sofmes_qpzz@`%` procedure calculateEqutRunTime(IN startDateTime varchar(20), IN endDateTime varchar(20),
                                                             IN equtFk varchar(100))
BEGIN
    ## 20231027-jy
    ## 计算【equipments设备表】中每个设备的运行时间,最后存入到【equipmentproperty设备属性表】中
    ## 主要使用的表:eps_working_rec
    # 属性记录id
    declare proId int default 0;
    # 设备运行时间(秒)
    declare runTime int default 0;
    declare num int default 0;
    declare v_euptPk varchar(100);
    declare v_equtName varchar(100);
    declare paramEqutFk varchar(100);
    # 游标结束标志
    declare done int default 0;
    # 创建游标
    DECLARE cur CURSOR FOR (select EuptPK, EqutName from equipments);
    # 指定游标循环结束时的返回值
#     declare continue HANDLER for SQLSTATE '02000' set done = 1;
    declare continue HANDLER FOR NOT FOUND set done = 1;
    #打开游标
    open cur;
    # 开始循环游标里的数据
    read_loop:
    loop
        # 根据游标当前指向的一条数据 插入到上面申明的局部变量中
        fetch cur into v_euptPk, v_equtName;
        # 判断游标的循环是否结束
        if done = 1 then
            begin
                leave read_loop; # 跳出游标循环
            end;
        end if;
        if equtFk is not null && equtFk <> ''
        then
            set paramEqutFk = equtFk;
        else
            set paramEqutFk = v_euptPk;
        end if;
        if !(startDateTime is not null && startDateTime <> '') && !(endDateTime is not null && endDateTime <> '')
        then
            # 获取设备运行时间
            select sum(if(Time_Cum is null, 0, Time_Cum))
            into runTime
            from eps_working_rec
            where eps_working_rec.EqutFK = + paramEqutFk
              and Rec_Type = 1;
        end if;
        if (startDateTime is not null && startDateTime <> '') && (endDateTime is not null && endDateTime <> '')
        then
            # 获取设备运行时间
            select sum(if(Time_Cum is null, 0, Time_Cum))
            into runTime
            from eps_working_rec
            where eps_working_rec.EqutFK = + paramEqutFk
              and BeginTime >= + startDateTime
              and EndTime <= + endDateTime
              and Rec_Type = 1;
        end if;
        # 开始时间条件
        if (startDateTime is not null && startDateTime <> '') && !(endDateTime is not null && endDateTime <> '')
        then
            # 获取设备运行时间
            select sum(if(Time_Cum is null, 0, Time_Cum))
            into runTime
            from eps_working_rec
            where eps_working_rec.EqutFK = + paramEqutFk
              and BeginTime >= + startDateTime
              and Rec_Type = 1;
        end if;
        # 结束时间条件
        if !(startDateTime is not null && startDateTime <> '') && (endDateTime is not null && endDateTime <> '')
        then
            # 获取设备运行时间
            select sum(if(Time_Cum is null, 0, Time_Cum))
            into runTime
            from eps_working_rec
            where eps_working_rec.EqutFK = + paramEqutFk
              and EndTime >= + endDateTime
              and Rec_Type = 1;
        end if;
        select runTime;
        # 运行时间大于0的设备,继续做操作
        if runTime is not null && runTime > 0 then
            begin
                # 获取设备属性为 【运行时间】得记录
                set proId = 0;
                select if(count(ID) > 0, ID, 0)
                into proId
                from equipmentproperty equtPro
                where equtPro.EqutPropertyName = '运行时间'
                  and equtPro.EqutFK = + paramEqutFk
                limit 1;
                # 设备属性中不存在运行时间记录,则插入数据,否则进行更新数据
                if proId is null || proId = 0 then
                    set num = num + 1;
                    begin
                        insert into equipmentproperty(equtpropertyname, equtfk, equtpropertyvalue, epvaluetype,
                                                      equtpropertydesc,
                                                      vuom)
                        values ('运行时间', paramEqutFk, runTime, 'NumberType', '运行时间', '秒');
                    end;
                else
                    set num = num + 1;
                    begin
                        update equipmentproperty
                        set EqutPropertyValue = runTime
                        where equipmentproperty.EqutFK = paramEqutFk
                          and EqutPropertyName = '运行时间';
                    end;
                end if;
            end;
        end if;
        if equtFk is not null && equtFk <> ''
        then
            begin
                # 参数 EqutFK不为空, 执行一次,就退出整个循环
                leave read_loop;
            end;
        end if;
#             有loop 就一定要有end loop
    end loop;
    # 关闭游标
    close cur;

END;



# 使用游标

声明游标

DECLARE cur CURSOR FOR (select EuptPK, EqutName from equipments);

  1. 游标的 sql 语句中,不能有动态参数。
  2. 游标的声明,一定是在存储过程的变量声明处(前面不能存在任何变量的计算等操作)
  3. 使用游标前需要 open [游标标识], 结束需要 close [游标标识]
  4. fetch cur into v_euptPk, v_equtName; 每执行一次该语句,游标都会指向下一行记录数据(相当于数组的下一项)

注意:

declare continue HANDLER FOR NOT FOUND set done = 1;

此 sql 语句是为在游标循环结束后将标志位置为 1,但是如果使用了 select into 的语句,且返回数据为空,则会同样将标志位置 1,导致游标循环提前结束