SELECT lpad( '+', (COUNT(parent.name)-1),'+')||node.name name FROM nested_category node, nested_category parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUPBY node.name,node.lft ORDERBY node.lft;
输出结果
1 2 3 4 5 6 7 8 9 10 11 12 13
NAME ---------------------------------- ELECTRONICS +TELEVISIONS ++TUBE ++LCD ++PLASMA +GAME CONSOLES +PORTABLE ELECTRONICS ++MP3 PLAYERS +++FLASH ++CD PLAYERS ++2 WAY RADIOS
如果我们想要在叶子节点下增加节点,我们得稍微修改一下查询语句。让我们在2 WAY RADIOS叶子节点下添加FRS节点吧:
--在叶子节点下增加节点 procedure add_child_node( cname nested_category.name%type, add_name nested_category.name%type ) is myLeft nested_category.lft%type ; BEGIN SELECT lft into myLeft FROM nested_category WHERE name = cname; UPDATE nested_category SET rgt = rgt +2WHERE rgt > myLeft; UPDATE nested_category SET lft = lft +2WHERE lft > myLeft; INSERTINTO nested_category(CATEGORY_ID, name, lft, rgt) VALUES(SEQ_CATEGORY.nextval, add_name, myLeft +1, myLeft +2); commit; exception when others then rollback; end;
EXECUTE pkg_category.add_child_node('2 WAY RADIOS','FRS');
SELECT lpad( '+', (COUNT(parent.name)-1),'+')||node.name name FROM nested_category node, nested_category parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUPBY node.name,node.lft ORDERBY node.lft;
输出结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14
NAME ---------------------------------- ELECTRONICS +TELEVISIONS ++TUBE ++LCD ++PLASMA +GAME CONSOLES +PORTABLE ELECTRONICS ++MP3 PLAYERS +++FLASH ++CD PLAYERS ++2 WAY RADIOS +++FRS
在这个例子中,我们扩大了新产生的父节点(2 WAY RADIOS节点)的右值及其所有它的右边节点的左右值,之后置新增节点于新父节点之下。正如你所看到的,我们新增的节点已经完全融入了嵌套集合中:
--删除叶子节点 procedure delete_leaf_node(leaf_name nested_category.name%type) is myLeft nested_category.lft%type ; myRight nested_category.rgt%type ; myWidth integer ; BEGIN SELECT lft , rgt , (rgt - lft+1) into myLeft , myRight, myWidth FROM nested_category WHERE name = leaf_name;
DELETEFROM nested_category WHERE lft BETWEEN myLeft AND myRight; UPDATE nested_category SET rgt = rgt - myWidth WHERE rgt > myRight; UPDATE nested_category SET lft = lft - myWidth WHERE lft > myRight; commit; exception when others then rollback; end;
SELECT lpad( '+', (COUNT(parent.name)-1),'+')||node.name name FROM nested_category node, nested_category parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUPBY node.name,node.lft ORDERBY node.lft;
输出结果
1 2 3 4 5 6 7 8 9 10 11 12 13
NAME -------------------------------------------------------------------------------- ELECTRONICS +TELEVISIONS ++TUBE ++LCD ++PLASMA +PORTABLE ELECTRONICS ++MP3 PLAYERS +++FLASH ++CD PLAYERS ++2 WAY RADIOS +++FRS
SELECT lpad( '+', (COUNT(parent.name)-1),'+')||node.name name FROM nested_category node, nested_category parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUPBY node.name,node.lft ORDERBY node.lft;
输出结果
1 2 3 4 5 6 7 8 9 10 11 12
NAME --------------------- ELECTRONICS +TELEVISIONS ++TUBE ++LCD ++PLASMA +CD PLAYERS +2 WAY RADIOS ++FRS
--增加平行节点 procedure add_node( cname nested_category.name%type, add_name nested_category.name%type ) is myRight nested_category.rgt%type ; BEGIN SELECT rgt into myRight FROM nested_category WHERE name = cname; UPDATE nested_category SET rgt = rgt +2WHERE rgt > myRight; UPDATE nested_category SET lft = lft +2WHERE lft > myRight; INSERTINTO nested_category(CATEGORY_ID,name, lft, rgt) VALUES(SEQ_CATEGORY.nextval,add_name, myRight +1, myRight +2); commit; exception when others then rollback; end;
--在叶子节点下增加节点 procedure add_child_node( cname nested_category.name%type, add_name nested_category.name%type ) is myLeft nested_category.lft%type ; BEGIN SELECT lft into myLeft FROM nested_category WHERE name = cname; UPDATE nested_category SET rgt = rgt +2WHERE rgt > myLeft; UPDATE nested_category SET lft = lft +2WHERE lft > myLeft; INSERTINTO nested_category(CATEGORY_ID, name, lft, rgt) VALUES(SEQ_CATEGORY.nextval, add_name, myLeft +1, myLeft +2); commit; exception when others then rollback; end;
--删除叶子节点 procedure delete_leaf_node(leaf_name nested_category.name%type) is myLeft nested_category.lft%type ; myRight nested_category.rgt%type ; myWidth integer ; BEGIN SELECT lft , rgt , (rgt - lft+1) into myLeft , myRight, myWidth FROM nested_category WHERE name = leaf_name;
DELETEFROM nested_category WHERE lft BETWEEN myLeft AND myRight; UPDATE nested_category SET rgt = rgt - myWidth WHERE rgt > myRight; UPDATE nested_category SET lft = lft - myWidth WHERE lft > myRight; commit; exception when others then rollback; end;
--删除该节点,而不删除该节点的子节点 procedure delete_node_only(node_name nested_category.name%type) is myLeft nested_category.lft%type ; myRight nested_category.rgt%type ; myWidth integer ; BEGIN SELECT lft , rgt , (rgt - lft+1) into myLeft , myRight, myWidth FROM nested_category WHERE name = node_name;
DELETEFROM nested_category WHERE lft = myLeft; UPDATE nested_category SET rgt = rgt -1, lft = lft -1WHERE lft BETWEEN myLeft AND myRight; UPDATE nested_category SET rgt = rgt -2WHERE rgt > myRight; UPDATE nested_category SET lft = lft -2WHERE lft > myRight; commit; exception when others then rollback; end;