5.9 Hierarchical queries

 < Day Day Up > 



5.9 Hierarchical queries

With Oracle CONNECT BY ... START WITH ...clause can be used to select data that has a hierarchical relationship, usually some sort of parent - child relationships. In Example 5-29, the table EMPLOYEES consists of just these attributes: parent and child. We make sure (by means of a unique constraint) that the child is unique within the table.

Example 5-29: Oracle hierarchical query

start example
 SELECT  substr(lpad(' ', level * 2) || emp_id,1,20) AS emp_id       , last_name       , emp_mgr_id       , level FROM  employees CONNECT BY PRIOR emp_id = emp_mgr_id START WITH emp_mgr_id IS NULL; EMP_ID               LAST_NAME            EMP_MGR_ID      LEVEL -------------------- -------------------- ---------- ----------   10000               Sands                                   1   10001               Marcus                   10000          2   10004               Polite                   10001          3   10005               Tenor                    10001          3   10002               January                  10000          2   10008               Even                     10002          3   10010               December                 10002          3   10011               August                   10002          3   10003               March                    10000          2   10006               Blonde                   10003          3   10007               Damon                    10003          3   10009               Ration                   10003          3 
end example

In the following we provide you a DB2 UDF to get the same result. The identity of each row is actually its encoded position in the hierarchy. This is arbitrary. The solution also assumes that the resulting sorting can be done based on the path. Here this works as long as not more than nine siblings exist on any given level. However, a simple formatting of the path to a specific number of digits per level can solve this problem.

The script uses SQL table functions. This capability however is only used for encapsulation and not required for function.

The function get_direct_childs() collects all immediate children of a node in the hierarchy and returns them together with their relative position to each other and in the tree; see Example 5-30.

Example 5-30: Computing of direct child data

start example
 CREATE FUNCTION get_direct_childs(code VARCHAR(30), parent INTEGER) RETURNS TABLE(code VARCHAR(30), id INTEGER) READS SQL DATA DETERMINISTIC NO EXTERNAL ACTION RETURN   SELECT code || '.' || RTRIM(CHAR(RANK() OVER (ORDER BY child_id))),   child_id     FROM (SELECT empno FROM emp           WHERE emp.mgr                 = get_direct_childs.parent)           AS T(child_id)! 
end example

The function get_rec_childs() contains the recursive logic. It starts with the root, which is provided by the caller, and then collects children until no more new children can be found. See Example 5-31.

Example 5-31: Hierarchical query with entry point

start example
 CREATE FUNCTION get_rec_childs(root INTEGER) RETURNS TABLE(code VARCHAR(30), id INTEGER) READS SQL DATA DETERMINISTIC NO EXTERNAL ACTION RETURN   WITH rec(code, id)     AS (VALUES(CAST('1' AS VARCHAR(30)), root)         UNION ALL         SELECT t.code, t.id           FROM rec, TABLE(get_direct_childs(rec.code, rec.id)) AS T)     SELECT code, id FROM rec ! 
end example

This function get_level() compute the hierarchy level of the current data; see Example 5-32.

Example 5-32: Compute hierarchy level

start example
 CREATE FUNCTION get_level(code VARCHAR(30)) RETURNS INTEGER DETERMINISTIC NO EXTERNAL ACTION RETURN   (length(code) - length(replace(code, '.', '')))! 
end example

You get the hierarchy tree with the UDF get_rec_childs(). As a parameter, you have to specify the root.

In Example 5-33 you see the use of the hierarchy function and its output with an adequate format.

Example 5-33: Sample use of hierarchical query

start example
 SELECT  T.code        ,T.id        ,substr(  (space(2 * get_level(code)) || employees.last_name)                 , 1                 , 20) as last_name        ,emp_mgr_id FROM  TABLE(get_rec_childs(10000)) AS T      ,employees where T.id = employees.emp_id ORDER BY code! CODE        ID          LAST_NAME            EMP_MGR_ID ----------- ----------- -------------------- ----------- 1                 10000  Sands                         - 1.1               10001  Marcus                    10000 1.1.1             10004  Polite                    10001 1.1.2             10005  Tenor                     10001 1.2               10002  January                   10000 1.2.1             10008  Even                      10002 1.2.2             10010  December                  10002 1.2.3             10011  August                    10002 1.3               10003  March                     10000 1.3.1             10006  Blonde                    10003 1.3.2             10007  Damon                     10003 1.3.3             10009  Ration                    10003 
end example



 < Day Day Up > 



Oracle to DB2 UDB Conversion Guide2003
Oracle to DB2 UDB Conversion Guide2003
ISBN: N/A
EAN: N/A
Year: 2004
Pages: 132

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net