Is there such a thing as a recursive query?? [message #22960] |
Thu, 07 November 2002 09:51 |
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 |
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 |
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
|
|
|