Composite Foreign Key - Possible In Oracle? - sql

I am trying to create a relation/table in Oracle that is between two many to many tables and therefore the Primary key of this table is a composite key but both keys are foreign.
CREATE TABLE employee_licence_certificate(
emp_id NUMBER(4) REFERENCES employee(emp_id)
, licence_cert_code VARCHAR2(6) REFERENCES licence_certificate(licence_cert_code)
, date_earned DATE NOT NULL
)
PRIMARY KEY (emp_id, licence_cert_code))
I have tried using the method for composition keys but I seem to get the following error, which is starting to make me wonder is this even possible?
Error starting at line 1 in command:
CREATE TABLE employee_licence_certificate(emp_id NUMBER(4) REFERENCES employee(emp_id)
, licence_cert_code VARCHAR2(6) REFERENCES licence_certificate(licence_cert_code)
, date_earned DATE NOT NULL) PRIMARY KEY (emp_id, licence_cert_code))
Error at Command Line:3 Column:29
Error report:
SQL Error: ORA-00922: missing or invalid option
00922. 00000 - "missing or invalid option"
*Cause:
*Action:

Try this:
CREATE TABLE employee_licence_certificate(
emp_id NUMBER(4) REFERENCES employee(emp_id)
, licence_cert_code VARCHAR2(6) REFERENCES licence_certificate(licence_cert_code)
, date_earned DATE NOT NULL
,
PRIMARY KEY (emp_id, licence_cert_code))

I use a different syntax. I prefer to explicitly name my foreign key constraints so that the error message if/when its violated is more meaningful/tracable. So I would do it something like this:
CREATE TABLE employee_licence_certificate
( emp_id NUMBER(4) NOT NULL
, licence_cert_code VARCHAR2(6) NOT NULL
, date_earned DATE NOT NULL
, CONSTRAINT elc_pk PRIMARY KEY (emp_id, licence_cert_code)
, CONSTRAINT elc_emp_fk FOREIGN KEY (emp_id)
REFERENCES employee(emp_id)
, CONSTRAINT elc_lct_fk FOREIGN KEY (licence_cert_code )
REFERENCES licence_certificate(licence_cert_code)
)

It sure is possible. You simply need to fix your statement:
CREATE TABLE employee_licence_certificate(emp_id NUMBER(4) REFERENCES employee(emp_id)
, licence_cert_code VARCHAR2(6) REFERENCES licence_certificate(licence_cert_code)
, date_earned DATE NOT NULL, PRIMARY KEY (emp_id, licence_cert_code))
By the way, it is MUCH easier to spot such errors when you format your statements properly:
create table employee_licence_certificate
(
emp_id number(15) references employee(emp_id),
licence_cert_code VARCHAR2(6) REFERENCES licence_certificate(licence_cert_code),
date_earned date not null,
primary key (emp_id, licence_cert_code)
)

Related

Why is parent key not found?

When I insert data into the ASSIGNMENTS table it all works fine except for the HARDWARE and SOFTWARE values, which are coded exactly in the same way as the others. I just don't get it.
This works:
INSERT INTO ASSIGNMENTS (ASSIGNMENT_ID, PROJECT_ID, STAFF_ID, JOB_ID)
VALUES ('A0005','B0002','ST002','J0002');
But when I try to include values for HARDWARE or SOFTWARE, like this:
INSERT INTO ASSIGNMENTS (ASSIGNMENT_ID, PROJECT_ID, STAFF_ID, JOB_ID, HARDWARE_ID)
VALUES ('A0005','B0002','ST002','J0002','H0002');
I just get the following error:
SQL Error: ORA-02291: integrity constraint (JAS1224.SYS_C0028418) violated - parent key not found
02291. 00000 - "integrity constraint (%s.%s) violated - parent key not found"
*Cause: A foreign key value has no matching primary key value.
*Action: Delete the foreign key or add a matching primary key.
Here is all the code, and all of the tables have been populated correctly (the hardware and software tables are coded in exactly the same format as the staff table):
CREATE TABLE PROJECT
(PROJECT_ID CHAR(5) NOT NULL,
PROJECT_NAME CHAR(20),
PROJECT_TYPE CHAR(20),
START_DATE DATE,
END_DATE DATE,
PRIMARY KEY (PROJECT_ID));
CREATE TABLE HARDWARE
(HARDWARE_ID CHAR(5) NOT NULL,
HARDWARE_NAME CHAR(20),
PRIMARY KEY (HARDWARE_ID));
CREATE TABLE SOFTWARE
(SOFTWARE_ID CHAR(5) NOT NULL,
SOFTWARE_NAME CHAR(20),
PRIMARY KEY (SOFTWARE_ID));
CREATE TABLE STAFF
(STAFF_ID CHAR(5) NOT NULL,
STAFF_NAME CHAR(20),
PRIMARY KEY (STAFF_ID));
CREATE TABLE JOB
(JOB_ID CHAR(5) NOT NULL,
JOB_TYPE CHAR(20),
JOB_GRADE CHAR(20),
PRIMARY KEY (JOB_ID));
CREATE TABLE ASSIGNMENTS
(ASSIGNMENT_ID CHAR(5) NOT NULL,
PROJECT_ID CHAR(5),
STAFF_ID CHAR(5),
JOB_ID CHAR(5),
HARDWARE_ID CHAR(5),
SOFTWARE_ID CHAR(5),
PRIMARY KEY (ASSIGNMENT_ID),
FOREIGN KEY (PROJECT_ID) REFERENCES PROJECT(PROJECT_ID),
FOREIGN KEY (STAFF_ID) REFERENCES STAFF(STAFF_ID),
FOREIGN KEY (JOB_ID) REFERENCES JOB(JOB_ID),
FOREIGN KEY (HARDWARE_ID) REFERENCES HARDWARE(HARDWARE_ID),
FOREIGN KEY (SOFTWARE_ID) REFERENCES SOFTWARE(SOFTWARE_ID));
The error message may be a bit cryptic at first, but it is pretty clear.
The only difference between the two INSERTs is for HARDWARE_ID. Hence 'H0002' is not a valid HARDWARE_ID. It is not in the HARDWARE table.

I'm trying to create a table with a foreign key but i keep getting the ORA-00904 error. What am I doing wrong?

create table reservation (
reserve_id number PRIMARY KEY,
date_in TIMESTAMP,
date_out TIMESTAMP,
made_by number(4),
constraint LocationID_fk foreign key (locId) references location(locId),
constraint fk_guest_id foreign key (guest_id) references guest(guest_id)
);
--these are the parent tables
create table guest(
guest_id NUMBER(3) PRIMARY KEY,
fname varchar(10),
lname varchar(5),
email varchar(10)
);
Create table location (
locId NUMBER(4) PRIMARY KEY,
loc_name varchar(10),
manager_name varchar(15)
);
-------error that keeps coming up
Error report -
SQL Error: ORA-00904: "LOCID": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
I think you misunderstand what the constraint definitions do:
constraint LocationID_fk foreign key (locId) references location(locId),
constraint fk_guest_id foreign key (guest_id) references guest(guest_id)
Maybe you are under the impression that by defining the foreign key constraints on locId and guest_id, that it also automatically defines the 2 columns on the reservation table? That is not the case. You have to explicitly define the 2 columns besides the foreign key constraint definition. Something like:
create table reservation (
reserve_id number PRIMARY KEY,
date_in TIMESTAMP,
date_out TIMESTAMP,
made_by number(4),
locId number(4), -- explicitly defined
guest_id number(3) -- explicitly defined
constraint LocationID_fk foreign key (locId) references location(locId),
constraint fk_guest_id foreign key (guest_id) references guest(guest_id)
);

"no matching unique or primary key for this column-list". The primary key does exist though

So i'm practicing some sql coding for a test and I can't get a foreign key to reference a primary key.
Here's the table that doesn't work:
CREATE TABLE ASSIGNMENT(
ASSIGN_ID NUMBER(2) NOT NULL,
START_DATE DATE,
END_DATE DATE,
BUDGET NUMBER (10,2),
MANAGER_ID NUMBER(2),
PRIMARY KEY (ASSIGN_ID,MANAGER_ID),
FOREIGN KEY (MANAGER_ID) REFERENCES EMPLOYEE(EMP_ID)
);
Here's the table it is referencing:
CREATE TABLE EMPLOYEE(
EMP_ID NUMBER(2) NOT NULL,
NAME VARCHAR(40),
OFFICE VARCHAR(20),
EXPERT_ID NUMBER(2),
PRIMARY KEY (EMP_ID,EXPERT_ID),
FOREIGN KEY (EXPERT_ID) REFERENCES EXPERTISE(EXPERT_ID)
);
Whenever I try to run the script it always comes back with:
Error report -
SQL Error: ORA-02270: no matching unique or primary key for this column-list
02270. 00000 - "no matching unique or primary key for this column-list"
*Cause: A REFERENCES clause in a CREATE/ALTER TABLE statement
gives a column-list for which there is no matching unique or primary
key constraint in the referenced table.
*Action: Find the correct column names using the ALL_CONS_COLUMNS
catalog view
I've looked around but can't seem to find the problem. Any help would be appreciated.
Here's the full code (haven't tested the last table yet):
CREATE TABLE EXPERTISE(
EXPERT_ID NUMBER(2) NOT NULL,
DESCRIPTION VARCHAR(50),
HOURLY_RATE NUMBER(3,2),
CHARGE_RATE NUMBER(3,2),
PRIMARY KEY(EXPERT_ID)
);
CREATE TABLE EMPLOYEE(
EMP_ID NUMBER(2) NOT NULL,
NAME VARCHAR(40),
OFFICE VARCHAR(20),
EXPERT_ID NUMBER(2),
PRIMARY KEY (EMP_ID,EXPERT_ID),
FOREIGN KEY (EXPERT_ID) REFERENCES EXPERTISE(EXPERT_ID)
);
CREATE TABLE ASSIGNMENT(
ASSIGN_ID NUMBER(2) NOT NULL,
START_DATE DATE,
END_DATE DATE,
BUDGET NUMBER (10,2),
MANAGER_ID NUMBER(2),
PRIMARY KEY (ASSIGN_ID,MANAGER_ID),
FOREIGN KEY (MANAGER_ID) REFERENCES EMPLOYEE(EMP_ID)
);
CREATE TABLE ALLOCATION(
EMP_ID NUMBER(3) NOT NULL,
ASSIGN_ID NUMBER(3) NOT NULL,
DAYS_WORKED_ON DATE,
HOURS_WORKED_ON DATE,
PRIMARY KEY(EMP_ID,ASSIGN_ID),
FOREIGN KEY(EMP_ID) REFERENCES EMPLOYEE(EMP_ID),
FOREIGN KEY(ASSIGN_ID) REFERENCES ASSIGNMENT(ASSIGN_ID)
);
I'm using Oracle SQL Developer to make it
*Cause: A REFERENCES clause in a CREATE/ALTER TABLE statement gives a column-list for which there is no matching unique or primary key
constraint in the referenced table.
The problem is that EMP_ID (by itself) isn't a primary or unique key of table Employees, instead, you have a compound primary key (EMP_ID, EXPERT_ID).
To fix the issue either make EMP_ID the primary key of the Employees table (which seems intuitive as each employee ought to have a unique id) or add a separate unique constraint on EMP_ID.
As pointed out in the comments, if you make EMP_ID the primary key, then (EMP_ID, EXPERT_ID) will also be unique by extension.
As the error suggest, the column you've referenced a foreign key doesn't match a unique constraint/pk on the parent table. Specifically for the primary key EMP_ID, EXPERT_ID you reference only EMP_ID.

Creating a table with a foreign key

Hey all I'm trying to create a table that contains a Foreign Key, and for some reason I am getting an error. The error says 00907. 00000 - "missing right parenthesis" which is odd because I don't have a random left parenthesis. I looked up how to create a table with a Foreign Key and that led to the following code:
Create Table EMPHIREINFO
(
empname VARCHAR2(10) NOT NULL FOREIGN KEY REFERENCES EMPADDRESS(empname),
empno NUMBER(4,0) NOT NULL PRIMARY KEY,
startdt DATE,
enddt DATE,
cntrlgth NUMBER(5,0)
)
I tried it with and without the REFERENCES EMPADDRESS(empname) and I still get the same error. Any help is appreciated, thanks.
You need to specify column after FOREIGN KEY. However, I'd prefer to use naming constraints, for instance
Create Table EMPHIREINFO
(
empname VARCHAR2(10) NOT NULL ,
empno NUMBER(4,0) NOT NULL ,
startdt DATE,
enddt DATE,
cntrlgth NUMBER(5,0),
CONSTRAINT PK_EMPHIREINFO PRIMARY KEY(empno) USING INDEX
(CREATE UNIQUE INDEX IDXU_EMPHIREINFO_empno ON EMPHIREINFO(empno) ),
CONSTRAINT FK_EMPHIREINFO_EMPNAME FOREIGN KEY(empname)
REFERENCES EMPADDRESS(empname)
)

SQL Error: ORA-00922: missing or invalid option creating composite key

I am trying to create a composite primary key for my table using emp_id and licence_cert_no why is this not working?
CREATE TABLE employee_licence_certificate(emp_id NUMBER(4) REFERENCES employee(emp_id)
, licence_cert_code VARCHAR2(6) REFERENCES licence_certificate(licence_cert_code)
, date_earned DATE NOT NULL)
CONSTRAINT pk_emp_licence PRIMARY KEY(emp_id, licence_cert_code)
Error Message:
Error starting at line 1 in command:
CREATE TABLE employee_licence_certificate(emp_id NUMBER(4) REFERENCES employee(emp_id)
, licence_cert_code VARCHAR2(6) REFERENCES licence_certificate(licence_cert_code)
, date_earned DATE NOT NULL)
CONSTRAINT pk_emp_licence PRIMARY KEY(emp_id, licence_cert_code)
Error at Command Line:3 Column:29
Error report:
SQL Error: ORA-00922: missing or invalid option
00922. 00000 - "missing or invalid option"
*Cause:
*Action:
The CONSTRAINT clause needs to go inside the parentheses:
CREATE TABLE employee_licence_certificate(
emp_id NUMBER(4) REFERENCES employee(emp_id)
, licence_cert_code VARCHAR2(6) REFERENCES licence_certificate(licence_cert_code)
, date_earned DATE NOT NULL
, CONSTRAINT pk_emp_licence PRIMARY KEY(emp_id, licence_cert_code)
);
(reference)