MySQL

发布于 更新于

AI总结: 本文介绍了一个名为`DeleteChildren`的存储过程,该过程用于递归删除给定根节点ID的所有子节点及其相关记录。过程通过游标遍历所有子节点,并在删除每个子节点之前递归调用自身。为了防止递归深度超限,需要调整会话的`max_sp_recursion_depth`设置。改进建议包括在删除操作之前增加对`max_sp_recursion_depth`的检查,以避免在深度递归时出现错误,并在操作完成后将其重置为默认值。
CREATE DEFINER=`root`@`%` PROCEDURE `DeleteChildren`(IN rootId INT)  
BEGIN  
    DECLARE done INT DEFAULT 0;  
    DECLARE childId INT;  
    -- 定义游标遍历所有子节点  
    DECLARE cur CURSOR FOR SELECT id FROM system_menu WHERE parent_id = rootId;  
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;  

    OPEN cur;  
    read_loop: LOOP  
        FETCH cur INTO childId;  
        IF done THEN  
            LEAVE read_loop;  
        END IF;  
        -- 递归调用自身删除子节点的子节点  
        CALL DeleteChildren(childId);  
        -- 删除当前子节点  
        DELETE FROM system_menu WHERE id = childId;  
    DELETE FROM system_role_menu WHERE menu_id = childId;  
    END LOOP;  
    CLOSE cur;  
END  
SET SESSION max_sp_recursion_depth = 255;   
CALL DeleteChildren(4000);  
SET SESSION max_sp_recursion_depth = 0;   

SET SESSION max_sp_recursion_depth = 255; 解决以下报错
Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine DeleteChildren