简体   繁体   中英

Drop foreign key in table with no constraint name - oracle

How can i drop the foreign key that references customer when the foreign key constraint has no name?

create table purchased (
    custnum int,
    stocknum int, 
    pdate date,
    primary key (custnum, stocknum, pdate),
    foreign key (custnum) references customer,
    foreign key (stocknum) references widget
); 

I've tried the following and it returns no data

select constraint_name
from user_cons_columns
where table_name = 'purchased'
and column_name = 'custnum';

Your are (correclty) using nonquoted identifiers in your DDL - ie purchased and not "purchased" - so the tabel and column names appear in the data dictionary in their default upper case. You need to match that case in your query:

select constraint_name
from user_cons_columns
where table_name = 'PURCHASED'
and column_name = 'CUSTNUM';

But that gives you two results here, because the column is also in the primary key. So you can narrow it down by restricting to referential-type constraints:

select uc.constraint_name
from user_constraints uc
join user_cons_columns ucc on ucc.constraint_name = uc.constraint_name
where uc.table_name = 'PURCHASED'
and uc.constraint_type = 'R'
and ucc.column_name = 'CUSTNUM';

db<>fiddle

You could also identify the primary key (type P) of the foreign table and then look for the referential constraint (type R) which has that as the R_CONSTRAINT_NAME value; something like:

select ucr.constraint_name
from user_constraints ucp
join user_constraints ucr on ucr.r_constraint_name = ucp.constraint_name
where ucp.table_name = 'CUSTOMER'
and ucp.constraint_type = 'P'
and ucr.table_name = 'PURCHASED'
and ucr.constraint_type = 'R';

db<>fiddle

That probably doesn't make a lot of difference here, but might be more useful for a compound key.

Either way you can then drop that constraint since you now know its name.

If you wanted to do it in one step you would need to use dynamic SQL.

You can look up the table all_constraints using the table name in uppercase.
Once you have the constraint name you can drop it. This works for named and automatically named constraints.

 create table parent( id int primary key);
  
 create table child( id int, constraint fk_id foreign key (id) references parent(id));
  
 select * from all_constraints where table_name = 'CHILD' or table_name = 'PARENT'
 OWNER | CONSTRAINT_NAME | CONSTRAINT_TYPE | TABLE_NAME | SEARCH_CONDITION | SEARCH_CONDITION_VC | R_OWNER | R_CONSTRAINT_NAME |  DELETE_RULE | STATUS | DEFERRABLE | DEFERRED | VALIDATED | GENERATED | BAD | RELY | LAST_CHANGE | INDEX_OWNER |  INDEX_NAME |  INVALID | VIEW_RELATED | ORIGIN_CON_ID:-------------------------- |:-------------- |:-------------- |:--------- |:--------------- |:------------------ |:-------------------------- |:---------------- |:---------- |:------ |:------------- |:-------- |:-------- |:------------- |:--- |:--- |:---------- |:-------------------------- |:------------ |:------ |:----------- |  ------------: FIDDLE_ECQIUQOOODNYCCRTUKLB |  FK_ID |  R |  CHILD | null |  null |  FIDDLE_ECQIUQOOODNYCCRTUKLB | SYS_C00113215 |  NO ACTION | ENABLED | NOT DEFERRABLE | IMMEDIATE | VALIDATED | USER NAME | null |  null |  05-APR-22 |  null |  null |  null |  null |  3 FIDDLE_ECQIUQOOODNYCCRTUKLB |  SYS_C00113215 |  P | PARENT | null |  null |  null |  null |  null |  ENABLED | NOT DEFERRABLE | IMMEDIATE | VALIDATED | GENERATED NAME | null |  null |  05-APR-22 |  FIDDLE_ECQIUQOOODNYCCRTUKLB | SYS_C00113215 |  null |  null |  3 

db<>fiddle here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM