2008-09-17 11 views
4

두 테이블 간의 외래 키를 기반으로 테이블 종속성 그래프를 작성하려고합니다. 이 그래프는 루트로서 임의의 테이블 이름으로 시작해야합니다. 나는 테이블 이름을 통해 all_constraints 뷰를 사용하여 테이블을 참조한 다음이를 참조하는 테이블을 찾는 등의 작업을 수행 할 수 있지만 이는 비효율적 일 수 있습니다. 모든 테이블에 대해 이렇게하는 재귀 쿼리를 작성했지만 추가 할 때 :재귀 쿼리를 사용하여 테이블 종속성 그래프 작성

START WITH Table_Name=:tablename 

전체 트리를 반환하지 않습니다. 전부

while (rows left in that table) 
    list = rows where table name exists in child but not in parent 
    print list 
    remove list from rows 

:이 작업을 수행하는

답변

8
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 테이블에 대한 제약)을 고려하지 않으므로 처리해야 할 경우 해당 사례를 처리하도록 코드를 수정해야합니다 자기 참조 제약이있다. 테스트 목적으로

, 나는 (손자 의존성 포함) 또한 DEPT 테이블을 참조하는 SCOTT 스키마에 대한 몇 가지 새로운 테이블

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 
+0

그 쿼리를 실행할 때'ORA-01437 : CONNECT BY와 결합 할 수 없습니다 .' –

+0

@ user1598390 - 정확한 테스트 케이스를 실행할 때 오류가 발생했다는 것을 말하고 있습니까? 아니면 뭔가 다른 것조차하고 있습니까? 코드를 보지 않으면, 우리가 당신을 도울 수있을 것 같지 않습니다. 아마도 사용하고있는 정확한 쿼리를 게시 할 수 있고 이상적으로 게시하는 일부 샘플 테이블로는 실패한 것으로 보이는 새로운 질문을 만들어야 할 것입니다. –

+0

SQL을 복사하여 Oracle 클라이언트 (PL/SQL Developer)에 붙여 넣은 다음 F8 키를 눌러 실행하고 오류가 발생합니다. –

2

가장 간단한 방법은 간단한 2 열 (부모, 자식) 테이블에 모든 FK 정보를 복사 한 후 다음과 같은 알고리즘을 사용하는 것입니다. 기본적으로, 당신은 먼저 인쇄물에 의존하지 않는 모든 노드를 제거하고 제거합니다. 그런 일이 끝나면 다른 노드가 무료로 제공되며 프로세스를 반복 할 수 있습니다.

P. 당신이 모든 것이 동일한 스키마에 가정 일을 (물론, 테이블 이름을 대체)해야한다 초기 목록 (아이 = 부모)