I have the following table
CREATE TABLE assignment (
assignment_code VARCHAR(10),
course_code VARCHAR(10),
PRIMARY KEY(course_code, assignment_code),
FOREIGN KEY(course_code) REFERENCES course(course_code));
But when I try to create it PostgreSQL tells me assignment_code needs to be unique. However my assignment is to make assignment_code unique per course in stead of completely unique, how do I do that?
the code below creates the enitre database (no data)
CREATE TABLE students (
student_id BIGINT PRIMARY KEY,
first_name VARCHAR(15),
surname VARCHAR(35),
enrollment_year INT,
bsn BIGINT,
class VARCHAR(5),
Graduated BOOLEAN);
CREATE TABLE teachers (
bsn BIGINT PRIMARY KEY,
first_name VARCHAR(15),
surname VARCHAR(35),
salary REAL,
scale INT,
CONSTRAINT salary CHECK(salary < (25 * scale) AND salary > (20 * scale)));
CREATE TABLE course (
course_code VARCHAR(10) PRIMARY KEY,
course_name VARCHAR(20),
course_follower VARCHAR(5),
study_points INT,
Amount_of_assignments INT);
CREATE TABLE teaches (
bsn BIGINT,
class VARCHAR(5),
course_code VARCHAR(10),
PRIMARY KEY(bsn, class, course_code),
FOREIGN KEY(bsn) REFERENCES teachers(bsn),
FOREIGN KEY(course_code) REFERENCES course(course_code));
CREATE TABLE study_program (
course_name VARCHAR(20),
course_code VARCHAR(10) PRIMARY KEY,
level VARCHAR(15),
duration VARCHAR(10),
FOREIGN KEY(course_code) REFERENCES course(course_code));
CREATE TABLE assignment (
assignment_code VARCHAR(10),
course_code VARCHAR(10),
PRIMARY KEY(course_code, assignment_code),
FOREIGN KEY(course_code) REFERENCES course(course_code));
CREATE TABLE records (
student_id BIGINT,
course_code VARCHAR(20),
school VARCHAR(50),
PRIMARY KEY(student_id, course_code),
FOREIGN KEY(student_id) REFERENCES students(student_id),
FOREIGN KEY(course_code) REFERENCES study_program(course_code));
CREATE TABLE make (
student_id BIGINT,
assignment_code VARCHAR(20),
completed BOOLEAN,
PRIMARY KEY(student_id, assignment_code),
FOREIGN KEY(student_id) REFERENCES students(student_id),
FOREIGN KEY(assignment_code) REFERENCES assignment(assignment_code));
CREATE TABLE prerequisit (
assignment_code VARCHAR(20),
prerequisit_code VARCHAR(20),
course_code VARCHAR(20),
PRIMARY KEY(assignment_code, course_code),
FOREIGN KEY(assignment_code) REFERENCES assignment(assignment_code),
FOREIGN KEY(course_code) REFERENCES course(course_code),
FOREIGN KEY(prerequisit_code) REFERENCES assignment(assignment_code));
CREATE TABLE records_2 (
assignment_code VARCHAR(20),
course_code VARCHAR(20),
bsn BIGINT,
mandatory BOOLEAN,
year INT,
week INT,
PRIMARY KEY(assignment_code, course_code, bsn),
FOREIGN KEY(assignment_code) REFERENCES assignment(assignment_code),
FOREIGN KEY(course_code) REFERENCES course(course_code),
FOREIGN KEY(bsn) REFERENCES teachers(bsn));
CREATE TABLE designes (
course_code VARCHAR(15),
bsn BIGINT,
PRIMARY KEY(course_code),
FOREIGN KEY(course_code) REFERENCES course(course_code),
FOREIGN KEY(bsn) REFERENCES teachers(bsn));
CREATE TABLE reviews (
bsn BIGINT,
course_code VARCHAR(15),
PRIMARY KEY(bsn, course_code),
FOREIGN KEY(bsn) REFERENCES teachers(bsn),
FOREIGN KEY(course_code) REFERENCES course(course_code));
Lurking deep in your code is this:
CREATE TABLE records_2
. . .
FOREIGN KEY(assignment_code) REFERENCES assignment(assignment_code),
A foreign key reference needs to be to a unique or primary key. If you have a composite primary key, then you need to use all the keys. Hence, this reference is missing course_code.
I am a strong believer in synthetic primary keys -- that is, serial integer columns that provide this information. I would recommend that you use them in your table and for foreign key references.
Related
I am trying to create SQL statements for an assignment in SQL Fiddle and I keep getting the error "Cannot add foreign key constraint". I have tried various things but I recieve different errors when I change things. What am I doing wrong?
CREATE TABLE Person (
ID int NOT NULL,
FName varchar(255),
LName varchar(255),
Preferred_Name varchar(255),
PRIMARY KEY (ID)
)
;
CREATE TABLE Song (
ID varchar(255) NOT NULL,
Title varchar(255),
Run_Time varchar(255),
Lyrics varchar(255),
LeadID int,
FOREIGN KEY (LeadID) REFERENCES Person(ID),
PRIMARY KEY (ID)
)
;
CREATE TABLE Album (
Title varchar(255) NOT NULL,
Run_Time int,
Release_Year TIMESTAMP,
PRIMARY KEY (Title)
)
;
CREATE TABLE Has (
Album_Title varchar(255),
Song_Title varchar(255),
FOREIGN KEY (Album_Title) REFERENCES Album(Title),
FOREIGN KEY (Song_Title) REFERENCES Song(ID)
)
;
CREATE TABLE Part_Of (
PersonID int,
SongID int,
Role varchar(255) NOT NULL,
FOREIGN KEY (PersonID) REFERENCES Person(ID),
FOREIGN KEY (SongID) REFERENCES Song(ID),
PRIMARY KEY (Role)
)
;
In the Song and Has tables you defined Song.ID and Has.Song_Title as a varchar(255). In the Part_Of table you defined SongID as an int. This is why the foreign key is failing. Use the same datatype in all tables (INT seems like a good option) to fix this.
CREATE TABLE Song (
ID varchar(255) NOT NULL, <------
Title varchar(255),
Run_Time varchar(255),
Lyrics varchar(255),
LeadID int,
FOREIGN KEY (LeadID) REFERENCES Person(ID),
PRIMARY KEY (ID)
)
;
CREATE TABLE Has (
Album_Title varchar(255),
Song_Title varchar(255), <-----
FOREIGN KEY (Album_Title) REFERENCES Album(Title),
FOREIGN KEY (Song_Title) REFERENCES Song(ID)
)
;
CREATE TABLE Part_Of (
PersonID int,
SongID int, <-----
Role varchar(255) NOT NULL,
FOREIGN KEY (PersonID) REFERENCES Person(ID),
FOREIGN KEY (SongID) REFERENCES Song(ID),
PRIMARY KEY (Role)
)
;
There is an error with the referencing of table booking to person and driver.
ERROR at line 17:
ORA-02270: no matching unique or primary key for this column-list
I've tried almost everything please help me.
alter session set NLS_DATE_FORMAT='DD/MM/YYYY';
DROP TABLE CARSERVICE;
DROP TABLE DRIVERBEN;
DROP TABLE BENEFITS;
DROP TABLE FOLLOWUP;
DROP TABLE INCIDENT;
DROP TABLE DSESSION;
DROP TABLE TRAINING;
DROP TABLE DRIVERINS;
DROP TABLE BOOKING;
DROP TABLE DRIVER;
DROP TABLE PERSON;
CREATE TABLE PERSON
(
PID CHAR(6) PRIMARY KEY,
PName VARCHAR(20),
PDOB DATE,
Sex CHAR(1),
PMOBILE CHAR(12)
);
CREATE TABLE DRIVER
(
DID CHAR(6),
DGrade CHAR(1),
DCarId CHAR(6),
DLicense CHAR(8),
DStart DATE,
DIPlan CHAR(1),
DSession CHAR(6),
DNRIC CHAR(12),
PID CHAR(6),
PRIMARY KEY (DID, DCarId),
FOREIGN KEY (DID) references PERSON(PID)
);
CREATE TABLE BOOKING
(
BookingID CHAR(6),
PickLoc VARCHAR(250),
DropLoc VARCHAR(250),
TripRating NUMBER(1),
RideFare NUMBER(*,1),
TollOther NUMBER(*,1),
TDate DATE,
TTime VARCHAR(5),
BStatus CHAR(1),
Payment VARCHAR(12),
IncRep CHAR(1),
PID CHAR(6),
DID CHAR(6),
PRIMARY KEY(BookingID,PID,DID),
FOREIGN KEY (DID) references Driver(DID),
FOREIGN KEY (PID) references PERSON(PID)
);
CREATE TABLE DRIVERINS
(
DIID CHAR(6) PRIMARY KEY,
PAmount NUMBER(*,1),
PDt DATE,
FOREIGN KEY (DIID) references DRIVER (DID)
);
CREATE TABLE TRAINING
(
TID CHAR(6) PRIMARY KEY,
TrainingPrg VARCHAR(50),
PrgSession VARCHAR2(10)
);
CREATE TABLE DSESSION
(
SID CHAR(6) PRIMARY KEY,
SDate DATE,
TID CHAR(6),
FOREIGN KEY (SID) references DRIVER(DID),
FOREIGN KEY (TID) references TRAINING(TID)
);
CREATE TABLE INCIDENT
(
INCID CHAR(6) PRIMARY KEY,
RIncident VARCHAR(30),
IncDate DATE,
FOREIGN KEY (INCID) references BOOKING(BookingID)
);
CREATE TABLE FOLLOWUP
(
FollowID CHAR(6) PRIMARY KEY,
IncPIC VARCHAR(30),
FollowUpDt VARCHAR2(50),
IncStatus CHAR(1),
FollowUpDate DATE,
FOREIGN KEY (FollowID) references INCIDENT(INCID)
);
CREATE TABLE BENEFITS
(
BID CHAR(6) PRIMARY KEY,
CMedBenefit NUMBER(*,1),
OBetterCars NUMBER(*,1),
PrepRet NUMBER(*,1)
);
CREATE TABLE DRIVERBEN
(
DBID CHAR(6),
CMedBenefit CHAR(1),
OBetterCars CHAR(1),
PrepRet CHAR(1),
FOREIGN KEY (DBID) references DRIVER(DID)
);
CREATE TABLE CARSERVICE
(
CarID CHAR(6) PRIMARY KEY,
CarType VARCHAR(20),
ServRem VARCHAR(250),
CarServDate DATE,
NextServD DATE,
FOREIGN KEY (CarID) references DRIVER(DCarId)
);
You have these definitions:
CREATE TABLE DRIVER (
. . .
PRIMARY KEY (DID, DCarId),
. . .
);
CREATE TABLE BOOKING (
. .
FOREIGN KEY (DID) references Driver(DID),
. . .
);
These are inconsistent. The primary key for Driver has two component keys. The foreign key reference only uses one. You need to reference both.
Would appreciate help. Can not create the "Teaches" and "takes" table.
CREATE DATABASE university;
use university;
CREATE TABLE classroom(
building VARCHAR(20),
room_number INT,
capacity INT,
PRIMARY KEY (building,room_number)
) ;
CREATE TABLE Sales(
item VARCHAR(20),
color VARCHAR(20),
clothes_size VARCHAR(20),
quantity INT,
PRIMARY KEY (item,color,clothes_size,quantity)
);
CREATE TABLE Department (
dept_name VARCHAR(20),
building VARCHAR(20),
budget INT,
FOREIGN KEY (building) references classroom(building),
PRIMARY KEY (dept_name,building,budget)
);
CREATE TABLE Course (
course_id VARCHAR(20)PRIMARY KEY,
title VARCHAR(20),
dept_name VARCHAR(20),
credits INT,
FOREIGN KEY (dept_name) references Department(dept_name)
);
CREATE TABLE Instructor(
ID VARCHAR(20) PRIMARY KEY,
neme VARCHAR(20),
dept_name VARCHAR(20),
salary INT,
FOREIGN KEY (dept_name) references Department(dept_name)
);
CREATE TABLE section(
course_id VARCHAR(20),
sec_id INT,
semester VARCHAR(20),
year1 INT,
building1 VARCHAR(20),
room_number INT,
time_slot_id CHAR,
FOREIGN KEY (course_id) REFERENCES Course(course_id),
FOREIGN KEY (building1,room_number) references classroom(building,room_number),
PRIMARY KEY(course_id,sec_id,semester,year1)
);
CREATE TABLE Teaches(
ID VARCHAR(20),
course_id VARCHAR(20),
sec_id VARCHAR(20),
semester VARCHAR(20),
year1 INT,
FOREIGN KEY (ID) references Instructor(ID),
FOREIGN KEY (sec_id) references section(sec_id),
FOREIGN KEY (semester,year1) references section(semester,year1),
FOREIGN KEY (course_id) references course(course_id),
PRIMARY KEY (ID,course_id,sec_id,year1,semester)
);
CREATE TABLE student(
ID VARCHAR(20) PRIMARY KEY,
name1 VARCHAR(20),
dept_name VARCHAR(20),
tot_cred INT);
CREATE TABLE Takes(
ID VARCHAR(20),
course_id VARCHAR(20),
sec_id INT,
semester VARCHAR(20),
year1 INT,
grade char,
FOREIGN KEY (ID) references student(ID),
FOREIGN KEY (sec_id) references section(sec_id),
FOREIGN KEY (semester) references section(semester),
FOREIGN KEY (year1) references section(year1),
FOREIGN KEY (course_id) references course(course_id),
PRIMARY KEY(ID,sec_id,semester,year1,course_id)
);
Foreign key references need to have the same types as the primary keys they refer to. So consider:
CREATE TABLE Department (
dept_name VARCHAR(20),
building VARCHAR(20),
budget INT,
FOREIGN KEY (building) references classroom(building),
PRIMARY KEY (dept_name,building,budget)
);
CREATE TABLE Instructor (
ID VARCHAR(20) PRIMARY KEY,
neme VARCHAR(20),
dept_name VARCHAR(20),
salary INT,
FOREIGN KEY (dept_name) references Department(dept_name)
);
The primary key for Department has three components -- dept_name, building, budget. However, the reference has only one component. They cannot match; the number is not correct, much less the types.
I would recommend that you use auto-incremented ids for your primary keys. You can also specify uniqueness constraints, if you like. So for this small example:
create table buildings (
building_id int auto_increment primary key,
building varchar(20),
constraint unq_buildings_building unique(building)
);
create table classrooms (
classroom_id int auto_increment primary key,
building_id int,
room_number int,
capacity int,
constraint fk_classrooms_building_id foreign key (building_id) references buildings (building_id)
) ;
create table Departments (
department_id int auto_increment primary key,
dept_name varchar(20),
building_id int,
budget INT,
constraint fk_departments_building_id foreign key (building_id) references buildings(building_id)
);
create table instructors (
instructor_id int auto_increment primary key,
id varchar(20) unique,
name varchar(20),
department_id int,
salary int,
foreign key instructors_department_id foreign key (department_id) references departments (department_id)
);
This is just a small sample of your tables. But the following are some rules that I follow:
Table names are plural.
They have a primary key which is the singular form followed by _id (or Id).
Foreign key references are only to primary keys.
To the extent possible, foreign keys and primary keys have the exact same name.
Explicit constraints are given names. The names follow a very precise naming convention.
I also added a buildings table. It is referenced in at least two places, so it seems worthy of being its own entity.
This should give you some ideas on how to build your database.
I am fairly new to SQL and I can't understand why I am receiving an error when establishing foreign keys as I receive an error saying that the destination table is invalid.
Below is the SQL code, any advice on how to fix would be brilliant! :)
The error appears regarding tblFilms and tblCinemaScreens.
CREATE TABLE tblCustomer (
CustomerID int,
CustomerSurname NVARCHAR(25),
CustomerForename NVARCHAR(20),
CustomerAge int,
CustomerPhoneNumber NVARCHAR(12),
CustomerEmailAddress NVARCHAR(100),
CONSTRAINT PK_tblCustomer PRIMARY KEY CLUSTERED (CustomerID)
)
GO
CREATE TABLE tblBookings (
BookingID int,
FilmShowings TIME,
PriceOfFilm MONEY,
DateOfBooking DATE,
FilmID int,
CinemaScreenID int,
CustomerID int,
CONSTRAINT PK_tblBookings PRIMARY KEY CLUSTERED (BookingID),
CONSTRAINT FK_FilmID FOREIGN KEY (FilmID) REFERENCES tblFilms(FilmID),
CONSTRAINT FK_CustomerID FOREIGN KEY (CustomerID) REFERENCES tblCustomer(CustomerID)
)
GO
CREATE TABLE tblFilms (
FilmID int,
FilmName VARCHAR(100),
FilmDuration int,
AgeRating VARCHAR(3),
CriticScore int,
FilmDescription NVARCHAR(300),
FilmGenre NVARCHAR(20),
FilmStartScreeningDate DATE,
FlimEndScreeningDate DATE,
CinemaScreenID int,
CONSTRAINT PK_tblFilms PRIMARY KEY CLUSTERED (FilmID),
CONSTRAINT FK_tblFilms FOREIGN KEY (CinemaScreenID) REFERENCES tblCinemaScreens(CinemaScreenID)
)
GO
CREATE TABLE tblCinemaScreens (
CinemaScreenID int,
CinemaScreenType NVARCHAR(10),
NumberOfSeats int,
FilmID int,
CONSTRAINT PK_tblCinemaScreens PRIMARY KEY CLUSTERED (CinemaScreenID),
CONSTRAINT FK_tblCinemaScreens FOREIGN KEY (FilmID) REFERENCES tblFilms(FilmID)
)
GO
Cinema screens table does not need a film id and you need to create the tables BEFORE referencing them with FK's
CREATE TABLE tblCinemaScreens (
CinemaScreenID int,
CinemaScreenType NVARCHAR(10),
NumberOfSeats int,
FilmID int,
CONSTRAINT PK_tblCinemaScreens PRIMARY KEY CLUSTERED (CinemaScreenID)
GO
CREATE TABLE tblFilms (
FilmID int,
FilmName VARCHAR(100),
FilmDuration int,
AgeRating VARCHAR(3),
CriticScore int,
FilmDescription NVARCHAR(300),
FilmGenre NVARCHAR(20),
FilmStartScreeningDate DATE,
FlimEndScreeningDate DATE,
CinemaScreenID int,
CONSTRAINT PK_tblFilms PRIMARY KEY CLUSTERED (FilmID),
CONSTRAINT FK_tblFilms FOREIGN KEY (CinemaScreenID) REFERENCES tblCinemaScreens(CinemaScreenID)
)
GO
CREATE TABLE tblCustomer (
CustomerID int,
CustomerSurname NVARCHAR(25),
CustomerForename NVARCHAR(20),
CustomerAge int,
CustomerPhoneNumber NVARCHAR(12),
CustomerEmailAddress NVARCHAR(100),
CONSTRAINT PK_tblCustomer PRIMARY KEY CLUSTERED (CustomerID)
)
GO
CREATE TABLE tblFilms (
FilmID int,
FilmName VARCHAR(100),
FilmDuration int,
AgeRating VARCHAR(3),
CriticScore int,
FilmDescription NVARCHAR(300),
FilmGenre NVARCHAR(20),
FilmStartScreeningDate DATE,
FlimEndScreeningDate DATE,
CinemaScreenID int,
CONSTRAINT PK_tblFilms PRIMARY KEY CLUSTERED (FilmID),
CONSTRAINT FK_tblFilms FOREIGN KEY (CinemaScreenID) REFERENCES tblCinemaScreens(CinemaScreenID)
)
GO
You are trying to create a foreign key on tables before they are made. Comment out the lines in the create table statements that are giving you an error and create the tables. Once the tables are made create the missing foreign keys you need like this:
alter table tblFilms
add CONSTRAINT FK_tblFilms FOREIGN KEY (CinemaScreenID) REFERENCES tblCinemaScreens(CinemaScreenID)
alter table tblBookings
add CONSTRAINT FK_FilmID FOREIGN KEY (FilmID) REFERENCES tblFilms(FilmID)
The answer is they should have not direct relationships
A film is shown on 0 or more screens
You need a join table
rblFilmCinema
filmID fk to tblFilms
screenID fk to tblCinemaScreens
composite PK on filmID, screenID
I would change up the schema some to give yourself more flexibility. I would assume that a film can be on more than one cinema screen so I would take CinemaScreenID off of tblFilms and remove the foreign key. You can also remove FilmID from tblBookings since you have the CinemaScreenID already which has the FilmID.. Another thing to consider might be having multiple films on the same CinemaScreen which would be another tabled called tblCinemaScreenFilms and you would put that CinemaScreenFilmID on the tblBookings instead
CREATE TABLE tblFilms (
FilmID int,
...
CONSTRAINT PK_tblFilms PRIMARY KEY CLUSTERED (FilmID),
)
GO
CREATE TABLE tblCustomer (
CustomerID int,
...
CONSTRAINT PK_tblCustomer PRIMARY KEY CLUSTERED (CustomerID)
)
GO
CREATE TABLE tblBookings (
BookingID int,
CinemaScreenID int,
CustomerID int,
...
CONSTRAINT PK_tblBookings PRIMARY KEY CLUSTERED (BookingID),
CONSTRAINT FK_CinemaScreenID FOREIGN KEY (CinemaScreenID ) REFERENCES tblCinemaScreens(CinemaScreenID),
CONSTRAINT FK_CustomerID FOREIGN KEY (CustomerID) REFERENCES tblCustomer(CustomerID)
)
GO
CREATE TABLE tblCinemaScreens (
CinemaScreenID int,
FilmID int,
...
CONSTRAINT PK_tblCinemaScreens PRIMARY KEY CLUSTERED (CinemaScreenID),
CONSTRAINT FK_tblCinemaScreens FOREIGN KEY (FilmID) REFERENCES tblFilms(FilmID)
)
GO
Option B (preferred)
CREATE TABLE tblCustomer (
CustomerID int,
...
CONSTRAINT PK_tblCustomer PRIMARY KEY CLUSTERED (CustomerID)
)
GO
CREATE TABLE tblFilms (
FilmID int,
...
CONSTRAINT PK_tblFilms PRIMARY KEY CLUSTERED (FilmID),
)
GO
CREATE TABLE tblCinemaScreens (
CinemaScreenID int,
...
CONSTRAINT PK_tblCinemaScreens PRIMARY KEY CLUSTERED (CinemaScreenID)
)
GO
CREATE TABLE tblCinemaScreenFilms (
CinemaScreenFilmID int,
CinemaScreenID int,
FilmID int
CONSTRAINT PK_tblCinemaScreenFilms PRIMARY KEY CLUSTERED (CinemaScreenFilmID),
CONSTRAINT FK_FilmID FOREIGN KEY (FilmID) REFERENCES tblFilms(FilmID),
CONSTRAINT FK_CinemaScreenID FOREIGN KEY (FilmID) REFERENCES tblCinemaScreens(CinemaScreenID)
)
GO
CREATE TABLE tblBookings (
BookingID int,
CustomerID int,
CinemaScreenFilmID int,
...
CONSTRAINT PK_tblBookings PRIMARY KEY CLUSTERED (BookingID),
CONSTRAINT FK_CustomerID FOREIGN KEY (CustomerID) REFERENCES tblCustomer(CustomerID),
CONSTRAINT FK_CinemaScreenFilmID FOREIGN KEY (CinemaScreenFilmID) REFERENCES tblCinemaScreenFilms(CinemaScreenFilmID)
)
GO
You're creating a table - tblFilms - and adding a foreign key to tblCinemaScreens before the second table has been created.
As a help I usually create all tables and then create any foreign key relationships and other constraints.
I am getting an error when i create my tabels.
The problem is that AssCode is not unique, so i can set it to unique, the combination of courseCode and AssCode is unique, thats why they are set as primary keys. I am using postgressql
here is the error:
ERROR: there is no unique constraint matching given keys for referenced table "assignments"
SQL state: 42830
here is my code:
CREATE TABLE Teachers (
BSN int primary key,
Surname varchar(40) NOT NULL,
Name varchar(40) NOT NULL
);
CREATE TABLE Courses (
CourseCode varchar(10) primary key,
Name varchar(20) NOT NULL
);
CREATE TABLE Assignments (
CourseCode varchar(10) REFERENCES Courses ON DELETE CASCADE,
AssCode varchar(10),
primary key(CourseCode,AssCode),
DependOn varchar(10),
Year date,
week int
);
CREATE TABLE WorkOn (
BSN int REFERENCES Teachers(BSN),
CourseCode varchar(10) REFERENCES Assignments(CourseCode),
AssCode varchar(10) REFERENCES Assignments(AssCode),
primary key (CourseCode,BSN,AssCode)
);
I found the answer:
CREATE TABLE WorkOn (
BSN int primary key REFERENCES Teachers(BSN),
CourseCode varchar(10),
AssCode varchar(10),
foreign key (CourseCode, AssCode) references Assignments (CourseCode, AssCode)
);