问题
I have lots of tables and lots of relationships between them. When I try to make some join between them I'm stuck at finding the relationship between the two tables.
For the sake of simplicity let's say I have Table A and Table B. They are linked with a foreign key.
Q: How can I find the foreign key between this two exact tables and the column it references? And not all the tables or foreign keys that have a reference to this table.
回答1:
You can join the data dictionary constraint-related views to themselves and each other to find both ends of any referential constraints.
A bit rough but something like:
select uc1.constraint_name, uc1.table_name, ucc1.column_name,
uc2.constraint_name, uc2.table_name, ucc2.column_name
from user_constraints uc1
join user_cons_columns ucc1 on ucc1.constraint_name = uc1.constraint_name
join user_constraints uc2 on uc2.constraint_name = uc1.r_constraint_name
join user_cons_columns ucc2 on ucc2.constraint_name = uc2.constraint_name
and ucc2.position = ucc1.position
where uc1.table_name in (<table1>, <table2>)
and uc1.constraint_type = 'R'
and uc2.table_name in (<table1>, <table2>)
and uc2.constraint_type in ('P', 'U');
I've assumed you might have compound keys, and don't know which way the relationship will be between the two tables - hence looking for either name in both filters in the here
clause. I've also simplified a bit by using user_tables
and even then ignoring the owner
column - if the references span schemas you can include that, and use the all_*
tables instead of the user_*
ones.
Quick demo:
create table t1 (
id number,
uniq1 number,
uniq2 number,
constraint t1_pk primary key (id),
constraint t1_uk unique (uniq1, uniq2)
);
create table t2 (
id number,
t1_id number,
t1_uniq1 number,
t1_uniq2 number,
constraint t2_fk_1 foreign key (t1_id) references t1 (id),
constraint t2_fk_2 foreign key (t1_uniq1, t1_uniq2) references t1 (uniq1, uniq2)
);
select uc1.constraint_name as foreign_key,
uc1.table_name as child_table,
ucc1.column_name as child_column,
ucc1.position,
uc2.constraint_name as pri_or_uniq_key,
uc2.table_name as parent_table,
ucc2.column_name as parent_column
from user_constraints uc1
join user_cons_columns ucc1 on ucc1.constraint_name = uc1.constraint_name
join user_constraints uc2 on uc2.constraint_name = uc1.r_constraint_name
join user_cons_columns ucc2 on ucc2.constraint_name = uc2.constraint_name
and ucc2.position = ucc1.position
where uc1.table_name in ('T1', 'T2')
and uc1.constraint_type = 'R'
and uc2.table_name in ('T1', 'T2')
and uc2.constraint_type in ('P', 'U')
order by foreign_key, position;
FOREIGN_KEY CHILD_TABLE CHILD_COLUMN POSITION PRI_OR_UNIQ_KEY PARENT_TABLE PARENT_COLUMN
----------- ----------- ------------ -------- --------------- ------------ -------------
T2_FK_1 T2 T1_ID 1 T1_PK T1 ID
T2_FK_2 T2 T1_UNIQ1 1 T1_UK T1 UNIQ1
T2_FK_2 T2 T1_UNIQ2 2 T1_UK T1 UNIQ2
回答2:
Although it is important to know where to find such an information, a GUI tool would help a lot.
What helps a lot more is a GUI tool that is capable of creating an ER diagram. You'd select tables and let that tool create it. Then you'd have the schema in front of you, with all the tables as rectangles and links between them as lines.
True - if there are many tables, the diagram will be a large one, it'll take time for it to be created and it probably won't be easy to read because tables won't be placed one next to another (depending on relationship between them). But, if you're patient enough, you'll rearrange it and actually benefit from it.
来源:https://stackoverflow.com/questions/53674824/how-to-find-specific-links-between-two-tables