Home » SQL & PL/SQL » SQL & PL/SQL » Is there such a thing as a recursive query??
Is there such a thing as a recursive query?? [message #22960] Thu, 07 November 2002 09:51 Go to next message
John Smith
Messages: 25
Registered: February 2002
Junior Member
Hi, I have the following table...
Folder Name   FolderID   ParentID
---------------------------------
Folder1          1        Root
Folder2          2           1  
Folder3          3           2
Folder4          4           1
Folder5          5           4
Folder6          6           1

Each folder gets a unique id(FolderID), and an ID that links it to a previous (or root) folder(ParentID).

The above table can be read as:  Folder1/Folder2/Folder3 
Folder1/Folder4/Folder5 
Folder1/Folder6


Currently, I am querying the entire database, and iterating through all the rows using JAVA, to build the directory path.
Is there a way to do a recursive query in SQL?

So as an example, If I was looking for the path of folder 5, It would find folder 4 as it's parent, and folder 1 as the parent of folder 4. Then it would pass back one row/column like so:

PATH
====
Folder1/Folder4/folder5

Or is the only way to do this through use of a programming language like (C, C++, JAVA, etc..)?
Re: Is there such a thing as a recursive query?? [message #22964 is a reply to message #22960] Thu, 07 November 2002 10:20 Go to previous messageGo to next message
Todd Barry
Messages: 4819
Registered: August 2001
Senior Member
It is called a hierarchical query in Oracle. In 9i, there is a SYS_CONNECT_BY_PATH function that would show the path from the bottom up (since that is where you are starting):

sql>select * from t;
 
       ID    PARENT NAME
--------- --------- ----------
        1         0 Folder 1
        2         1 Folder2
        3         2 Folder 3
        4         1 Folder 4
        5         4 Folder 5
        6         1 Folder 6
 
6 rows selected.
 
sql>select sys_connect_by_path(name, '/')
  2    from t
  3   where parent = 0 
  4   start with id = 5
  5   connect by prior parent = id;
 
SYS_CONNECT_BY_PATH(NAME,'/')
------------------------------------------------------------------------------
/Folder 5/Folder 4/Folder 1
 
1 row selected.


But since you want the path displayed from the top down and you are starting at the bottom, we can use PL/SQL to handle this (in both 8i and 9i):

sql>create or replace function showpath(p_id in t.id%type)
  2    return varchar2
  3  is
  4    v_path  varchar2(256);
  5  begin
  6    for r in (select name
  7                from t
  8               start with id = p_id
  9               connect by prior parent = id
 10               order by level desc) loop
 11                
 12      v_path := v_path || r.name || '/';            
 13    end loop;
 14    
 15    return (rtrim(v_path, '/'));
 16  end;
 17  /
 
Function created.
 
sql>select id, parent, showpath(id) path from t;
 
       ID    PARENT PATH
--------- --------- ------------------------------
        1         0 Folder 1
        2         1 Folder 1/Folder2
        3         2 Folder 1/Folder2/Folder 3
        4         1 Folder 1/Folder 4
        5         4 Folder 1/Folder 4/Folder 5
        6         1 Folder 1/Folder 6
 
6 rows selected.
 
sql>var x varchar2(30)
sql>exec :x := showpath(5)
 
PL/SQL procedure successfully completed.
 
sql>print x
 
X
--------------------------------
Folder 1/Folder 4/Folder 5
Re: Is there such a thing as a recursive query?? [message #22966 is a reply to message #22960] Thu, 07 November 2002 11:01 Go to previous message
John Smith
Messages: 25
Registered: February 2002
Junior Member
Thanks for your reply. I'm using TOAD 7.2 to run the sql commands, and it doesnt seem to support sys_connect_by_path.

The other way you showed doesn't work either (unless I'm doing something wrong). Is that calling multiple queries? If so, I am trying to minimize database calls, and would opt to read it into a large table and sort from there.

Thanks
Previous Topic: connect asp program with oracle
Next Topic: NO_DATA_FOUND in Cursor with a Select into
Goto Forum:
  


Current Time: Mon Apr 29 07:24:25 CDT 2024