我想基於它們之間的外鍵構建表的依賴關係圖。此圖需要以任意表名作爲其根。我可以用給定的表名查找使用all_constraints視圖引用它的表,然後查找引用它們的表等等,但這樣做效率太差。我寫的,這是否對所有表遞歸查詢,但是當我補充一下:使用遞歸查詢構建表依賴關係圖
START WITH Table_Name=:tablename
它不會返回整個樹。
我想基於它們之間的外鍵構建表的依賴關係圖。此圖需要以任意表名作爲其根。我可以用給定的表名查找使用all_constraints視圖引用它的表,然後查找引用它們的表等等,但這樣做效率太差。我寫的,這是否對所有表遞歸查詢,但是當我補充一下:使用遞歸查詢構建表依賴關係圖
START WITH Table_Name=:tablename
它不會返回整個樹。
select parent, child, level from (
select parent_table.table_name parent, child_table.table_name child
from user_tables parent_table,
user_constraints parent_constraint,
user_constraints child_constraint,
user_tables child_table
where parent_table.table_name = parent_constraint.table_name
and parent_constraint.constraint_type IN('P', 'U')
and child_constraint.r_constraint_name = parent_constraint.constraint_name
and child_constraint.constraint_type = 'R'
and child_table.table_name = child_constraint.table_name
and child_table.table_name != parent_table.table_name
)
start with parent = 'DEPT'
connect by prior child = parent
應該工作(更換表名,當然)假設這一切都是在同一個模式。如果您需要處理跨架構依賴性,請爲OWNER和R_OWNER列使用數據字典表和條件的DBA_版本。在進一步的反思中,這並沒有考慮到自我指涉約束(即MGR列引用EMPNO列的EMP表上的約束),因此如果需要處理,您必須修改代碼以處理該案例有自我指涉的限制。
出於測試目的,我增加了一些新表SCOTT模式也引用DEPT表(包括孫子依賴)
SQL> create table dept_child2 (
2 deptno number references dept(deptno)
3 );
Table created.
SQL> create table dept_child3 (
2 dept_child3_no number primary key,
3 deptno number references dept(deptno)
4 );
Table created.
SQL> create table dept_grandchild (
2 dept_child3_no number references dept_child3(dept_child3_no)
3 );
Table created.
並驗證該查詢返回預期輸出
SQL> ed
Wrote file afiedt.buf
1 select parent, child, level from (
2 select parent_table.table_name parent, child_table.table_name child
3 from user_tables parent_table,
4 user_constraints parent_constraint,
5 user_constraints child_constraint,
6 user_tables child_table
7 where parent_table.table_name = parent_constraint.table_name
8 and parent_constraint.constraint_type IN('P', 'U')
9 and child_constraint.r_constraint_name = parent_constraint.constraint_name
10 and child_constraint.constraint_type = 'R'
11 and child_table.table_name = child_constraint.table_name
12 and child_table.table_name != parent_table.table_name
13 )
14 start with parent = 'DEPT'
15* connect by prior child = parent
SQL>/
PARENT CHILD LEVEL
------------------------------ ------------------------------ ----------
DEPT DEPT_CHILD3 1
DEPT_CHILD3 DEPT_GRANDCHILD 2
DEPT DEPT_CHILD2 1
DEPT EMP 1
最簡單的方式做,這是所有的FK信息複製到一個簡單的,2列(父母,子女)表,然後用下面的算法:
while (rows left in that table)
list = rows where table name exists in child but not in parent
print list
remove list from rows
僅此而已。基本上,您首先打印並刪除所有不依賴於任何內容的節點。在完成之後,其他一些節點將獲得免費,您可以重複流程。
P.S.確保你不插入自引用表中的初始列表(子=父)
當我運行該查詢,我得到`ORA-01437:不能與CONNECT BY` – 2013-06-20 18:57:25