使用mysql 游标,快速删除子节点及其附属节点
admin
2023-05-18 12:01:53
0

上篇,我写了如何使用html展示数据库中存储的树形结构, 本篇我将说一下如何通过存储过程,快速删除一个树节点及其附属节点。网上已经有非常多的关于mysql 游标使用的文章了, 为什么我还要写这篇文章呢,我主要是想表达一些在软件设计领域的一些想法。

一直不太赞同在数据库中大量的使用存储过程, 因为随着软件系统的复杂度逐渐提高,维护的难度会逐渐的增大。而且大批量的使用存储过程,不利于后期通过分布式部署应用程序来解决日益增多的业务需求。

我推荐把存储过程仅用在处理一些不包含太多业务,批量操作数据的场景中,因为这样可以避免应用程序频繁的访问数据库。删除一个树的子节点正好符合这一场景。

我们知道删除一个树节点的同时,需要删除其子节点或叶子节点。通过使用mysql的游标,我们可以遍历某一节点的所有子节点,通过使用递归,我们可以跨越多层直至叶子节点。

要实现删除一个树节点, 一个存储过程肯定可以搞定,但是为了让程序逻辑更简单些, 我写了两个存储过程,一个用来获取存储过程所有符合条件的节点,另一个用来执行删除操作。

遍历节点,找出符合节点及其所有的子节点的实现是这样的。

/* 创建一个获取树节点及其子节点的函数,并以 节点id1, 节点id2 的形式返回 */
DROP PROCEDURE IF EXISTS get_tree_node;
CREATE  PROCEDURE get_tree_node(IN node_id INT, OUT result VARCHAR(2000))
BEGIN      
    DECLARE nodeid INT(50);  
  DECLARE done INT DEFAULT 0;  
     DECLARE cur CURSOR FOR SELECT id FROM treenodes WHERE pid = node_id;
    DECLARE CONTINUE HANDLER FOR NOT found SET done = TRUE;

  # 这一句非常重要, 他可以保证存储过程至少会返回一个根节点id,调用 CONCAT_WS 函数时就不会出错了
  SELECT id INTO result FROM treenodes WHERE id= node_id;

  OPEN cur;
  REPEAT
            FETCH cur INTO nodeid;                     
      # 避免多一条记录
      IF done <> 1 THEN                
        # 调用递归函数获取节点下的子节点
        CALL get_tree_node(nodeid, @temp);            
        # 合并父节点和子节点的id
                SELECT CONCAT_WS(",", result, @temp) INTO result;
            END IF;
    UNTIL done END REPEAT;  
  # 关闭光标
    CLOSE cur;

END;

删除树节点的存储过程是这个样子的

/* 删除一个节点及其附属节点 */
DROP PROCEDURE IF EXISTS delete_tree_node;
CREATE PROCEDURE delete_tree_node(IN node_id int)
BEGIN
    SET  max_sp_recursion_depth = 10;
    CALL get_tree_node(node_id, @result);
    DELETE FROM treenodes WHERE FIND_IN_SET(id, @result);
    DELETE FROM books WHERE FIND_IN_SET(id, @result);
END

这里注意 max_sp_recursion_depth 这个msyql 参数 和 FIND_IN_SET 函数。

max_sp_recursion_depth 控制可以执行递归的层数,

FIND_IN_SET 函数的作用,会将@result 先变为一个字符串列表,再查找复合条件的值。这里若用 IN 关键字的话,将得不到任何结果

附件:http://down.51cto.com/data/2366729

相关内容

热门资讯

浙江宣传评文艺圈“塌房”:人品... 近几年来,文艺圈人品“塌房”事件屡有发生,从言行失范、私德有亏到违法犯罪,当创作者的德行有了污点,其...
伊朗看到了美国的3个软肋 全世界现在哭笑不得。刚扬言要狠狠打击伊朗,打击伊朗的能源基础设施,甚至感觉迫在眉睫、必须要打、不打不...
接连反转!特朗普透露三个信息 特朗普称美伊3日将举行谈判。美国总统特朗普当地时间8月2日,美国总统特朗普谈及伊朗时称,关于霍尔木兹...
河南深夜通报:查实作弊 针对近期备受关注的2026年河南省“三支一扶”计划招募相关舆情,河南省“三支一扶”领导小组协调办公室...
高通机器人演示翻车,DeepM... 人形机器人领域正呈现出截然不同的两面性。一端是高通(Qualcomm)机器人的尴尬演示:在展示搭载最...
小米多款主力手机涨价,店员:很... 8月2日,小米商城显示,多款手机主力机型价格上调300元至500元不等。其中,REDMI Turbo...
主持人陈璇采访《奥德赛》主创人... 诺兰新片《奥德赛》周四举行北京首映礼,上海外语频道主持人陈璇采访外籍主创人员时半蹲弯腰,背对镜头,向...
初创公司推Arm架构AI服务器... 由前谷歌和Meta工程师于2023年创立的Majestic Labs,近日发布了一款旨在挑战英伟达G...
日元跌跌不休,美国罕见出手,外... 【环球时报驻日本特约记者 王军】在日元跌至近40年来最低水平后,日本政府和日本银行连续出手干预汇市,...
特朗普再提珍珠港事件 据朝日电视台8月3日报道,美国总统特朗普表示,美国政府出手买入日元实施汇率干预,目的是帮扶日本。2日...