【SQL Server】存储过程 遍历树

存储过程递归树结构实现(某一节点下所有子节点)三种方式

2018年11月01日 15:08:41 peach桃 阅读数:75

最近项目中碰到需要写递归,就特意实现了集中实现方式,总结一下~

情景:通过给出的机构id,得到该机构id以及所有的子机构信息,机构id是UUID;

通过三种方式去实现,亲自实现过,可直接用:

第一种:通过多次操作数据库获得所有子机构信息。实现如下:

 
  1. /**

  2. * 递归获取某个机构id下面的所有子机构

  3. * @param comTreeBeanHashSet 节点集合

  4. * @param mechanismId 当前机构ID

  5. */

  6. private void findChildMechanisms(Set<ComTreeBean> comTreeBeanHashSet, String mechanismId) {

  7.  
  8. ComTreeBean dep=comTreeDao.findByMechanismId(mechanismId);

  9. List<ComTreeBean> comTreeBeans = new ArrayList<ComTreeBean>();

  10. comTreeBeans.add(dep);

  11. /**

  12. * 加入当前机构

  13. */

  14. comTreeBeanHashSet.addAll(comTreeBeans.stream().collect(Collectors.toList()));

  15. /**

  16. * 获取子机构

  17. */

  18. List<ComTreeBean> comTreeBeanPars = comTreeDao.findByParentId(mechanismId);

  19. for (ComTreeBean d : comTreeBeanPars) {

  20. /**

  21. * 递归子单位

  22. */

  23. findChildMechanisms(comTreeBeanHashSet, d.getUid());

  24. }

  25. }

第二种:不会多次操作数据库,通过一次查询,获取所有机构树信息,再从当前机构去递归获取所有子机构信息

 
  1. //子节点集合

  2. List<ComTreeBean> childMenu = new ArrayList<ComTreeBean>;

  3.  
  4. /**

  5. * 获取某个父节点下面的所有子节点

  6. * @param menuList

  7. * @param id 当前机构id

  8. * @return

  9. */

  10. public static List<ComTreeBean> treeMenuList(List<ComTreeBean> childMenu,

  11. List<ComTreeBean> menuList, String id){

  12. for(ComTreeBean mu: menuList){

  13. //遍历出父id等于参数的id,add进子节点集合

  14. if(id.equals(mu.getParComUid())){

  15. //递归遍历下一级

  16. treeMenuList(childMenu,menuList,mu.getUid());

  17. childMenu.add(mu);

  18. }

  19. }

  20. return childMenu;

  21. }

直接使用能获取所有子机构信息,但是不能获取传入机构信息,如果想保留当前传入id机构,在初始化子节点集合时放入当前机构即可,即为:

 
  1. //子节点集合

  2. List<ComTreeBean> childMenu = comTreeBeanList.stream().filter(comTreeBean ->

  3. pid.equals(comTreeBean.getUid())).collect(Collectors.toList());

当然,这两种方式都是机构树的数据不是很大,考虑到如果其他情况下,比如数据量大,就考虑使用第三种方式,通过创建存储过程实现,我也将其实现了一遍,表实例就不给出了,具体实现如下,可自己创建表实例实验:

第三种:存储过程

首先定义执行递归操作的存储过程,如下

 
  1. -- 首先定义执行递归操作的存储过程:findChildList

  2.  
  3. CREATE PROCEDURE findChildList(IN id varchar(100))

  4. BEGIN

  5. DECLARE v_dep varchar(100) DEFAULT -1;

  6. DECLARE done varchar(100) DEFAULT 0;

  7. DECLARE C_dep CURSOR FOR SELECT d.id FROM T_COM_INFO d WHERE d.par_com_uid = id;

  8. DECLARE CONTINUE HANDLER FOR NOT found set done=1;

  9. SET @@max_sp_recursion_depth = 10;

  10. INSERT INTO tmp_Dep VALUES (id);

  11. OPEN C_dep;

  12. FETCH C_dep INTO v_dep;

  13. WHILE (done =0)

  14. DO

  15. CALL findChildList(v_dep);

  16. FETCH C_dep INTO v_dep;

  17. END WHILE;

  18. END

然后定义调用递归操作的存储过程,如下

 
  1. -- 再定义调用递归操作的存储过程:findDepList

  2.  
  3. CREATE PROCEDURE findDepList(IN id varchar(100))

  4. BEGIN

  5.  
  6. DROP TEMPORARY TABLE IF EXISTS tmp_Dep;

  7. CREATE TEMPORARY TABLE tmp_Dep(depId varchar(100));

  8. DELETE FROM tmp_Dep;

  9. CALL findChildList(id);

  10. SELECT distinct tmp_Dep.depId,T_COM_INFO.com_name FROM tmp_Dep,T_COM_INFO where tmp_Dep.depId = T_COM_INFO.id order by depId;

  11. END

调用存储过程及删除存储过程,如下:

 
  1. call findDepList('45e9b12d-165f6037fad-9c1534b1e8dbb5a0c0ec3f70d24f9627')

  2.  
  3. drop procedure if exists findChildList

  4.  
  5. drop procedure if exists findDepList

具体就是这样,顺便给出本人写测试时,id为int类型的存储过程,如下

 
  1. -- 首先定义执行递归操作的存储过程:findChildList

  2.  
  3. CREATE PROCEDURE findChildList(IN id BIGINT)

  4. BEGIN

  5. DECLARE v_dep integer DEFAULT -1;

  6. DECLARE done integer DEFAULT 0;

  7. DECLARE C_dep CURSOR FOR SELECT d.id FROM treenodes d WHERE d.pid = id;

  8. DECLARE CONTINUE HANDLER FOR NOT found set done=1;

  9. SET @@max_sp_recursion_depth = 10;

  10. INSERT INTO tmp_Dep VALUES (id);

  11. OPEN C_dep;

  12. FETCH C_dep INTO v_dep;

  13. WHILE (done =0)

  14. DO

  15. CALL findChildList(v_dep);

  16. FETCH C_dep INTO v_dep;

  17. END WHILE;

  18. END

  19.  
  20. -- 再定义调用递归操作的存储过程:findDepList

  21.  
  22. CREATE PROCEDURE findDepList(IN id BIGINT)

  23. BEGIN

  24.  
  25. DROP TEMPORARY TABLE IF EXISTS tmp_Dep;

  26. CREATE TEMPORARY TABLE tmp_Dep(depId INTEGER);

  27. DELETE FROM tmp_Dep;

  28. CALL findChildList(id);

  29. SELECT distinct tmp_Dep.depId,treenodes.nodename FROM tmp_Dep,treenodes where tmp_Dep.depId = treenodes.id order by depId;

  30. END

  31.  
  32.  
  33. drop procedure if exists findChildList

  34.  
  35. drop procedure if exists findDepList

  36.  
  37.  
  38. call findDepList(3)

https://blog.csdn.net/peach_garden/article/details/83620345

猜你喜欢

转载自blog.csdn.net/xuheng8600/article/details/85321321
今日推荐