MYSQL 递归获取 子节点

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a919423654/article/details/78812348
表结构
create table `tb_xa_department` (
	`id` bigint (20),
	`department_name` varchar (150),
	`level` int (11),
	`parent_id` bigint (20),
	`vendor_id` bigint (20)
); 
DROP TEMPORARY TABLE IF EXISTS tempTableForChildNote;drop procedure if exists findAlldep;
CREATE PROCEDURE findAlldep(IN deptid BIGINT)
BEGIN
	-- 创建临时表  不能在这里删除 临时表,删除临时表会报错,或者 清空里面的数据也是可以的
	CREATE TEMPORARY TABLE tempTableForChildNote(
	  departmentId BIGINT
	);
--  这个是因为的 业务需要,需要把业务自身加进入		
 insert into tempTableForChildNote(departmentId) values(deptid);


	CALL findChildrenNote(deptid);
	
END


-- 查找 子节点
drop procedure if exists findChildrenNote;
CREATE PROCEDURE findChildrenNote(IN parentId BIGINT)
BEGIN


   DECLARE finished INT DEFAULT 0;
	 DECLARE childNote BIGINT;
	 DECLARE number INT DEFAULT 0;
   DECLARE cur CURSOR FOR SELECT id FROM tb_xa_department WHERE parent_id=parentId;
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;

-- 设置 递归的深度,不设置回报错
   SET @@max_sp_recursion_depth = 100; 


   OPEN cur;
   FETCH cur INTO childNote;
   WHILE finished = 0 DO
	--  不要使用 动态sql,不然会报错
	  -- SET @mysql = CONCAT('insert into tempTableForChildNote(departmentId) values(',childNote,')');
	  -- PREPARE stmt FROM @mysql;
	  -- EXECUTE stmt;	
	insert into tempTableForChildNote(departmentId) values(childNote);
	
	  set number = 0;
	  SELECT COUNT(*) INTO number FROM tb_xa_department WHERE parent_id=childNote;
	  IF number > 0 THEN
			CALL findChildrenNote(childNote); -- 这里递归
	  END IF;
		FETCH cur INTO childNote;  
   END WHILE;
   CLOSE cur;
END

--  创建方法 返回  查询的结果,系统设计  4000 长度够用
DROP FUNCTION IF EXISTS findAllNoteStr;
CREATE FUNCTION findAllNoteStr(parentId bigint)
RETURNS VARCHAR(4000) CHARSET utf8
BEGIN
      DECLARE result VARCHAR(4000);
			call findAlldep(parentId);
			select GROUP_CONCAT(departmentId)into result from tempTableForChildNote;
 			-- 如果是用 drop table 回报错,但是如如果是删除临时表旧不会报错(很奇怪)
			DROP TEMPORARY TABLE IF EXISTS tempTableForChildNote;
      RETURN result;  
END;

-- 这里测试调用,临时表是 每个 链接 创建,链接断开的时候会自动删除掉,因为我们 链接一直是在一个 链接中,所以需要我们在这里删除下
drop table tempTableForChildNote;
select findAllNoteStr(4);

 
 
 
 
 
 
 

猜你喜欢

转载自blog.csdn.net/a919423654/article/details/78812348