I've got 2 entities:
1) EMPLOYEES (Parent)
CREATE TABLE EMPLOYEES (
employee_id NUMBER (3) NOT NULL,
first_name VARCHAR (20) NOT NULL,
last_name VARCHAR (20) NOT NULL,
job_title VARCHAR (20) NOT NULL,
employee_type VARCHAR (1) NOT NULL,
salary NUMBER (5),
hourly_pay NUMBER (5,2),
bonus_pay NUMBER (5,2),
CONSTRAINT employee_pk PRIMARY KEY(employee_id));
2) EMPLOYEE_HISTORY (Child)
CREATE TABLE EMPLOYEE_HISTORY (
start_date DATE NOT NULL,
employee_id NUMBER (3) NOT NULL,
end_date DATE,
job_title VARCHAR (10) NOT NULL,
hourly_rate NUMBER (5,2) NOT NULL,
CONSTRAINT employee_history_pk PRIMARY KEY(start_date, employee_id));
I'm trying to create:
ALTER TABLE employee_history
ADD CONSTRAINT employee_history_fk
FOREIGN KEY (employee_id)
REFERENCES employee_history(employee_id);
When I do this, I get an error
ORA-02270: no matching unique or primary key for this column-list
My guess is that I cannot create the constraint on just employee_id because I have a composite key in my child table. I understand when an employee gets put into the database, the parent table is filled out and the "start date" should be filled out along with everything else. However, I do not understand how this would work if I had start_date in my parent table as well. I would be able to create my constraint, yes, but how will I be able to keep a record of changes in start_date if my start_date was inputted at the time of when the employee was entered into the database.I thought about using job_title as a primary key instead of start_date because it's present in both tables, but what happens when an employee gets promoted and demoted again? Won't a duplicate value constraint come up when the same employee_id and job_title is getting inserted?
Your references clause needs to reference the parent table. Not the child table
ALTER TABLE employee_history
ADD CONSTRAINT employee_history_fk
FOREIGN KEY (employee_id)
REFERENCES employee(employee_id); -- employee not employee_history
The SQL you posted is trying to create a self-referential foreign key where employee_history is both the parent and the child. That doesn't make sense in this case.
Related
I want to create a table department:
COLUMN NAME DATATYPE SIZE CONSTRAINT
dept_id number 4 Primary key
prod_id number 4 Foreign key
I tried this:
CREATE TABLE Department(
dept_id number(4) primary key,
prod_id number(4) foreign key);
It shows error. How can I add a foreign key constraint to this table?
A foreign key defines a relationship between your table DEPARTMENT and another table with a primary key. It means, you cannot create a row in DEPARTMENT with a PROD_ID of 1234 unless there is a pre-existing row in the designated parent table with a value of 1234 as its primary key.
So do you have such an existing parent table? if so you need to include its name in the foreign key definition. Otherwise you must create it.
Let's say the parent table is PRODUCT:
create table product (
prod_id number(4) primary key
, name varchar2(32) not null
);
Then you can create DEPARTMENT with a foreign key like this:
CREATE TABLE Department(
dept_id number(4) primary key,
prod_id references PRODUCT );
Yep, that's all the syntax you need: it automatically creates a column PROD_ID with the same datatype and precision as the primary key column of the referenced table. More verbose syntax is available. Read the Oracle SQL documentation to find out more.
I assume that the other table is named other_table_name and that it contains a primary key named prod_id.
CREATE Department (
dept_id number(4) primary key,
prod_id number(4) REFERENCES other_table_name (prod_id)
);
or a different syntax
CREATE Department (
dept_id number(4) primary key,
prod_id number(4)
...
CONSTRAINT fk_prod_id
FOREIGN KEY (prod_id)
REFERENCES other_table_name (prod_id)
);
How to link the MgrId in ManagerProject to EmpId in the Employee table ?
This is wat I tried :
CREATE TABLE Employee(EmpId varchar2(5),
EmpName varchar2(25),
DeptId varchar2(3),
Salary Number(8),
Constraint PK_addn primary key (EmpId, DeptId),
Constraint fk_Department foreign key (DeptId) references Department (DeptId));
But the second table failed to be created :
CREATE TABLE ManagerProject(ProjId varchar2(4),
MgrId varchar2(5),
StartDate Date,
EndDate Date,
Constraint fk_managerproject foreign key (MgrId) references Employee (EmpId),
Constraint PK_Managerproject Primary key(ProjId, MgrId, StartDate));
It displays
ORA-02270: no matching unique or primary key for this column-list
The error message says that you are trying to create a FK referencing a column on which there is no Unique or Primary Key constraint.
Assuming that you don't want to add the column DeptId to ManagerProject, you need to add a unique key on employee:
alter table Employee add constraint empId_UK unique ( empId)
But this strongly depends on what your schema should be.
If you want to add the column DeptId to ManagerProject, you will need to edit your FK to both use EmpId and DeptId in referencing employee.
while making foreign key in player table it shows following error
ORA-02270: no matching unique or primary key for this column-list
create table person
(
per_ssn number(10) not null,
per_name varchar2(30) not null,
CONSTRAINT pk_PersonID PRIMARY KEY (per_ssn,per_name)
);
create table Player
(
player_ssn number(10) not null,
player_name varchar2(30) not null,
football_club_name varchar2(30) not null,
p_age number(2) not null,
p_weight number(3) not null,
p_height number(10) not null,
country varchar2(20) not null,
p_starting_date date not null,
p_ending_date date not null
);
alter table Player
add constraint player_ssn
FOREIGN KEY (player_ssn)
REFERENCING person (per_ssn)on delete cascade
I want to make two primary keys in person table and then want to refer these
primary keys in player table.
If I make one primary key and then refer it in player table, then it does not show error but I want to make two primary keys.
You should be referencing per_ssn,per_name because that is your PK on person.
Anyway, think about making per_ssn your PK in person table
alter table Player
add constraint player_ssn
FOREIGN KEY (player_ssn,player_name)
REFERENCING person (per_ssn,per_name)on delete cascade
I have 3 tables:
1) SERVICE_REQUESTS (Parent)
CREATE TABLE SERVICE_REQUESTS(
service_id NUMBER (7) NOT NULL,
serial_number NUMBER (10) NOT NULL,
service_date DATE NOT NULL,
service_description VARCHAR(50) NOT NULL,
hourly_rate NUMBER(5,2) NOT NULL,
customer_id NUMBER (5) NOT NULL,
employee_id NUMBER (3) NOT NULL,
CONSTRAINT service_request_pk PRIMARY KEY(service_id, serial_number));
2) SERVICE_PARTS (Associative Entity to solve M:M relationship)
CREATE TABLE SERVICE_PARTS(
service_id NUMBER (7) NOT NULL,
part_id NUMBER (10) NOT NULL,
quantity NUMBER (4) NOT NULL,
unit_cost NUMBER(7,2) NOT NULL,
CONSTRAINT service_part_pk PRIMARY KEY(service_id, part_id));
3) PARTS (Parent)
CREATE TABLE PARTS(
part_id NUMBER (10) NOT NULL,
part_description VARCHAR(50) NOT NULL,
cost NUMBER(7,2) NOT NULL,
quantity_on_hand NUMBER (5) NOT NULL,
CONSTRAINT part_pk PRIMARY KEY(part_id));
I've created a foreign key constraint from SERVICE_PARTS to PARTS with the following statement:
ALTER TABLE service_parts
ADD CONSTRAINT service_parts_part_id_fk
FOREIGN KEY (part_id)
REFERENCES parts(part_id);
Now I'm trying to create a foreign key constraint from SERVICE_PARTS to SERVICE_REQUESTS using the follow statement:
ALTER TABLE service_parts
ADD CONSTRAINT service_parts_service_id_fk
FOREIGN KEY (service_id)
REFERENCES service_requests(service_id);
But I get the following error: ORA-02270: no matching unique or primary key for this column-list. Why does it allow a constraint to be added for the part_id but not the service_id?
I've attached my ER Diagram for visual clarification:
If the primary key of the service_requests table is service_id, serial_number, your M:M mapping table would need to include both elements of the primary key. The definition of the primary key implies that you can have many rows with the same service_id but different serial_number values. If your mapping table doesn't contain both elements of the key, you wouldn't be able to figure out which particular row in service_requests was mapped to any particular row in service_parts.
Your mapping table definition would need to be
CREATE TABLE SERVICE_PARTS(
service_id NUMBER (7) NOT NULL,
serial_number NUMBER (10) NOT NULL,
part_id NUMBER (10) NOT NULL,
quantity NUMBER (4) NOT NULL,
unit_cost NUMBER(7,2) NOT NULL,
CONSTRAINT service_part_pk PRIMARY KEY(service_id, serial_number, part_id));
and then your foreign key
ALTER TABLE service_parts
ADD CONSTRAINT service_parts_service_id_fk
FOREIGN KEY (service_id, serial_number)
REFERENCES service_requests(service_id, serial_number);
Alternately, if we believe that your mapping table is correct, which would imply that service_id was the key for service_requests, then the definition of service_requests would be
CREATE TABLE SERVICE_REQUESTS(
service_id NUMBER (7) NOT NULL,
serial_number NUMBER (10) NOT NULL,
service_date DATE NOT NULL,
service_description VARCHAR(50) NOT NULL,
hourly_rate NUMBER(5,2) NOT NULL,
customer_id NUMBER (5) NOT NULL,
employee_id NUMBER (3) NOT NULL,
CONSTRAINT service_request_pk PRIMARY KEY(service_id));
Then your mapping table and your foreign key definition would be correct as is.
Your primary key in table SERVICE_REQUESTS:
CONSTRAINT service_request_pk PRIMARY KEY(service_id, serial_number)
Such primary key can't guarantee, that your service_id value will be unique. Hence, you can't make reference only to this field from another table, because there is no way to determine, to which record you will refer. Your primary key in one table and foreign key in another have to be exactly the same.
I have a composite primary key in my Candidate table
CREATE TABLE CANDIDATE(
CANDIDATE_ID VARCHAR(5),
NAME VARCHAR(30),
TELEPHONE NUMBER,
PRIMARY KEY(CANDIDATE_ID, NAME));
When I create a child table, I get an error saying the number of referencing columns must match referenced columns when I create a foreign key for the CANDIDATE_ID
CREATE TABLE JOB(
POSITION_ID VARCHAR(5) PRIMARY KEY,
CANDIDATE_ID VARCHAR(5),
DATE2 DATE,
FOREIGN KEY(CANDIDATE_ID) REFERENCES CANDIDATE);
A table can only have one primary key-- you have a composite primary key. If you have a composite primary key, you have to reference the entire key in your child table. That would mean that the child table would need to have a CANDIDATE_ID column and a NAME column.
CREATE TABLE job (
position_id VARCHAR2(5) PRIMARY KEY,
candidate_id VARCHAR2(5),
name VARCHAR2(30),
date2 DATE,
FOREIGN KEY( candidate_id, name ) REFERENCES candidate( candidate_id, name )
);
Of course, you probably don't want to store the name in both tables. You probably want the candidate_id to be the prmiary key of candidate and you may want to create a separate unique constraint on name.
CREATE TABLE CANDIDATE(
CANDIDATE_ID VARCHAR(5) primary key,
NAME VARCHAR(30) unique,
TELEPHONE NUMBER);
CREATE TABLE JOB(
POSITION_ID VARCHAR(5) PRIMARY KEY,
CANDIDATE_ID VARCHAR(5),
DATE2 DATE,
FOREIGN KEY(CANDIDATE_ID) REFERENCES CANDIDATE(candidate_id));
Assuming that the combination of CANDIDATE_ID and NAME is required for the key to be unique, then you will need to add a reference to the NAME column in your referencing table.
I suspect that CANDIDATE_ID is enough to uniquely identify the candidates in your primary table. If that is the case then it should be your primary key and your relationship will work. If you want to index the NAME separately then do so, but leave it out of the primary key.
Last line should be like this;
CONSTRAINT FK_CANDIDATE_ID FOREIGN KEY (CANDIDATE_ID)REFERENCES CANDIDATE(CANDIDATE_ID);
CREATE TABLE dept
( did char(3) not null,
dname varchar2(20) not null,
CONSTRAINT dept_pk PRIMARY KEY (did)
);
strong text
create table emp
(
eid char(3) unique,
ename varchar2(10) not null,
sal number check (sal between 20000 AND 50000),
city varchar2(10) default 'texus',
did char(3) not null,
constraint fk_did_dept
FOREIGN KEY (did) references
dept(did)
);