表结构 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);
MYSQL 递归获取 子节点
最新推荐文章于 2023-05-29 18:09:23 发布