List of foreign keys and the tables they reference in Oracle DB
Here is an all-purpose script we use that has been incredibly handy.
Save it off so you can execute it directly (@fkeys.sql). It will let you search by Owner and either the Parent or Child table and show foreign key relationships. The current script does explicitly spool to C:\SQLRPTS so you will need to create that folder of change that line to something you want to use.
REM ########################################################################
REM ##
REM ## fkeys.sql
REM ##
REM ## Displays the foreign key relationships
REM ##
REM #######################################################################
CLEAR BREAK
CLEAR COL
SET LINES 200
SET PAGES 54
SET NEWPAGE 0
SET WRAP OFF
SET VERIFY OFF
SET FEEDBACK OFF
break on table_name skip 2 on constraint_name on r_table_name skip 1
column CHILDCOL format a60 head 'CHILD COLUMN'
column PARENTCOL format a60 head 'PARENT COLUMN'
column constraint_name format a30 head 'FK CONSTRAINT NAME'
column delete_rule format a15
column bt noprint
column bo noprint
TTITLE LEFT _DATE CENTER 'FOREIGN KEY RELATIONSHIPS ON &new_prompt' RIGHT 'PAGE:'FORMAT 999 SQL.PNO SKIP 2
SPOOL C:\SQLRPTS\FKeys_&new_prompt
ACCEPT OWNER_NAME PROMPT 'Enter Table Owner (or blank for all): '
ACCEPT PARENT_TABLE_NAME PROMPT 'Enter Parent Table or leave blank for all: '
ACCEPT CHILD_TABLE_NAME PROMPT 'Enter Child Table or leave blank for all: '
select b.owner || '.' || b.table_name || '.' || b.column_name CHILDCOL,
b.position,
c.owner || '.' || c.table_name || '.' || c.column_name PARENTCOL,
a.constraint_name,
a.delete_rule,
b.table_name bt,
b.owner bo
from all_cons_columns b,
all_cons_columns c,
all_constraints a
where b.constraint_name = a.constraint_name
and a.owner = b.owner
and b.position = c.position
and c.constraint_name = a.r_constraint_name
and c.owner = a.r_owner
and a.constraint_type = 'R'
and c.owner like case when upper('&OWNER_NAME') is null then '%'
else upper('&OWNER_NAME') end
and c.table_name like case when upper('&PARENT_TABLE_NAME') is null then '%'
else upper('&PARENT_TABLE_NAME') end
and b.table_name like case when upper('&CHILD_TABLE_NAME') is null then '%'
else upper('&CHILD_TABLE_NAME') end
order by 7,6,4,2
/
SPOOL OFF
TTITLE OFF
SET FEEDBACK ON
SET VERIFY ON
CLEAR BREAK
CLEAR COL
SET PAGES 24
SET LINES 100
SET NEWPAGE 1
UNDEF OWNER
Try this:
select * from all_constraints where r_constraint_name in (select constraint_name
from all_constraints where table_name='YOUR_TABLE_NAME');
This will travel the hierarchy of foreign keys for a given table and column and return columns from child and grandchild, and all descendant tables. It uses sub-queries to add r_table_name and r_column_name to user_constraints, and then uses them to connect rows.
select distinct table_name, constraint_name, column_name, r_table_name, position, constraint_type
from (
SELECT uc.table_name,
uc.constraint_name,
cols.column_name,
(select table_name from user_constraints where constraint_name = uc.r_constraint_name)
r_table_name,
(select column_name from user_cons_columns where constraint_name = uc.r_constraint_name and position = cols.position)
r_column_name,
cols.position,
uc.constraint_type
FROM user_constraints uc
inner join user_cons_columns cols on uc.constraint_name = cols.constraint_name
where constraint_type != 'C'
)
start with table_name = 'MY_TABLE_NAME' and column_name = 'MY_COLUMN_NAME'
connect by nocycle
prior table_name = r_table_name
and prior column_name = r_column_name;
The referenced primary key is described in the columns r_owner
and r_constraint_name
of the table ALL_CONSTRAINTS
. This will give you the info you want:
SELECT a.table_name, a.column_name, a.constraint_name, c.owner,
-- referenced pk
c.r_owner, c_pk.table_name r_table_name, c_pk.constraint_name r_pk
FROM all_cons_columns a
JOIN all_constraints c ON a.owner = c.owner
AND a.constraint_name = c.constraint_name
JOIN all_constraints c_pk ON c.r_owner = c_pk.owner
AND c.r_constraint_name = c_pk.constraint_name
WHERE c.constraint_type = 'R'
AND a.table_name = :TableName