• mysql 树结构递归处理


    日常开发中我们经常会遇到树形结构数据处理,一般表结构通常会常用id,pid这种设计方案。

    之前用oracle、sqlServer数据库,用相应的语法即可获取树形结构数据(oracel:connect by prior ;sqlServer:with...as ...)。

    最近一个项目数据库用的是mysql,需求中含有获取树形结构数据的接口,由于之前没怎么用过mysql,于是第一时间就是查看mysql语法,看看有没有类似于oracle或sqlserver的递归语法,结果是没有,后来决定自定义数据库函数(暂时解决了需求)。

    1.自定义递归函数

    SET FOREIGN_KEY_CHECKS=0;
    
    -- ----------------------------
    -- Function structure for `getPartyChildOrg`
    -- ----------------------------
    DROP FUNCTION IF EXISTS `getPartyChildOrg`;
    DELIMITER ;;
    CREATE DEFINER=`root`@`%` FUNCTION `getPartyChildOrg`(orgid BIGINT) RETURNS varchar(4000) CHARSET utf8
    BEGIN
    DECLARE oTemp VARCHAR(4000);
    DECLARE oTempChild VARCHAR(4000);
     
    SET oTemp = '';
    SET oTempChild = CAST(orgid AS CHAR);
     
    WHILE oTempChild IS NOT NULL
    DO
    SET oTemp = CONCAT(oTemp,',',oTempChild);
    SELECT GROUP_CONCAT(id) INTO oTempChild FROM sub_party_orginfo WHERE logic_delete = 0 and FIND_IN_SET(pid,oTempChild) > 0;
    END WHILE;
    RETURN oTemp;
    END
    ;;
    DELIMITER ;
    

      暂时满足了需求,后期数据量大了,再加上主键生成策略生成的主键长度比较长,函数返回结果长度受VARCHAR最大长度限制,该方案会失效,导致查询的数据不全。

    2.自定义存储过程,将查询的结果存放到临时表中。

    SET FOREIGN_KEY_CHECKS=0;
    
    -- ----------------------------
    -- Procedure structure for `findPartyOrgChildList`
    -- ----------------------------
    DROP PROCEDURE IF EXISTS `findPartyOrgChildList`;
    DELIMITER ;;
    CREATE DEFINER=`root`@`%` PROCEDURE `findPartyOrgChildList`(IN pid VARCHAR(20))
    BEGIN
      DECLARE v_org BIGINT(20);
      DECLARE done INTEGER DEFAULT 0;
        -- 查询结果放入游标中
      DECLARE C_org CURSOR FOR SELECT d.id
                               FROM sub_party_orginfo d
                               WHERE d.pid = pid;
      DECLARE CONTINUE HANDLER FOR NOT found SET done=1;
      SET @@max_sp_recursion_depth = 10;
        
        -- 传入的组织id写入临时表
     INSERT INTO temp_party_org VALUES (pid);
      OPEN C_org;
      FETCH C_org INTO v_org;
      WHILE (done=0)
      DO
            -- 递归调用,查找下级
        CALL findPartyOrgChildList(v_org);
        FETCH C_org INTO v_org;
      END WHILE;
      CLOSE C_org;
    END
    ;;
    DELIMITER ;
    
    -- ----------------------------
    -- Procedure structure for `findPartyOrgList`
    -- ----------------------------
    DROP PROCEDURE IF EXISTS `findPartyOrgList`;
    DELIMITER ;;
    CREATE DEFINER=`root`@`%` PROCEDURE `findPartyOrgList`(IN pid BIGINT(20))
    BEGIN
      DROP TEMPORARY TABLE IF EXISTS temp_party_org;
        -- 创建临时表
        CREATE TEMPORARY TABLE temp_party_org(id BIGINT(20));
        -- 清空临时表数据
        DELETE FROM temp_party_org;
        -- 发起调用
        CALL findPartyOrgChildList(pid);
       
    END
    ;;
    DELIMITER ;
    

      

  • 相关阅读:
    iOS 9 ContactsFramework
    performSelector延时调用导致的内存泄露
    ARC 下内存泄露的那些点
    CoreText.framework --- 基本用法
    edgesForExtendedLayout
    CocoaPods使用详细说明
    IOS开发笔记(11)IOS开发之NSLog使用技巧
    网页中调用JS与JS注入
    Block就像delegate的简化版
    转:UINavigationBar--修改导航栏返回按钮的文字
  • 原文地址:https://www.cnblogs.com/chao555/p/10820217.html
Copyright © 2020-2023  润新知