Fru*_*ner 4 oracle recursion recursive-query oracle10g
我有一个想法,我可以编写一个查询来查找根表的所有后代表,基于外键.
查询看起来像这样:
select level, lpad(' ', 2 * (level - 1)) || uc.table_name as "TABLE", uc.constraint_name, uc.r_constraint_name
from all_constraints uc
where uc.constraint_type in ('R', 'P')
start with uc.table_name = 'ROOT_TAB'
connect by nocycle prior uc.constraint_name = uc.r_constraint_name
order by level asc;
Run Code Online (Sandbox Code Playgroud)
结果我看起来像这样:
1 ROOT_TAB XPKROOTTAB
1 ROOT_TAB R_20 XPKPART_TAB
2 CHILD_TAB_1 R_40 XPKROOTTAB
2 CHILD_TAB_2 R_115 XPKROOTTAB
2 CHILD_TAB_3 R_50 XPKROOTTAB
这个结果是所有的子表ROOT_TAB,但查询不改乘的孩子CHILD_TAB_1,CHILD_TAB_2或CHILD_TAB_3.
递归查询对我来说是新的,所以我猜我在connect by条款中遗漏了一些东西,但我在这里画了一个空白.实际上是否可以ROOT_TAB在单个查询中获得完整的层次结构,或者我最好在递归过程中包装查询?
你想要这样的东西:
select t.table_name, level,lpad(' ', 2 * (level - 1))||t.table_name
from user_tables t
join user_constraints c1
on (t.table_name = c1.table_name
and c1.constraint_type in ('U', 'P'))
left join user_constraints c2
on (t.table_name = c2.table_name
and c2.constraint_type='R')
start with t.table_name = 'ROOT_TAB'
connect by prior c1.constraint_name = c2.r_constraint_name
Run Code Online (Sandbox Code Playgroud)
原始查询的问题是子表的uc.constraint_name是外键的名称.这对于将第一个子节点连接到根表是很好的,但是不需要将第二个节点上的子节点连接到第一个节点.这就是为什么你需要连接两次约束 - 一次获取表的主键,一次获取外键.
顺便说一句,如果您要查询all_*视图而不是user_*视图,通常需要将它们连接到table_name AND owner,而不仅仅是table_name.如果多个模式具有相同名称的表,则仅加入table_name将得到不正确的结果.
| 归档时间: |
|
| 查看次数: |
8132 次 |
| 最近记录: |