Adding foreign key constraint to associative entity - oracle

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.

Related

ORA-02256: number of referencing columns must match referenced [duplicate]

This question already has an answer here:
ORA-02256: referencing foreign key
(1 answer)
Closed last year.
CREATE TABLE Goft_ForeEver_cus(
customer_Id VARCHAR(10),
first_Name VARCHAR2(20) CONSTRAINT sys_cus_fName_nn NOT NULL,
last_Name VARCHAR2(20) CONSTRAINT sys_cus_lName_nn NOT NULL,
girt_Card_Amount NUMBER(5,2) CONSTRAINT sys_cus_gca_nn NOT NULL,
email VARCHAR2(30) CONSTRAINT sys_cus_email_ck CHECK (email ='%[^a-z,0-9,#,.,_,-]%' ) CONSTRAINT sys_cus_email_nn NOT NULL,
CONSTRAINT sys_cus_pk PRIMARY KEY(customer_Id)
);
ALTER TABLE Goft_ForeEver_cus
ADD CONSTRAINT sys_cus_email_UK UNIQUE (email);
CREATE TABLE Goft_ForeEver_Course_Info(
course_Name VARCHAR2(20),
city VARCHAR2(30) CONSTRAINT sys_courtInf_city_nn NOT NULL,
prov VARCHAR2(20) CONSTRAINT sys_courtInf_prov_nn NOT NULL,
postal_Code VARCHAR2(10) CONSTRAINT sys_courtInf_posC_nn NOT NULL,
star_rating NUMBER(1,1),
discript VARCHAR2(200) CONSTRAINT sys_courtInf_descript_uk UNIQUE,
year_Build DATE CONSTRAINT sys_courtInf_date_nn NOT NULL,
court_length Number(5,2)
CONSTRAINT sys_courtInf_courtL_ck CHECK( court_length = 'YARD')
CONSTRAINT sys_courtInf_courtL_nn NOT NULL,
CONSTRAINT sys_courtInf_pk PRIMARY KEY (course_Name, star_rating )
);
CREATE TABLE Goft_ForeEver_favorite_courses(
course_Name VARCHAR2(20),
customer_Id VARCHAR2(10),
CONSTRAINT sys_favCourt_PK PRIMARY KEY(course_Name,customer_Id),
CONSTRAINT sys_favCourt_FK1 FOREIGN KEY (customer_Id) REFERENCES Goft_ForeEver_cus(customer_Id),
CONSTRAINT sys_favCourt_FK2 FOREIGN KEY (course_Name) REFERENCES Goft_ForeEver_Course_Info(course_Name)
);
);
Error
Error report - ORA-02256: number of referencing columns must match referenced columns 02256. 00000 - "number of referencing columns must match referenced columns" *Cause: The number of columns in the foreign-key referencing list is not equal to the number of columns in the referenced list. *Action: Make sure that the referencing columns match the referenced columns.
It is because Goft_ForeEver_Course_Info has primary key as
CONSTRAINT sys_courtInf_pk PRIMARY KEY (course_Name, star_rating )
while Goft_ForeEver_favorite_courses that references it has foreign key as
CONSTRAINT sys_favCourt_FK2 FOREIGN KEY (course_Name) REFERENCES Goft_ForeEver_Course_Info(course_Name)
See? You're referencing COURSE_NAME, STAR_RATING composite key by COURSE_NAME only - that won't work.
Therefore, either remove STAR_RATING from the primary key in Goft_ForeEver_Course_Info, add STAR_RATING to Goft_ForeEver_favorite_courses, or redesign everything alltogether.
Illustration (SQL*Plus, which points to the error):
SQL> CREATE TABLE Goft_ForeEver_favorite_courses(
2 course_Name VARCHAR2(20),
3 customer_Id VARCHAR2(10),
4 CONSTRAINT sys_favCourt_PK PRIMARY KEY(course_Name,customer_Id),
5 CONSTRAINT sys_favCourt_FK1 FOREIGN KEY (customer_Id) REFERENCES Goft_ForeEver_cus(customer_Id),
6 CONSTRAINT sys_favCourt_FK2 FOREIGN KEY (course_Name) REFERENCES Goft_ForeEver_Course_Info(course_Name)
7 );
CONSTRAINT sys_favCourt_FK2 FOREIGN KEY (course_Name) REFERENCES Goft_ForeEver_Course_Info(course_Name)
*
ERROR at line 6:
ORA-02270: no matching unique or primary key for this column-list
SQL>
The problem here is you have declared the "course_Name" along with "star_rating" column as composite primary key in Goft_ForeEver_Course_Info table whereas you are referencing only one column "course_Name" in sys_favCourt_FK2 foreign key declaration in Goft_ForeEver_favorite_courses table.

having error for missing left parenthesis?

CREATE TABLE Transaction
(Portfolio_Number NUMBER(7,0) CONSTRAINT NN_Portfolio_Number NOT NULL,
CONSTRAINT FK_Portfolio_Number FOREIGN KEY
(Portfolio_Number) REFERENCES Portfolio(Portfolio_Number),
CONSTRAINT PK_Portfolio_Number PRIMARY KEY,
Stock_Code VARCHAR2(50) CONSTRAINT NN_Stock_Code NOT NULL,
CONSTRAINT FK_Stock_Code FOREIGN KEY
(Stock_Code) REFERENCES Stock(Stock_Code),
CONSTRAINT PK_Stock_Code PRIMARY KEY,
Transaction_Date DATE DEFAULT SYSDATE
CONSTRAINT PK_Transaction_Date PRIMARY KEY
CONSTRAINT NN_Transaction_Date NOT NULL,
Exchange_Code VARCHAR2(4) CONSTRAINT NN_Exchange_Code NOT NULL,
CONSTRAINT FK_Exchange_Code FOREIGN KEY
(Exchange_Code) REFERENCES Exchange(Exchange_Code),
Broker_Number NUMBER(7,0) CONSTRAINT NN_Broker_Number NOT NULL,
CONSTRAINT FK_Broker_Number FOREIGN KEY
(Broker_Number) REFERENCES Broker(Broker_Number),
Buy_Sell CHAR(1) CONSTRAINT NN_Buy_Sell NOT NULL,
Quantity NUMBER(7,0) CONSTRAINT CK_Quantity CHECK (Quantity > 0)
CONSTRAINT NN_Quantity NOT NULL,
Price_Per_Share NUMBER(6,2) CONSTRAINT NN_Price_Per_Share NOT NULL);
It seems that you got lost in too many CONSTRAINTs scattered throughout that piece of code.
a table can have only one primary key constraint; you have 3 of them. If it is a composite primary key, all columns should be placed into the same CONSTRAINT clause (see my example)
you can't mix constraints with columns; if you use them, put all those outline constraints to the end of the script (like I did)
I can't run it as I miss all tables you're referencing, but - this code is formatted properly so I hope it should compile.
CREATE TABLE Transaction
(
Portfolio_Number NUMBER (7, 0) CONSTRAINT NN_Portfolio_Number NOT NULL,
Stock_Code NUMBER (7, 0) CONSTRAINT NN_Stock_Code NOT NULL,
Transaction_Date DATE
DEFAULT SYSDATE
CONSTRAINT NN_Transaction_Date NOT NULL,
Exchange_Code VARCHAR2 (4) CONSTRAINT NN_Exchange_Code NOT NULL,
Broker_Number NUMBER (7, 0) CONSTRAINT NN_Broker_Number NOT NULL,
Buy_Sell CHAR (1) CONSTRAINT NN_Buy_Sell NOT NULL,
Quantity NUMBER (7, 0)
CONSTRAINT CK_Quantity CHECK (Quantity > 0)
CONSTRAINT NN_Quantity NOT NULL,
Price_Per_Share NUMBER (6, 2) CONSTRAINT NN_Price_Per_Share NOT NULL,
--
CONSTRAINT PK_Transaction_Date PRIMARY KEY
(portfolio_number, transaction_date, stock_code),
CONSTRAINT FK_Portfolio_Number FOREIGN KEY
(Portfolio_Number)
REFERENCES Portfolio (Portfolio_Number),
CONSTRAINT FK_Stock_Code FOREIGN KEY
(Stock_Code)
REFERENCES Stock (Stock_Code),
CONSTRAINT FK_Exchange_Code FOREIGN KEY
(Exchange_Code)
REFERENCES Exchange (Exchange_Code),
CONSTRAINT FK_Broker_Number FOREIGN KEY
(Broker_Number)
REFERENCES Broker (Broker_Number)
);
You are trying to create a primary key without specifying column name
, CONSTRAINT PK_Portfolio_Number PRIMARY KEY,
which is wrong. The right would be something like that
, CONSTRAINT PK_Portfolio_Number PRIMARY KEY(Portfolio_Number),
Next thing to note is you're trying to create 2 primary keys for same table which is impossible. If you need a primary key to be for both columns, you need to specify them in the same statement
, CONSTRAINT PK_Portfolio_Number PRIMARY KEY(Portfolio_Number, Stock_Code),

data base oracle foreign key error ORA-02270: no matching unique or primary key for this column-list

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

Creating table in Oracle 11g with multiple foreign keys with - ORA-00922: missing or invalid option

I followed the previous instruction of placing commas after each of the CONSTRAINTS. However, on this table, it's giving me the following error message:
ORA-02264: name already used by an existing constraint
All the foreign key tables that are associated with this table are created successfully. What is missing here?
CREATE TABLE FIELD (
ENCT_ID VARCHAR2(25) NOT NULL,
FLD_NUM NUMBER NOT NULL,
FLD_DESC VARCHAR2(50) NOT NULL,
SYMPT_CODE VARCHAR2(25),
DIAG_CODE VARCHAR2(25),
TEST_ID VARCHAR2(25),
RM_ID VARCHAR2(10) NOT NULL,
AX_CODE VARCHAR2(25) NOT NULL,
PROV_ID VARCHAR2(25) NOT NULL,
MED_NDC VARCHAR2(25),
PRIMARY KEY (ENCT_ID, FLD_NUM),
CONSTRAINT FK_ENCOUNTER FOREIGN KEY (ENCT_ID) REFERENCES ENCOUNTER(ENCT_ID),
CONSTRAINT FK_SYMPTOM FOREIGN KEY (SYMPT_CODE) REFERENCES SYMPTOM(SYMPT_CODE),
CONSTRAINT FK_DIAGNOSIS FOREIGN KEY (DIAG_CODE) REFERENCES DIAGNOSIS(DIAG_CODE),
CONSTRAINT FK_TEST FOREIGN KEY (TEST_ID) REFERENCES TEST(TEST_ID),
CONSTRAINT FK_ROOM FOREIGN KEY (RM_ID) REFERENCES ROOM(RM_ID),
CONSTRAINT FK_ASSESSMENT FOREIGN KEY (AX_CODE) REFERENCES ASSESSMENT(AX_CODE),
CONSTRAINT FK_PROVIDER FOREIGN KEY (PROV_ID) REFERENCES PROVIDER(PROV_ID),
CONSTRAINT FK_MEDICATION FOREIGN KEY (MED_NDC) REFERENCES MEDICATION(MED_NDC));
CREATE TABLE FIELD (
ENCT_ID VARCHAR2(25) PRIMARY KEY,
FLD_NUM NUMBER PRIMARY KEY,
FLD_DESC VARCHAR2(50) NOT NULL,...
Remove any one primary key. It will be the index for the table. Like a School text books have only one index, same way, every table will have only one primary key.

Employee/History - Part of composite key as foreign key

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.

Resources