Storage of plsql-based code in the first root traversal tree with layer number

This article is from Li Mingzi's csdn blog( http://blog.csdn.net/free1985 For commercial reprints, please contact the blogger for authorization. For non-commercial reprints, please indicate the source.
Abstract: this paper introduces the implementation of plsql-based code storage in the first root traversal tree with layer number. The code in this paper is written in March 2014. In addition, this paper provides the storage process source code and sample examples of test table creation statement, insertion node, acquisition of direct child node, acquisition of self and descendant node, acquisition of path from root to designated node, deletion node and so on.

1 Storage Mode Introduction

The main idea of the storage method of the first root traversal tree with layer number is to maintain the hierarchical relationship of the tree structure by recording the sequence number of the first visit to the node in the first root traversal (hereinafter referred to as the left value) and the order number of the second visit in the backtracking (hereinafter referred to as the right value). From the concept of root traversal, we can see that the left value of the child node must be greater than the left value of the parent node, and the right value must be less than the right value of the parent node. Combined with sorting operation, it is easy to query tree data without recursion. In addition, on the basis of recording the left and right values, the method also maintains the layer number of the node to reduce the time complexity of querying the direct (parent) child nodes.
The storage structure of the first root traversal tree with layer numbers is shown in Table 1-1.

Table 1-1 Storage structure of first-root traversal tree with layer number

2 tabular statement

The table building statement of the first root traversal tree with layer number under Oracle is as follows.

CREATE TABLE TREE
(
    NODENAME   NVARCHAR2(50) NOT NULL, 
    LEVELNUM  NUMBER(8) NOT NULL, 
    LEFTVALUE   NUMBER(8) NOT NULL, 
    RIGHTVALUE  NUMBER(8) NOT NULL );

COMMENT ON TABLE TREE IS 'Traversal Tree with Layer First Root'
;
COMMENT ON COLUMN TREE.NODENAME   IS 'Node name'
;
COMMENT ON COLUMN TREE.LEVELNUM  IS 'Layer number, starting from 1'
;
COMMENT ON COLUMN TREE.LEFTVALUE   IS 'First root traversal left value'
;
COMMENT ON COLUMN TREE.RIGHTVALUE  IS 'First root traversal right value'
;

ALTER TABLE TREE ADD CONSTRAINT PK_NODENAME
    PRIMARY KEY (NODENAME)
;

3 Insert Node

3.1 Implementation
The insertion node stored procedure code is as follows:

procedure InsertNode --Insert Node
  (parentName in nvarchar2, --Parent node name, empty when inserting root
   nodeName  in nvarchar2 --Node name
   ) is
    parentRight TREE.RIGHTVALUE%type; --Right value of parent node
    parentLevel TREE.LEVELNUM%type; --Parent node hierarchy
  begin
    if parentName is null then
      insert into TREE values (nodeName, 1, 1, 2);
    else
      --Get the right value of the parent node
      select RIGHTVALUE, LEVELNUM
        into parentRight, parentLevel
        from TREE
       where NODENAME = parentName;
      update TREE
         set LEFTVALUE = LEFTVALUE + 2
       where LEFTVALUE > parentRight - 1;
      update TREE
         set RIGHTVALUE = RIGHTVALUE + 2
       where RIGHTVALUE > parentRight - 1;
      insert into TREE
      values
        (nodeName, parentLevel + 1, parentRight, parentRight + 1);
    end if;
  end InsertNode;

3.2 Test
For example, we want to create a tree as shown in Figure 3-1.

Figure 3-1 Test Case Tree Structure Diagram

To create the tree above, you can call the following sample code:

begin  
-- Call the procedure  
tree_package.InsertNode('', 'A');  
tree_package.InsertNode('A', 'B');  
tree_package.InsertNode('A', 'C');  
tree_package.InsertNode('A', 'D');  
tree_package.InsertNode('C', 'E');  
tree_package.InsertNode('C', 'F');  
tree_package.InsertNode('C', 'G');  
end;  

After executing the test code, the table record is updated to the state shown in Table 3-1.

Table 3-1 Table records after insertion of nodes

4 Get direct subnodes

4.1 Implementation
Get the direct child stored procedure code as follows:

procedure GetChildren --Get child nodes
  (parentName IN NVARCHAR2, --Parent Node Name
   children  OUT RETCURSOR --Child node name
   ) is
    parentLeft  TREE.LEFTVALUE%type; --Left value of parent node
    parentRight TREE.RIGHTVALUE%type; --Right value of parent node
    parentLevel TREE.LEVELNUM%type;
  begin
    select LEFTVALUE, RIGHTVALUE, LEVELNUM
      into parentLeft, parentRight, parentLevel
      from TREE
     where NODENAME = parentName;
    open children for
      select NODENAME
        from TREE
       where LEFTVALUE between parentLeft and parentRight
         and LEVELNUM = parentLevel + 1
       order by LEFTVALUE asc;
  end GetChildren;

4.2 Test
For example, we want to get the direct child node of node A and call GetChildren to get the cursor as shown in Table 4-1.

Table 4-1 Gets the result cursor of the direct child node

5 Get the current node and descendant node

5.1 Implementation
Get the stored procedure code for the current node and its descendants as follows:

  procedure GetDescendants --Getting descendant nodes
  (parentName IN NVARCHAR2, --Parent Node Name
   descendants  OUT RETCURSOR --Descendant node name
   )is
    parentLeft  TREE.LEFTVALUE%type; --Left value of parent node
    parentRight TREE.RIGHTVALUE%type; --Right value of parent node
  begin
    select LEFTVALUE, RIGHTVALUE
      into parentLeft, parentRight
      from TREE
     where NODENAME = parentName;
    open descendants for
      select NODENAME
        from TREE
       where LEFTVALUE between parentLeft and parentRight
       order by LEFTVALUE asc;
  end GetDescendants;

5.2 Test
For example, if we want to get node A and its descendants and call GetDescendants, we get the cursor as shown in Table 5-1.

Table 5-1 Gets the result cursor for the current node and its descendants

6 Gets the path from the root to the specified node

6.1 Implementation
Get the path stored procedure code from the root to the specified node as follows:

 procedure GetNodePath --Get the node path
  (node IN NVARCHAR2, --Node name
   nodePath OUT RETCURSOR --Node Path
   ) is
    nodeLeft  TREE.LEFTVALUE%type; --Node Left Value
    nodeRight TREE.RIGHTVALUE%type; --Right Value of Node
  begin
    select LEFTVALUE, RIGHTVALUE
      into nodeLeft, nodeRight
      from TREE
     where NODENAME = node;
    open nodePath for
      select NODENAME
        from TREE
       where LEFTVALUE <= nodeLeft
         and RIGHTVALUE >= nodeRight
       order by LEFTVALUE asc;
  end GetNodePath;

6.2 Test
For example, if we want to get the path from root to node G and call GetNodePath, the cursor we get is shown in Table 6-1.

Table 6-1 Returns Result Cursor from Root to Designated Node

7 Delete Nodes

7.1 Implementation
The stored procedure code for deleting nodes is as follows:

procedure DeleteNode --Delete nodes and their children
  (node IN NVARCHAR2 --Node name
   ) is
    nodeLeft     TREE.LEFTVALUE%type; --Node Left Value
    nodeRight    TREE.RIGHTVALUE%type; --Right Value of Node
    delNodeCount NUMBER; --Deleted Nodes
  begin
    select LEFTVALUE, RIGHTVALUE
      into nodeLeft, nodeRight
      from TREE
     where NODENAME = node;
    delNodeCount := (nodeRight - nodeLeft+1)/2;
    delete from TREE
     where LEFTVALUE >= nodeLeft
       and RIGHTVALUE <= nodeRight;
    update TREE
       set LEFTVALUE = LEFTVALUE - delNodeCount * 2
     where LEFTVALUE > nodeLeft;
    update TREE
       set RIGHTVALUE = RIGHTVALUE - delNodeCount * 2
     where RIGHTVALUE > nodeRight;
  end DeleteNode;

7.2 Test
For example, if we want to delete node C, the sub-nodes E, F and G of C will be deleted together. The deleted table record status is shown in Table 7-1.

Table 7-1 Table records after deleting nodes

Keywords: Stored Procedure less Oracle

Added by Replika on Fri, 14 Jun 2019 01:47:13 +0300