| Child tables, grand child tables of a table [message #635562] |
Wed, 01 April 2015 05:04  |
pointers
Messages: 451 Registered: May 2008
|
Senior Member |
|
|
Hi,
I would like to list all the child tables->grand child tables -> grand grand child tables of a given table based on primary/foreign key relation.
I've the following query which works well.
I would like to know
1. if there is any other way of doing it
2. would like to know how to replace the function definition with a sub-query in the connect by clause so that I don't need to use function.
CREATE OR REPLACE FUNCTION my_func (p_in VARCHAR2)
RETURN VARCHAR2
AS
l_constraint_name VARCHAR2(200);
BEGIN
SELECT constraint_name INTO l_constraint_name
FROM dba_constraints
WHERE constraint_type = 'P'
AND table_name = p_in;
RETURN l_constraint_name;
END;
/
SELECT DISTINCT LTRIM(SYS_CONNECT_BY_PATH(table_name,'<----'),'<----')
,owner
,table_name
,constraint_name
,CONNECT_BY_ISCYCLE
FROM dba_CONSTRAINTS
START WITH table_name = 'TABLE_NAME' AND constraint_type='P'
CONNECT BY NOCYCLE my_func(PRIOR table_name) = r_constraint_name
AND owner = r_owner;
ORDER BY 1
Thank you.
Regards,
Pointers
|
|
|
|
| Re: Child tables, grand child tables of a table [message #635563 is a reply to message #635562] |
Wed, 01 April 2015 06:19   |
 |
Michel Cadot
Messages: 68776 Registered: March 2007 Location: Saint-Maur, France, https...
|
Senior Member Account Moderator |
|
|
Which remember an issue I asked to myself many years ago. 
Here's the script I got for the current schema:
Prompt By default starting tables are those that does not referenced other one
Accept Table_ CHAR PROMPT "Starting tables (% allowed)? "
Set Termout OFF
Column table_ NOPRINT NEW_VALUE Table_
Select nvl(upper('&Table_'),'*NO REF*') table_ from dual
/
Set Termout ON
Column line_ FORMAT A120 HEADING "Foreign Key Tree"
With
data as (
/* Les tables/cles etrangeres avec la table/contrainte referencee */
select decode(b.table_name, a.table_name, '*SELF REF*', b.table_name)
table_name,
b.constraint_name,
a.table_name r_table_name,
a.constraint_name r_unq_name
from user_constraints a, user_constraints b
where b.r_owner = a.owner
and b.r_constraint_name = a.constraint_name
and b.constraint_type = 'R'
and a.constraint_type in ('P', 'U')
union all
/* Les tables referencees ne referencant personne */
select a.table_name, null, null, null
from user_constraints a
where exists ( select 1 from user_constraints b
where b.r_owner = a.owner
and b.r_constraint_name = a.constraint_name
and b.constraint_type = 'R'
and a.constraint_type in ('P', 'U') )
and not exists ( select 1 from user_constraints b
where b.table_name = a.table_name
and b.constraint_type = 'R' )
)
Select lpad(' ',3*(level-1)) ||
decode(table_name, '*SELF REF*', r_table_name, table_name) ||
decode(r_table_name,
null, '',
' ('||constraint_name||' ref. '||
r_table_name||'/'||r_unq_name||')' )||
decode(table_name,
'*SELF REF*', ' ...',
decode(connect_by_iscycle, 1, ' ...'))
line_
from data
connect by nocycle prior table_name = r_table_name
start with ( '&Table_' = '*NO REF*' and r_table_name is null )
or ( '&Table_' != '*NO REF*' and table_name like '&Table_' )
/
("&Table_" SQL*Plus variable contains the table(s) which you want to start from (LIKE expression); "*SELF REF*" indicates the tables which reference themselves and "*NO REF*" is the value for "&Table_" to indicate all the tables which do not reference anyone.)
here's an example of execution:
SQL> @dispfk
By default starting tables are those that does not referenced other one
Starting tables (% allowed) ? dept
Foreign Key Tree
-------------------------------------------------------------------------
DEPT
EMP (EMP_DEPT_FK ref. DEPT/DEPT_PK)
EMP (EMP_EMP_FK ref. EMP/EMP_PK) ...
Have fun!
|
|
|
|
|
|