0% found this document useful (0 votes)
377 views8 pages

Foreign Key Constraints

The document discusses foreign key constraints and how to identify them. It summarizes that foreign key constraints reference columns in parent tables from child tables to enforce referential integrity. The document then demonstrates creating sample tables with foreign key constraints and shows how to identify these constraints from the data dictionary.

Uploaded by

JP Vijaykumar
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
377 views8 pages

Foreign Key Constraints

The document discusses foreign key constraints and how to identify them. It summarizes that foreign key constraints reference columns in parent tables from child tables to enforce referential integrity. The document then demonstrates creating sample tables with foreign key constraints and shows how to identify these constraints from the data dictionary.

Uploaded by

JP Vijaykumar
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 8

FINDING FOREIGN KEY CONSTRAINTS

----------------------------------------------------------
Author JP Vijaykumar Oracle DBA
Date 02-24-2007
Many a time, the developer folks, find it difficult in deleting records from parent tables, when child
records reference them through foreign key (referential integrity) constraints.

Constraints validate the data. Without constraints, we are just storing invalid data.

For a developer to identify foreign key constraints and disabling them is a difficult task. Most of
the time, the application’s ER diagrams are not available to the developers. A brief description on
the foreign key (referential integrity) constraints will go a long way in identifying and disabling
these constraints.

THE DETAILS OF THE THREE TABLES I CREATED IN THIS DOCUMENT ARE


TEMP_JP1 PARENT TABLE
TEMP_JP2 CHILD TABLE
TEMP_JP3 CHILD TABLE
CHILD TABLES TEMP_JP2 AND TEMP_JP3 REFERENCE THE PARENT TABLE TEMP_JP1

Created a table TEMP_JP1, inserted one row.


create table temp_jp1(col1 number,col2 number);

insert into temp_jp1 values(1,2);

commit;

Created a second table TEMP_JP2. When I tried to create a foreign key(referential integrity)
constraint on the second table, I received error.
create table temp_jp2(col1 number);

SQL> alter table temp_jp2 add (constraint temp_jp2_fk


2 foreign key (col1) references temp_jp1(col1));
foreign key (col1) references temp_jp1(col1))
*
ERROR at line 2:
ORA-02270: no matching unique or primary key for this column-list
Unless a primary/unique key constraint is enabled on the parent key column, Oracle does not
allow enabling foreign key constraint on child key column. Primary/unique keys on the parent key
column will not allow duplicate values.

Created primary key index on the parent table TEMP_JP1(COL1).


alter table temp_jp1 add constraint temp_jp1_pk primary key(col1);

Created foreign key(referential integrity) constraint on the second table successfully and
inserted one row.

SQL> alter table temp_jp2 add (constraint temp_jp2_fk


2 foreign key (col1) references temp_jp1(col1));
Table altered.

insert into temp_jp2 values(1);

commit;

For demo purpose, created a third table TEMP_JP3.


create table temp_jp3(col2 number);

Tried to add a foreign key(referential integrity) constraint to the third table, TEMP_JP3.

SQL> alter table temp_jp3 add(constraint temp_jp3_fk


2 foreign key(col2) references temp_jp1(col2));
foreign key(col2) references temp_jp1(col2))
*
ERROR at line 2:
ORA-02270: no matching unique or primary key for this column-list

Again, make sure there are no duplicates in the parent key column, before enabling
foreign key(referential integrity constraints on a child key column.

Tried to add primary key index on the parent table TEMP_JP1.COL1. Duplicate primary keys are
not allowed in the parent table.

SQL> alter table temp_jp1 add constraint temp_jp1_pk primary key(col2);


alter table temp_jp1 add constraint temp_jp1_pk primary key(col2)
*
ERROR at line 1:
ORA-02260: table can have only one primary key

Ok, now I will add a unique key constraint on parent table TEMP_JP1’s
Col2. As the errors say, a table can have only one primary key constraint. A table can have
multiple unique key constraints.

SQL> alter table temp_jp1 add constraint temp_jp1_Uk unique (col2);

We are good to add a foreign key constraint on TEMP_JP3 table.


SQL> alter table temp_jp3 add(constraint temp_jp3_fk
2 foreign key(col2) references temp_jp1(col2));

Table altered.

Let us insert a row into TEMP_JP3 table.

SQL> insert into temp_jp3 values(1);


insert into temp_jp3 values(1)
*
ERROR at line 1:
ORA-02291: integrity constraint (JP.TEMP_JP3_FK) violated - parent key not
found

The enabled foreign key constraint will not allow inserting child records in the table, unless a
matching record is found in the parent table

SQL> insert into temp_jp3 values(2);

1 row created.

SQL> commit;

Commit complete.
In essence, constraints safeguard and validate the data.
Each parent record can have multiple child records, but each child can relate to ONLY one parent
record. That is why, Oracle want a PRIMARY/ UNIQUE KEY index created on the PRIMARY KEY
column of the PARENT TABLE. It is not mandatory to have such an index created on the CHILD
KEY column in the CHILD TABLE.

In our case, I could not enable foreign key constraints on TEMP_JP2 and TEMP_JP3 tables,
unless I first added a PRIMARY KEY constraint on TEMP_JP1.COL1 and a UNIQUE KEY
constraint on TEMP_JP1.COL2.
Now let us remove the records from the parent table TEMP_JP1.
SQL> truncate table temp_jp1;
truncate table temp_jp1
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys

SQL> Delete from temp_jp1;


Delete from temp_jp1
*
ERROR at line 1:
ORA-02292: integrity constraint (JP.TEMP_JP3_FK) violated - child record
found

The parent table can not be truncated, nor deleted, when foreign key(referential integrity)
constraint are referencing them.

From the data dictionary view all_constrains, I will start my investigation.

SQL> desc all_constraints


Name Null? Type
----------------------------------------- -------- ----------------------------
OWNER NOT NULL VARCHAR2(30)
CONSTRAINT_NAME NOT NULL VARCHAR2(30)
CONSTRAINT_TYPE VARCHAR2(1)
TABLE_NAME NOT NULL VARCHAR2(30)
SEARCH_CONDITION LONG
R_OWNER VARCHAR2(30)
R_CONSTRAINT_NAME VARCHAR2(30)
DELETE_RULE VARCHAR2(9)
STATUS VARCHAR2(8)
DEFERRABLE VARCHAR2(14)
DEFERRED VARCHAR2(9)
VALIDATED VARCHAR2(13)
GENERATED VARCHAR2(14)
BAD VARCHAR2(3)
RELY VARCHAR2(4)
LAST_CHANGE DATE
INDEX_OWNER VARCHAR2(30)
INDEX_NAME VARCHAR2(30)
INVALID VARCHAR2(7)
VIEW_RELATED VARCHAR2(14)

Remember, when we tried to truncate the table TEMP_JP1, we received an error that says
“ORA-02266: unique/primary keys in table referenced by enabled foreign keys”

Let us find out the constraints enabled on our parent table TEMP_JP1

SQL> select owner,constraint_name,constraint_type,table_name,r_owner,r_constraint_name


2 from all_constraints where constraint_type in (‘P’,’U’) and table_name='TEMP_JP1';

OWNER CONSTRAINT_NAME C TABLE_NAME R_OWNER R_CONSTRAINT_NAME


---------- --------------- - ---------- ---------- --------------------
JP TEMP_JP1_PK P TEMP_JP1
JP TEMP_JP1_UK U TEMP_JP1
Now we know the primary/unique key constraints enabled on our parent table TEMP_JP1.

The r_constraint_name( primary/unique constraint name in the parent table) column in


all_constraints view is referenced by the constraint_name (foreign key(referential integrity)
constraint in the child table), when the constraint_type is ‘R’. Using this definition, let us find out
all the foreign key(referential integrity) constraints referencing the TEMP_JP1 table:

SQL> select owner,constraint_name,constraint_type,table_name,r_owner,r_constraint_name


2 from all_constraints
3 where constraint_type='R'
4 and r_constraint_name in (select constraint_name from all_constraints
5 where constraint_type in ('P','U') and table_name='TEMP_JP1');

OWNER CONSTRAINT_NAME C TABLE_NAME R_OWNER R_CONSTRAINT_NAME


---------- --------------- - ---------- ---------- --------------------
JP TEMP_JP2_FK R TEMP_JP2 JP TEMP_JP1_PK
JP TEMP_JP3_FK R TEMP_JP3 JP TEMP_JP1_UK

Here in my sub-query, I am supplying ONLY the primary and unique key constraints types with
the qualifier “where constraint_type in (‘P’,’U’) “, as we had seen earlier, tha foreign key
constraints can only be enabled on a child table, when a PRIMARY/UNIQUE KEY constraint is
enabled on the parent table.

We had identified the foreign key constraints, that are referencing the parent table TEMP_JP1.

Let us try to disable the primary/unique key constraints on the table


SQL> alter table temp_jp1 disable constraint temp_jp1_pk;
alter table temp_jp1 disable constraint temp_jp1_pk
*
ERROR at line 1:
ORA-02297: cannot disable constraint (JP.TEMP_JP1_PK) - dependencies exist

Let us disable the unique key constraint from our parent table TEMP_JP1.
SQL> alter table temp_jp1 disable constraint temp_jp1_uk;
alter table temp_jp1 disable constraint temp_jp1_uk
*
ERROR at line 1:
ORA-02297: cannot disable constraint (JP.TEMP_JP1_UK) - dependencies exist

Now we understood that, as long as the foreign key constraints are enabled on the child tables,
the data in the parent table is protected.

If we need to manipulate the data in the parent table TEMP_JP1, first disable the foreign
key(referential integrity) constraints on the child tables that are referencing the parent table.

Now let us disable the foreign key(referential integrity) constraints on the child tables, identified
from our earlier query.

SQL> alter table temp_jp2 disable constraint temp_jp2_fk;


Table altered.

SQL> alter table temp_jp3 disable constraint temp_jp3_fk;

Table altered.

SQL> truncate table temp_jp1;

Table truncated.
We could successfully truncate the parent table, after disabling the foreign key constraints on the
child tables, that were referencing the parent table.

A ready built script to identify and disable/enable foreign key constraints on child tables.
SQL> select 'alter table '||a.owner||'.'||a.table_name||
2 ' disable constraint '||a.constraint_name||';'
3 from all_constraints a, all_constraints b
4 where a.constraint_type = 'R'
5 and a.r_constraint_name = b.constraint_name
6 and a.r_owner = b.owner
7 and b.table_name = 'TEMP_JP1';

'ALTERTABLE'||A.OWNER||'.'||A.TABLE_NAME||'DISABLECONSTRAINT'||
A.CONSTRAINT_NAME
--------------------------------------------------------------------------------
alter table JP.TEMP_JP3 disable constraint TEMP_JP3_FK;
alter table JP.TEMP_JP2 disable constraint TEMP_JP2_FK;
Hope the narrative had given a clear picture about foreign key constraints and how to handle the
problems, while manipulating the data in the parent table.

For the experienced:


SQL> INSERT INTO TEMP_JP1 VALUES(2,NULL);

1 row created.

SQL> INSERT INTO TEMP_JP3 VALUES(NULL);

1 row created.
SQL> INSERT INTO TEMP_JP3 VALUES(NULL);

1 row created.

SQL> insert into temp_jp1 values(null,null);


insert into temp_jp1 values(null,null)
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("JP"."TEMP_JP1"."COL1")

Please be careful: Primary / Unique key indexes, both do not allow duplicates in the column. All
primary key indexes are unique. A table can have only one Primary key index and can have
multiple unique key indexes. One main difference is that you can not insert NULL values into a
primary key constraint enabled column, where as you can insert NULL values into a unique key
constraint enabled column.

For this reason, if your parent key in the parent table is indexed with a unique key constraint, then
enable NOT NULL constraint on the parent key column.

SQL> alter table temp_jp1 modify(col2 not null);

Table altered.

SQL> insert into temp_jp1 values(2,null);


insert into temp_jp1 values(2,null)
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("JP"."TEMP_JP1"."COL2")

You might also like