2012-08-04 75 views
3

我想要根據角色(在其他表中指定)獲得子菜單munus &。 在角色的基礎上,如果我選擇了MenuIDs:1,2,5我應該得到M1,M2的所有子菜單,M2 & M3。 MenuParentID指定父級的MenuId。MySql遞歸邏輯

MenuID MenuParentID MenuName   MenuNavigateUrl  HasSubMenus 
1  -1    M1     1.aspx    0 
2  -1    M2     #      1 
3  2    M2.1    2.aspx    0 
4  2    M2.2    3.aspx    0 
5  -1    M3     #      1 
6  5    M3.1    #      1 
7  5    M3.2    #      1 
8  6    M3.1.1    4.aspx    0 
9  6    M3.1.2    5.aspx    0 
10  7    M3.2.1    6.aspx    0 
11  7    M3.2.2    7.aspx    0 
12  -1    M4     #      1 
13  12    M4.1    8.aspx    0 
14  12    M4.2    9.aspx    0 

這裏就是我所做的:

DELIMITER $$ 

DROP FUNCTION IF EXISTS `myDB`.`GetPermissions`$$ 

CREATE DEFINER=`root`@`%` FUNCTION `GetPermissions`(
rootMenuID int(11) 
) RETURNS varchar(200) CHARSET latin1 
BEGIN 
DECLARE menuIdList VARCHAR(100); 
DECLARE menu_id INT(11); 
DECLARE record_not_found INT DEFAULT 0; 
DECLARE getMenuCursor CURSOR FOR SELECT DISTINCT(MenuId) FROM MenuIdListTable; 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET record_not_found = 1; 
CREATE TEMPORARY TABLE MenuIdListTable(MenuId INT(11) NULL); 
SET menuIdList = ','; 
IF((SELECT COUNT(*) FROM menus WHERE MenuParentID = rootMenuID) > 0) THEN 
    INSERT INTO MenuIdListTable(MenuID) SELECT MenuID FROM menus WHERE  
MenuParentID = rootMenuID; 
    OPEN getMenuCursor; 
    read_loop: LOOP 
     FETCH getMenuCursor INTO menu_id; 
     IF record_not_found THEN 
      LEAVE read_loop; 
     END IF; 
     SET menuIdList = CONCAT(menuIdList,menu_id,','); 
    END LOOP read_loop; 
END IF; 
DROP TEMPORARY TABLE MenuIdListTable; 
SET menuIdList = SUBSTR(menuIdList,1,LENGTH(menuIdList)-1); 
RETURN menuIdList; 
END$$ 

DELIMITER ; 

但我不能夠申請遞歸的邏輯來獲取所有子菜單。例如,對於'M3'(MenuID = 5),我得到子菜單'M3.1'&'M3.2';但不是他們的子菜單。即對於'M3.1':'M3.1.1','M3.1.2'和'M3.2':'M3.2.1','M3.2.2'。 如果其中一個有子菜單,問題也會持續存在!請幫忙。

+0

爲什麼是MenuParentID爲-1?也爲Menue IDID 1,2,5你應該得到家庭,帳戶用戶和包禮儀的所有子菜單? – AnandPhadke 2012-08-04 07:20:25

+0

MenuParentID表示相應的菜單沒有父菜單。是的,我可以得到這些子菜單。如果他們有更多的子菜單,那麼我不會得到它。 – benjamin54 2012-08-04 07:25:59

+0

但是,當我們比較MenuParentID = rootMenuID,那麼它將不匹配,因爲menuparent id是-1。 – AnandPhadke 2012-08-04 08:03:17

回答

1

試試這個代碼hierarchicals:

DROP TABLE IF EXISTS temp; 
CREATE TABLE temp(id int,MenuID int,MenuName varchar(50),MenuParentID int,HasSubMenus int) SELECT (@id:[email protected]+1) as id,MenuID,MenuName,MenuParentID,HasSubMenus from menus, 
(SELECT @id:=0) id where MenuParentID = 5; 
select * from temp; 
DROP TABLE IF EXISTS output; 
CREATE TABLE output(MenuID int,MenuName varchar(50),MenuParentID int,HasSubMenus int) select MenuID,MenuName,MenuParentID,HasSubMenus from temp; 

SET @idmin = (SELECT min(id) from temp); 
SET @idmax = (SELECT max(id) from temp); 

WHILE @idmin <= @idmax DO 

INSERT INTO output(MenuID,MenuName,MenuParentID,HasSubMenus) 
select MenuID,MenuName,MenuParentID,HasSubMenus from menus where MenuParentID=(select MenuID from temp where id = @idmin); 

SET @[email protected]+1; 

END WHILE; 

select (@id:[email protected]) as id1,GROUP_CONCAT(MenuName,',') from output, (SELECT @id:=1) id1 group by id1; 
+0

它的工作。謝謝。 – benjamin54 2012-08-04 18:19:12

3

Aww從其他dbs缺少mysql的plsql或CTE的「connect by prior」的喜悅。

因爲我的大腦目前沒有全面分析你的mysql給出的功能能力,它只是拋出一個參考:http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/ 它指向你一些很好的解釋相關(有時邪惡......像樹形的結構中只有一個選擇)關於在MySQL