how to create a foreign key in Oracle - oracle

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.

Related

Create table field with foreign key constraint

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 do i resolve ORA-00904: "CI"."CATALOG_ITEM_ID": invalid identifier Error at Line: 2 Column: 52

I need to create a query that will display title, publisher, ISBN, release date, number of pages, and whether it's carried in any library ("Yes" or "No") For each book in the catalog and sort results by title. I can't have any duplicates either.
The query I have is
select distinct ci.title, ci.publisher, ci.RELEASE_DATE, b.ISBN, b.pages from
catalog_item ci, book b
left join physical_item pi on pi.CATALOG_ITEM_ID = ci.CATALOG_ITEM_ID
left join branch b on b.branch_id = pi.branch_id
left join library l on b.library_id=l.library_id
order by ci.TITLE
;
I get the following error
ORA-00904: "CI"."CATALOG_ITEM_ID": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error at Line: 2 Column: 52
I don't see how it is invalid
My DDL is as follows:
CREATE TABLE CUSTOMER (Customer_ID NUMBER PRIMARY KEY, Customer_Firstname
VARCHAR2(30), Customer_Lastname VARCHAR2(30), Customer_Street VARCHAR2(30),
Customer_City VARCHAR2(30), Customer_State VARCHAR2(20), Customer_Zip
VARCHAR2(10));
CREATE TABLE BRANCH (Branch_ID NUMBER PRIMARY KEY, Branch_Name VARCHAR2(30),
Branch_Phone VARCHAR2 (30), Branch_Address VARCHAR2(30), LIBRARY_ID NUMBER);
CREATE TABLE PHYSICAL_ITEM (Physical_Item_ID NUMBER PRIMARY KEY, Branch_ID NUMBER,
Catalog_Item_ID NUMBER, Copy_Number NUMBER, Date_Purchased DATE);
CREATE TABLE CATALOG_ITEM (Catalog_Item_ID NUMBER PRIMARY KEY, Title VARCHAR2 (30),
Description VARCHAR2(30), Publisher VARCHAR2 (30), Release_Date DATE, Type
VARCHAR2(30));
CREATE TABLE DVD (Catalog_Item_ID NUMBER, Length VARCHAR2(30));
CREATE TABLE BOOK (Catalog_Item_ID NUMBER, ISBN VARCHAR2(13), Pages NUMBER);
CREATE TABLE TRANSACTION (Transaction_ID NUMBER PRIMARY KEY, Date_checkout DATE,
Date_Due DATE, Date_Returned DATE, Library_Card_ID NUMBER, Physical_Item_ID NUMBER);
CREATE TABLE LIBRARY (Library_ID NUMBER PRIMARY KEY, Library_Name VARCHAR2 (30),
Library_Phone VARCHAR2(30), Library_Address VARCHAR2(30));
CREATE TABLE LIBRARY_CARD (Library_Card_ID NUMBER PRIMARY KEY, Library_ID NUMBER,
Customer_ID NUMBER, Card_Number VARCHAR2(30), PIN VARCHAR2(8), Date_Expire DATE);
ALTER TABLE BRANCH ADD CONSTRAINT Library_ID_FK FOREIGN KEY (Library_ID) REFERENCES
LIBRARY (Library_ID);
ALTER TABLE PHYSICAL_ITEM ADD CONSTRAINT Branch_ID_FK FOREIGN KEY (Branch_ID)
REFERENCES BRANCH (Branch_ID);
ALTER TABLE PHYSICAL_ITEM ADD CONSTRAINT Catalog_Item_ID_FK FOREIGN KEY
(Catalog_Item_ID) REFERENCES CATALOG_ITEM (Catalog_Item_ID);
ALTER TABLE TRANSACTION ADD CONSTRAINT Library_Card_ID_FK FOREIGN KEY
(Library_Card_ID) REFERENCES LIBRARY_CARD (Library_Card_ID);
ALTER TABLE TRANSACTION ADD CONSTRAINT Physical_Item_ID_FK FOREIGN KEY
(Physical_Item_ID) REFERENCES PHYSICAL_ITEM (Physical_Item_ID);
ALTER TABLE LIBRARY_CARD ADD CONSTRAINT Library_ID_FK1 FOREIGN KEY (Library_ID)
REFERENCES LIBRARY (Library_ID);
ALTER TABLE LIBRARY_CARD ADD CONSTRAINT Customer_ID_FK FOREIGN KEY (Customer_ID)
REFERENCES CUSTOMER (Customer_ID);
ALTER TABLE DVD ADD CONSTRAINT Catalog_Item_ID_FK1 FOREIGN KEY (Catalog_Item_ID)
REFERENCES CATALOG_ITEM (Catalog_Item_ID);
ALTER TABLE BOOK add CONSTRAINT Catalog_Item_ID_FK2 FOREIGN KEY (Catalog_Item_ID)
REFERENCES CATALOG_ITEM (Catalog_Item_ID);

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.

Can a unique key ( not a primary key) be a foreign key to other table?

I have two table students and studentsprofilepic
'username' from students is unique key of the table
it is referenced as foreign key for the 'studentsprofilepic' table
the DDL for the tables are
CREATE TABLE students (
id NUMBER,
username VARCHAR2(30),
password VARCHAR2(30),
firstname VARCHAR2(30),
lastname VARCHAR2(40),
email VARCHAR2(300),
dob VARCHAR2(20),
alt_email VARCHAR2(300),
street_address VARCHAR2(50),
address_2 VARCHAR2(50),
city VARCHAR2(30),
state VARCHAR2(30),
zip VARCHAR2(10),
country VARCHAR2(60),
telephone VARCHAR2(10),
CONSTRAINT student_id_pk PRIMARY KEY (id),
CONSTRAINT student_username_uk UNIQUE (username)
);
CREATE TABLE studentsprofilepic (
id NUMBER,
photo_id NUMBER,
photo BLOB,
PRIMARY KEY (photo_id),
FOREIGN KEY (username) REFERENCES students (username)
);
YES, The foreign key column establishes a direct relationship with a primary key or unique key column (referenced key) usually in another table:
CREATE TABLE BOOK(
BNAME VARCHAR2(10)NOT NULL UNIQUE,
BTYPE VARCHAR2(10));
CREATE TABLE BOOKS_AUTH(
A_ID INT NOT NULL,
BNAME_REF VARCHAR2(10) NOT NULL,
FOREIGN KEY (BNAME_REF) REFERENCES BOOK (BNAME));
SQLFIDDLE DEMO
Yes, why not. It is possible to reference a UNIQUE constraint in a FOREIGN KEY.
You could have a Primary key and an Unique key, and you would like to validate both.
Yes, you can reference a column (or columns) governed by either a primary key constraint or a unique constraint.
The problem with your table "studentsprofilepic" is that your foreign key tries to use the column "studentsprofilepic"."username", but that column doesn't exist.
create table studentsprofilepic(
id number,
photo_id number,
photo blob,
-- Add the "username" column.
username varchar2(30) not null,
primary key (photo_id),
foreign key (username) references students (username)
);
Also, ask yourself "What's the point of "studentsprofilepic"."id"?" It's not the primary key. It's not a foreign key. It doesn't seem to serve any purpose besides letting you say, "Hey, my table has a column named 'id'!" That's a questionable feature.
Think about adding more not null constraints.

Oracle foreign key relation

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)
);

Resources