转载自:https://blog.csdn.net/mchdba/article/details/39277301。如需删除请及时联系
关于多级别菜单栏或者权限系统中部门上下级的树形遍历,oracle中有connect by来实现,mysql没有这样的便捷途径,所以MySQL遍历数据表是我们经常会遇到的头痛问题,下面通过存储过程来实现。
DROP TABLE IF EXISTS csdn.channel;
CREATE TABLE csdn.channel (
id INT(11) NOT NULL AUTO_INCREMENT,
cname VARCHAR(200) DEFAULT NULL,
parent_id INT(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO channel(id,cname,parent_id)
VALUES (13,'首页',-1),
(14,'TV580',-1),
(15,'生活580',-1),
(16,'左上幻灯片',13),
(17,'帮忙',14),
(18,'栏目简介',17);
DROP TABLE IF EXISTS channel;
-- pro_cre_childlist
DELIMITER $$
DROP PROCEDURE IF EXISTS csdn.pro_cre_childlist$$
CREATE PROCEDURE csdn.pro_cre_childlist(IN rootId INT,IN nDepth INT)
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE b INT;
DECLARE cur1 CURSOR FOR SELECT id FROM channel WHERE parent_id=rootId;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SET max_sp_recursion_depth=12;
INSERT INTO tmpLst VALUES (NULL,rootId,nDepth);
OPEN cur1;
FETCH cur1 INTO b;
WHILE done=0 DO
CALL pro_cre_childlist(b,nDepth+1);
FETCH cur1 INTO b;
END WHILE;
CLOSE cur1;
END$$
– pro_cre_parentlist
DELIMITER
INSERT INTO tmpLst VALUES (NULL,rootId,nDepth);
OPEN cur1;
FETCH cur1 INTO b;
WHILE done=0 DO
CALL pro_cre_parentlist(b,nDepth+1);
FETCH cur1 INTO b;
END WHILE;
CLOSE cur1;
END$$
– pro_cre_pathlist
DELIMITER
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SET max_sp_recursion_depth=12;
OPEN cur1;
FETCH cur1 INTO parentid,pathstr;
WHILE done=0 DO
CALL pro_cre_pathlist(parentid,delimit,pathstr);
FETCH cur1 INTO parentid,pathstr;
END WHILE;
CLOSE cur1;
END$$
DELIMITER ;
– pro_cre_pnlist
DELIMITER
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SET max_sp_recursion_depth=12;
OPEN cur1;
FETCH cur1 INTO parentid,pathstr;
WHILE done=0 DO
CALL pro_cre_pnlist(parentid,delimit,pathstr);
FETCH cur1 INTO parentid,pathstr;
END WHILE;
CLOSE cur1;
END$$
DELIMITER ;
– fn_tree_path
DELIMITER
SET @pathid=CAST(nid AS CHAR);
CALL pro_cre_pathlist(nid,delimit,@pathid);
RETURN @pathid;
END$$
– fn_tree_pathname
– 调用函数输出name路径
DELIMITER
– pro_show_childLst
DELIMITER
CALL pro_cre_childlist(rootId,0);
SELECT channel.id,CONCAT(SPACE(tmpLst.depth*2),'--',channel.cname) NAME,channel.parent_id,tmpLst.depth,fn_tree_path(channel.id,'/') path,fn_tree_pathname(channel.id,'/') pathname
FROM tmpLst,channel WHERE tmpLst.id=channel.id ORDER BY tmpLst.sno;
END$$
– pro_show_parentLst
DELIMITER
pro_show_parentLst
(IN rootId INT)
CALL pro_cre_parentlist(rootId,0);
SELECT channel.id,CONCAT(SPACE(tmpLst.depth*2),'--',channel.cname) NAME,channel.parent_id,tmpLst.depth,fn_tree_path(channel.id,'/') path,fn_tree_pathname(channel.id,'/') pathname
FROM tmpLst,channel WHERE tmpLst.id=channel.id ORDER BY tmpLst.sno;
END$$
mysql> CALL pro_show_childLst(-1);
+—-+———————–+———–+——-+————-+—————————-+
| id | NAME | parent_id | depth | path | pathname |
+—-+———————–+———–+——-+————-+—————————-+
| 13 | –首页 | -1 | 1 | -1/13 | 首页/ |
| 16 | –左上幻灯片 | 13 | 2 | -1/13/16 | 首页/左上幻灯片/ |
| 14 | –TV580 | -1 | 1 | -1/14 | TV580/ |
| 17 | –帮忙 | 14 | 2 | -1/14/17 | TV580/帮忙/ |
| 18 | –栏目简介 | 17 | 3 | -1/14/17/18 | TV580/帮忙/栏目简介/ |
| 15 | –生活580 | -1 | 1 | -1/15 | 生活580/ |
+—-+———————–+———–+——-+————-+—————————-+
6 rows in set (0.05 sec)
Query OK, 0 rows affected (0.05 sec)
CALL pro_show_childLst(13);
mysql> CALL pro_show_childLst(13);
+—-+———————+———–+——-+———-+————————-+
| id | NAME | parent_id | depth | path | pathname |
+—-+———————+———–+——-+———-+————————-+
| 13 | –首页 | -1 | 0 | -1/13 | 首页/ |
| 16 | –左上幻灯片 | 13 | 1 | -1/13/16 | 首页/左上幻灯片/ |
+—-+———————+———–+——-+———-+————————-+
2 rows in set (0.02 sec)
Query OK, 0 rows affected (0.02 sec)
mysql>
CALL pro_show_childLst(14);
mysql> CALL pro_show_childLst(14);
+—-+——————–+———–+——-+————-+—————————-+
| id | NAME | parent_id | depth | path | pathname |
+—-+——————–+———–+——-+————-+—————————-+
| 14 | –TV580 | -1 | 0 | -1/14 | TV580/ |
| 17 | –帮忙 | 14 | 1 | -1/14/17 | TV580/帮忙/ |
| 18 | –栏目简介 | 17 | 2 | -1/14/17/18 | TV580/帮忙/栏目简介/ |
+—-+——————–+———–+——-+————-+—————————-+
3 rows in set (0.02 sec)
Query OK, 0 rows affected (0.02 sec)
mysql>
CALL pro_show_childLst(17);
mysql> CALL pro_show_childLst(17);
+—-+——————+———–+——-+————-+—————————-+
| id | NAME | parent_id | depth | path | pathname |
+—-+——————+———–+——-+————-+—————————-+
| 17 | –帮忙 | 14 | 0 | -1/14/17 | TV580/帮忙/ |
| 18 | –栏目简介 | 17 | 1 | -1/14/17/18 | TV580/帮忙/栏目简介/ |
+—-+——————+———–+——-+————-+—————————-+
2 rows in set (0.03 sec)
Query OK, 0 rows affected (0.03 sec)
mysql>
mysql> CALL pro_show_childLst(18);
+—-+—————-+———–+——-+————-+—————————-+
| id | NAME | parent_id | depth | path | pathname |
+—-+—————-+———–+——-+————-+—————————-+
| 18 | –栏目简介 | 17 | 0 | -1/14/17/18 | TV580/帮忙/栏目简介/ |
+—-+—————-+———–+——-+————-+—————————-+
1 row in set (0.36 sec)
Query OK, 0 rows affected (0.36 sec)
mysql>
CALL pro_show_parentLst(-1);
mysql> CALL pro_show_parentLst(-1);
Empty set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
mysql>
CALL pro_show_parentLst(13);
mysql> CALL pro_show_parentLst(13);
+—-+———-+———–+——-+——-+———-+
| id | NAME | parent_id | depth | path | pathname |
+—-+———-+———–+——-+——-+———-+
| 13 | –首页 | -1 | 0 | -1/13 | 首页/ |
+—-+———-+———–+——-+——-+———-+
1 row in set (0.02 sec)
Query OK, 0 rows affected (0.02 sec)
mysql>
CALL pro_show_parentLst(14);
mysql> CALL pro_show_parentLst(14);
+—-+———+———–+——-+——-+———-+
| id | NAME | parent_id | depth | path | pathname |
+—-+———+———–+——-+——-+———-+
| 14 | –TV580 | -1 | 0 | -1/14 | TV580/ |
+—-+———+———–+——-+——-+———-+
1 row in set (0.02 sec)
Query OK, 0 rows affected (0.02 sec)
mysql>
CALL pro_show_parentLst(17);
mysql> CALL pro_show_parentLst(17);
+—-+———–+———–+——-+———-+—————+
| id | NAME | parent_id | depth | path | pathname |
+—-+———–+———–+——-+———-+—————+
| 17 | –帮忙 | 14 | 0 | -1/14/17 | TV580/帮忙/ |
| 14 | –TV580 | -1 | 1 | -1/14 | TV580/ |
+—-+———–+———–+——-+———-+—————+
2 rows in set (0.02 sec)
Query OK, 0 rows affected (0.02 sec)
mysql>
CALL pro_show_parentLst(18);
mysql> CALL pro_show_parentLst(18);
+—-+—————-+———–+——-+————-+—————————-+
| id | NAME | parent_id | depth | path | pathname |
+—-+—————-+———–+——-+————-+—————————-+
| 18 | –栏目简介 | 17 | 0 | -1/14/17/18 | TV580/帮忙/栏目简介/ |
| 17 | –帮忙 | 14 | 1 | -1/14/17 | TV580/帮忙/ |
| 14 | –TV580 | -1 | 2 | -1/14 | TV580/ |
+—-+—————-+———–+——-+————-+—————————-+
3 rows in set (0.02 sec)
Query OK, 0 rows affected (0.02 sec)
mysql>
参考网址:
http://jan.kneschke.de/projects/mysql/sp/sp_tree.sql
http://blog.csdn.net/ylqmf/article/details/5172901