How to create two indexes for the same column that is both a primary and a foreign key? - oracle

From what I have been told and read online, I need to create an index for a foreign key even if this exact column already has an index as a primary key. But how to do that? If I simply use this
create index document_fk_i on document(id);
Won't it simply create a second identical index to the first one? (the first one was created automatically by Oracle)

You can't index the same column twice. If there's an index on document.id column because it is a primary key, then you don't (and can't) create another index which would be used for that column's "foreign key constraint" role.
Master table:
SQL> create table test_a (id number primary key);
Table created.
Detail table: ID is a primary key and Oracle will create an index:
SQL> create table test_b (id number primary key);
Table created.
Create a foreign key constraint from detail to master table:
SQL> alter table test_b add constraint fk_ba foreign key (id)
2 references test_a (id);
Table altered.
Try to create additional index on detail's ID column:
SQL> create index idxb on test_b (id);
create index idxb on test_b (id)
*
ERROR at line 1:
ORA-01408: such column list already indexed
SQL>

Related

How do I create a foreign key on two columns that are under the primary key constraint?

CREATE TABLE "RESEARCH_DEP"."RESEARCH_TV_COMPANY"
( "CID" NUMBER(38,0) NOT NULL ENABLE,
"SOURCE_ID" NUMBER(2,0),
CONSTRAINT "PK_RESEARCH_TV_COMPANY_1" PRIMARY KEY ("CID", "SOURCE_ID")
USING INDEX (CREATE UNIQUE INDEX "RESEARCH_DEP"."IDX_TV_COMPANY_CID_SOURCE_ID" ON "RESEARCH_DEP"."RESEARCH_TV_COMPANY" ("CID", "SOURCE_ID")
CREATE TABLE "RESEARCH_DEP"."RESEARCH_METRICS_PHARMA_AUD"
( "ID" NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE,
"SOURCE_ID" NUMBER(2,0) NOT NULL ENABLE,
"MEDIA_COMPANY_ID" NUMBER(*,0) NOT NULL ENABLE
)
NEED
ALTER TABLE RESEARCH_DEP.RESEARCH_METRICS_PHARMA_AUD
ADD CONSTRAINT fk_METRICS_PHARMA_AUD_TV_COMPANY_ID
FOREIGN KEY (MEDIA_COMPANY_ID,SOURCE_ID) REFERENCES RESEARCH_DEP.RESEARCH_TV_COMPANY(CID,SOURCE_ID);
ORA-02298: parent keys not found
DO I NEED TO CREATE A COMPOSITION COLUMN: CID,SOURCE_ID?
OR
create sequence of values two column oracle CID,SOURCE_ID ?
Your code is more or less OK:
SQL> create table research_tv_company
2 (cid number,
3 source_id number,
4 --
5 constraint pk_rtc primary key (cid, source_id)
6 );
Table created.
SQL> create table research_metrics_pharma_aud
2 (id number,
3 source_id number,
4 media_company_id number
5 );
Table created.
SQL> alter table research_metrics_pharma_aud
2 add constraint fk_rmpa_rtc
3 foreign key (media_company_id, source_id)
4 references research_tv_company (cid, source_id);
Table altered.
SQL>
Note that I
removed double quotes
removed NOT NULL for primary key columns (they can't be NULL anyway)
don't have any indexes created so Oracle will - along with table creation - create a primary key constraint AND unique index to support it
as I'm on 11gXE and it doesn't support identity columns, I removed that
from the second table; I'd have to enforce it via a trigger. You don't have to do anything about it, just saying (so that you wouldn't wonder where did it go?)
Error you got:
ORA-02298: parent keys not found
means that there are combinations of (media_company_id, source_id) in the second table that do not exist as pairs of (cid, source_id) in the first table. To illustrate it:
Drop the foreign key constraint first (otherwise, I wouldn't be able to do that):
SQL> alter table research_metrics_pharma_aud drop constraint fk_rmpa_rtc;
Table altered.
Insert a row into the first (master) table:
SQL> insert into research_tv_company (cid, source_id) values (1, 1);
1 row created.
Insert two rows into the second (detail) table; the first combination is valid, the second is not as (2, 2) don't exist in research_tv_company:
SQL> insert into research_metrics_pharma_aud (id, source_id, media_company_id) values (1, 1, 1);
1 row created.
SQL> insert into research_metrics_pharma_aud (id, source_id, media_company_id) values (2, 2, 2);
1 row created.
SQL>
If we try to create a foreign key constraint:
SQL> alter table research_metrics_pharma_aud
2 add constraint fk_rmpa_rtc
3 foreign key (media_company_id, source_id)
4 references research_tv_company (cid, source_id);
add constraint fk_rmpa_rtc
*
ERROR at line 2:
ORA-02298: cannot validate (SCOTT.FK_RMPA_RTC) - parent keys not found
SQL>
See? The same error you got.
What can you do?
insert missing primary key values into the master table, or
delete detail rows that violate the constraint, or
create the constraint, but instruct Oracle not to check whether existing rows are valid or not:
SQL> alter table research_metrics_pharma_aud
2 add constraint fk_rmpa_rtc
3 foreign key (media_company_id, source_id)
4 references research_tv_company (cid, source_id)
5 enable novalidate;
Table altered.
SQL>
The enable novalidate means that foreign key constraint will be enabled for any new or modified rows, but existing rows won't be checked. If that option suits you, use it. However, I believe that one of the first two option is better, with the first one - adding missing primary keys - being the best.

add composite/ foreign key in sqlplus

I have a very basic question regarding the Keys in SQL. I am trying to write an SQL statement so I can add the foreign key to my tables, however, it would always "table not found or missing". And the reason why I can't create that table is that the next table also has foreign keys from another table that I need to reference. Is there a way around it?
create table table_name (id char (3) primary key, name varchar (8));
SQL > table created.
create table table_name_2 (table2ID char (3) primary key, CID char (3),
name varchar (8), title varchar (8), foreign key (CID) references table_name_3);
SQL > missing table (table_name_3);
create table table_name_3 (CID char (3) primary key, tTitle varchar (8),
foreign key (phone) references table_name_4);
So I was only able to create table 3. What do I need to do so that I can create the table and add the foreign keys referencing while I write the SQL statements?
I am not ALLOWED to use ALTER table.
Create foreign keys separately, using the ALTER TABLE statement. Like this:
SQL> CREATE TABLE table_name(
2 id CHAR(3)PRIMARY KEY,
3 name VARCHAR(8)
4 );
Table created.
SQL> CREATE TABLE table_name_2(
2 table2id CHAR(3)PRIMARY KEY,
3 cid CHAR(3),
4 name VARCHAR(8),
5 title VARCHAR(8)
6 );
Table created.
SQL> CREATE TABLE table_name_3(
2 cid CHAR(3)PRIMARY KEY,
3 ttitle VARCHAR(8)
4 );
Table created.
Now the foreign key:
SQL> ALTER TABLE table_name_2 ADD CONSTRAINT fk_2_3 FOREIGN KEY(cid)
2 REFERENCES table_name_3;
Table altered.
SQL>
one approach you can od is to create the table with the Primary key and then do
and add the foreign key.
ALTER TABLE child_table
ADD CONSTRAINT fk_name
FOREIGN KEY (col1) REFERENCES parent_table(col1);

How to assign two foreign keys in child table ORACLE SQL?

How can I inherit from two(or more) parent classes in ORACLE SQL? I've tried something like this:
ID(13),
OTHER_ID(9),
CONSTRAINT FK_ID FOREIGN
KEY(ID) REFERENCES TABLE_ONE(ID),
CONSTRAINT FK_OTHER_GROUP FOREIGN
KEY(OTHER_ID) REFERENCES TABLE_TWO(OTHER_ID)
I've read the documentation and the code I've found is this one:
INDEX (product_category, product_id),
INDEX (customer_id),
FOREIGN KEY (product_category, product_id)
REFERENCES product(category, id)
ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (customer_id)
REFERENCES customer(id)
It doesn't quite work for me. Is there any special way to define these indexes? I haven't met them before. The first example had a problem that data types weren't specified. But I'd like someone to explain me how could I do it the second(oracle documentation) way.
This is how I understood the problem:
there are two tables, each having primary key constraint
in my example, those are t_emp and t_dept
there's also the third table whose columns are supposed to reference primary keys from previous two tables
those are fk_th_emp and fk_th_dep foreign key constraints
If that's so, here's how to do that:
SQL> create table t_emp
2 (empno number constraint pk_temp primary key,
3 ename varchar2(20)
4 );
Table created.
SQL> create table t_dept
2 (deptno number constraint pk_dept primary key,
3 dname varchar2(20)
4 );
Table created.
SQL> create table third
2 (id number constraint pk_third primary key,
3 other_id number,
4 --
5 constraint fk_th_emp foreign key (id) references t_emp (empno),
6 constraint fk_th_dep foreign key (other_id) references t_dept (deptno)
7 );
Table created.
SQL>

I'm trying to create foreign key between two tables but got: ORA-02270

Maybe I'm burnout, but I don't understand this. I have two tables in Oracle: TBL_a and TBL_x. I'm trying to create a foreign key between thos two tables as follows and get error
ORA-02270: no matching unique or primary key.
CREATE TABLE tbl_a (
cod_op integer,
cod_dni char(8),
cod_correl integer,
varchar2(50)
);
CREATE TABLE tbl_x (
cod_op integer,
cod_dni char(8),
blabla varchar2(50)
);
CREATE UNIQUE INDEX TBL_A_PK ON TBL_A (COD_OP);
CREATE UNIQUE INDEX TBL_x_PK ON TBL_x (COD_OP);
ALTER TABLE TBL_a ADD CONSTRAINT TBL_a_R01
FOREIGN KEY (COD_OP) REFERENCES TBL_x (COD_OP);
The problem is that you've created unique INDEXES on your tables, but you didn't create a unique or primary key CONSTRAINT. Oracle requires that the constraints exist in order to establish a foreign key relationship.
If you drop your existing indexes and add the appropriate constraints you can establish your foreign key relationship:
DROP INDEX TBL_A_PK;
DROP INDEX TBL_x_PK;
ALTER TABLE TBL_A
ADD CONSTRAINT UQ_A
UNIQUE(COD_OP)
USING INDEX;
ALTER TABLE TBL_X
ADD CONSTRAINT UQ_X
UNIQUE(COD_OP)
USING INDEX;
dbfiddle here
The table that is referred by the foreign key (here, tbl_x) must have a primary key or a unique constraint.
In your use case, as you are declaring a unique index on cod_op, you could simply make cod_op the primary key of tbl_x instead: that would make the error disappear.
Demo on DB Fiddle
In general, it is a good practice to have a primary key on any table. Extending the principe of turning your unique indexes to primary keys, your DDL statements could be simplified as follows:
CREATE TABLE tbl_x (
cod_op INTEGER PRIMARY KEY,
cod_dni CHAR(8),
blabla VARCHAR2(50)
);
CREATE TABLE tbl_a (
cod_op INTEGER PRIMARY KEY,
cod_dni CHAR(8),
cod_correl INTEGER,
blabla VARCHAR2(50),
CONSTRAINT TBL_a_R01 FOREIGN KEY (COD_OP) REFERENCES TBL_x (COD_OP)
);
Demo on DB Fiddle

oracle foreign key returns null

currently i am facing an oracle constraints issue.
After submiting an insert my foreign key constraint(s) won't fire. What it should do is giving two tables the same ID, but unfortunately only the one table with the primary Key is giving an ID. The column with the foreign key in the second table remains null.
For Instance: Insert into table t1 (t1_id,name, dpt) values (value1 (trigger with autoincrement for id), value2, value3); The same procedure is behind table 2, table 3 ... All constraints are written correctly
Table 1 (Emp)
ID Name Department
1 Joe HR
Table 2 (Projects)
ID Project EmpID
1 new (null) -> must be 1
Thank you in advanced.
Constraint: ALTER TABLE "PROJECTS" ADD CONSTRAINT "EMP_FK" FOREIGN KEY ("EMP_ID")
REFERENCES "EMP" ("EMP_ID") ON DELETE CASCADE ENABLE
Trigger: create or replace TRIGGER Projects_TRG BEFORE
INSERT ON Projects FOR EACH ROW BEGIN :NEW.Project_ID := Projects_SEQ.NEXTVAL;
END;
How do i manage to populate the parent id from the parent table into the child table?
Please note that I used different names in my application.
It appears that you've misunderstood the purpose of a foreign key constraint. A foreign key constraint does NOT automatically propagate constraint values from the parent table to the child table. The purpose of the constraint is to ensure that the values of the key column in the child table, when populated, have matching values in the key column of the parent table. Your application is responsible for ensuring that the key column on the child table is populated with the appropriate value. The constraint doesn't do that for you. It's also perfectly legitimate to have a NULL in the key column of the child table, assuming the the column on the child table doesn't have a NOT NULL constraint on it.

Resources