函数与存储过程

Eave 2025.07.13

用root账号授权当前账号有创建函数的权限

GRANT CREATE ROUTINE, ALTER ROUTINE, DROP ROUTINE ON `gramess`.* TO 'gramess'@'%';
FLUSH PRIVILEGES;

创建函数:格式化时长

DROP FUNCTION IF EXISTS `format_duration`;

DELIMITER $$

CREATE FUNCTION `format_duration`(seconds INT) RETURNS VARCHAR(100)
DETERMINISTIC
BEGIN
    DECLARE years INT;
    DECLARE days INT;
    DECLARE hours INT;
    DECLARE minutes INT;
    DECLARE secs INT;
    DECLARE result VARCHAR(100) DEFAULT '';
    DECLARE remaining_seconds INT DEFAULT seconds;

    -- 计算各时间单位(使用365天为一年)
    SET years = FLOOR(remaining_seconds / 31536000);  -- 365*24*3600
    SET remaining_seconds = remaining_seconds % 31536000;

    SET days = FLOOR(remaining_seconds / 86400);     -- 24*3600
    SET remaining_seconds = remaining_seconds % 86400;

    SET hours = FLOOR(remaining_seconds / 3600);
    SET remaining_seconds = remaining_seconds % 3600;

    SET minutes = FLOOR(remaining_seconds / 60);
    SET secs = remaining_seconds % 60;

    -- 智能拼接时间单位(仅当值>0时添加)
    IF years > 0 THEN
        SET result = CONCAT(result, years, '年');
    END IF;

    IF days > 0 THEN
        SET result = CONCAT(result, days, '天');
    END IF;

    IF hours > 0 THEN
        SET result = CONCAT(result, hours, '小时');
    END IF;

    IF minutes > 0 THEN
        SET result = CONCAT(result, minutes, '分');
    END IF;

    IF secs > 0 OR result = '' THEN  -- 处理全为0的情况
        SET result = CONCAT(result, secs, '秒');
    END IF;

    RETURN result;
END $$

DELIMITER ;

创建存储过程

DROP PROCEDURE IF EXISTS `LGS_INIT_15`;
DELIMITER $$
CREATE PROCEDURE `LGS_INIT_15`(IN begindate VARCHAR(12), IN enddate VARCHAR(12))
BEGIN
    DECLARE arowcount INT DEFAULT 0;
    DECLARE uid INT;

    -- 发货单关系表状态处理
    INSERT INTO `lgs_create_log`(id, begin_date, end_date, message) VALUES(NULL, begindate, enddate, '15.1发货单关系表状态处理开始...');
    SELECT LAST_INSERT_ID() INTO uid;

    UPDATE `lgs_take_delivery_rel` SET is_process = 1 WHERE is_process = 0;

    SELECT ROW_COUNT() INTO arowcount;
    UPDATE `lgs_create_log` SET message = CONCAT('15.1发货单关系表状态处理结束', arowcount) WHERE id = uid;



    -- 临时表数据清除
    INSERT INTO `lgs_create_log`(id, begin_date, end_date, message) VALUES(NULL, begindate, enddate, '15.2临时表[lgs_delivery_info_centre_temp]数据清除开始...');
    SELECT LAST_INSERT_ID() INTO uid;

    TRUNCATE TABLE `lgs_delivery_info_centre_temp`;

    SELECT ROW_COUNT() INTO arowcount;
    UPDATE `lgs_create_log` SET message = CONCAT('15.2临时表[lgs_delivery_info_centre_temp]数据清除结束', arowcount) WHERE id = uid;



    INSERT INTO `lgs_create_log`(id, begin_date, end_date, message) VALUES(NULL, begindate, enddate, '15.3临时表[lgs_delivery_bill_centre_temp]数据清除开始...');
    SELECT LAST_INSERT_ID() INTO uid;

    TRUNCATE TABLE `lgs_delivery_bill_centre_temp`;

    SELECT ROW_COUNT() INTO arowcount;
    UPDATE `lgs_create_log` SET message = CONCAT('15.3临时表[lgs_delivery_bill_centre_temp]数据清除结束', arowcount) WHERE id = uid;



    INSERT INTO `lgs_create_log`(id, begin_date, end_date, message) VALUES(NULL, begindate, enddate, '15.4 All Done');

COMMIT;

END $$
DELIMITER ;
DROP PROCEDURE IF EXISTS `LGS_INIT_10`;

DELIMITER $$
CREATE PROCEDURE `LGS_INIT_10`()
BEGIN

    -- 记录开始时间
    DECLARE starttime INT;

    DECLARE v_id INT;
    DECLARE v_start_date CHAR(8);
    DECLARE v_end_date CHAR(8);

    DECLARE m_id INT;


    -- 2. 声明游标(关联查询)
    DECLARE cur CURSOR FOR SELECT id, start_date, end_date FROM `lgs_create_cursor` WHERE `status` = 1 ORDER BY id ASC;

    -- 3. 声明 NOT FOUND 处理器
    -- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    SELECT COALESCE(MAX(id), 0) INTO m_id FROM `lgs_create_cursor` WHERE `status` = 1;

    -- 4. 打开游标
    OPEN cur;

    -- 5. 循环读取数据
    read_loop: LOOP
        FETCH cur INTO v_id, v_start_date, v_end_date;  -- 获取一行数据

        SELECT UNIX_TIMESTAMP() INTO starttime;

        -- 数据执行
        CALL LGS_INIT_11(v_start_date, v_end_date);
        CALL LGS_INIT_12(v_start_date, v_end_date);
        CALL LGS_INIT_13(v_start_date, v_end_date);
        CALL LGS_INIT_14(v_start_date, v_end_date);
        CALL LGS_INIT_15(v_start_date, v_end_date);

        UPDATE `lgs_create_cursor` SET duration = format_duration(UNIX_TIMESTAMP() - starttime), `status` = 2 WHERE id = v_id;

        IF v_id = m_id THEN
            LEAVE read_loop;       -- 退出循环
        END IF;
    END LOOP;

    -- 6. 关闭游标
    CLOSE cur;
END $$
DELIMITER ;