循环,直到父值为空

时间:2016-05-18 09:42:39

标签: sql oracle oracle10g

我有两张桌子,tbl_folder

FOLDER_ID  FOLDER_NAME  PARENT_FOLDER_ID
1           Folder1
2           Folder1.1        1
3           Folder1.2        1
4           Folder1.1.1      2
5           Folder1.1.2      2
6           Folder1.2.1      3
7           Folder1.2.2      3

tbl_file

FILE_ID   FILE_NAME   PARENT_FOLDER_ID    ACTIVITY_ID
1         Abc.txt            5                2
2         PQR.txt            2                1
3         XYZ.txt            7                2

我正在传递activity_id作为过程的输入,从中我可以获得该活动ID的所有文件的parent_folder_id。我想使用tbl_folder中的数据获取该父文件夹的完整路径。

例如,如果我将2作为activity_id传递,那么我将获得两个文件:

  1. Abc.txt - 文件的父文件夹ID为5
  2. XYZ.txt - 文件的父文件夹ID为7
  3. parent_folder_id我将获得该文件夹的名称,例如Folder1.1.2。 我将选择该文件夹parent_folder_id并获取其名称和父级,依此类推。最后,我将为Abc.txt生成Folder1\Folder1.1\Folder1.1.2的路径。

    这样做的正确方法是什么?我应该使用循环吗?还是一张临时桌子?或其他什么?

1 个答案:

答案 0 :(得分:5)

您可以使用hierarchical query获取每个文件夹的完整路径:

select folder_id, sys_connect_by_path(folder_name, '/') as path
from tbl_folder
start with parent_folder_id is null
connect by parent_folder_id = prior folder_id;

 FOLDER_ID PATH                                   
---------- ----------------------------------------
         1 /Folder1                                
         2 /Folder1/Folder1.1                      
         4 /Folder1/Folder1.1/Folder1.1.1          
         5 /Folder1/Folder1.1/Folder1.1.2          
         3 /Folder1/Folder1.2                      
         6 /Folder1/Folder1.2/Folder1.2.1          
         7 /Folder1/Folder1.2/Folder1.2.2       

sys_connect_by_path function正在为你构建完整路径。

您可以加入tbl_file来获取每个文件的完整路径:

select f.file_name, h.path
from tbl_file f
join (
  select folder_id, sys_connect_by_path(folder_name, '/') as path
  from tbl_folder
  start with parent_folder_id is null
  connect by parent_folder_id = prior folder_id
) h
on h.folder_id = f.parent_folder_id
where f.activity_id = 2;

FILE_NAME  PATH                                   
---------- ----------------------------------------
Abc.txt    /Folder1/Folder1.1/Folder1.1.2          
XYZ.txt    /Folder1/Folder1.2/Folder1.2.2          

或者使用反斜杠并且根文件夹上没有前导斜杠(可以使用ltrim()删除),这更接近问题中的示例:

select f.file_name, ltrim(h.path, '\') as path
from tbl_file f
join (
  select folder_id, sys_connect_by_path(folder_name, '\') as path
  from tbl_folder
  start with parent_folder_id is null
  connect by parent_folder_id = prior folder_id
) h
on h.folder_id = f.parent_folder_id
where f.activity_id = 2;

FILE_NAME  PATH                                   
---------- ----------------------------------------
Abc.txt    Folder1\Folder1.1\Folder1.1.2           
XYZ.txt    Folder1\Folder1.2\Folder1.2.2           

在Oracle的更高版本中,您也可以使用递归子查询因子,但在10g中不可用。