5019COMP Coursework 2
Drop if Exists
DROP PROCEDURE IF EXISTS new_loan;
DROP TRIGGER IF EXISTS loan_overdue;
DROP TABLE IF EXISTS overdue;
DROP VIEW IF EXISTS student_cmp;
DROP
DROP
DROP
DROP
TABLE
TABLE
TABLE
TABLE
IF
IF
IF
IF
EXISTS
EXISTS
EXISTS
EXISTS
loan;
copy;
book;
student;
Create Tables
Tables
CREATE TABLE book(
isbn CHAR (17) NOT NULL,
title VARCHAR (30) NOT NULL,
author VARCHAR (30) NOT NULL,
CONSTRAINT pri_book
PRIMARY KEY (isbn)
);
CREATE TABLE student(
`no` INT NOT NULL,
`name` VARCHAR (30) NOT NULL,
school CHAR (3) NOT NULL,
embargo BIT DEFAULT 0,
CONSTRAINT pri_student
PRIMARY KEY (`no`)
);
CREATE TABLE copy(
`code` INT NOT NULL,
isbn CHAR (17),
duration TINYINT NOT NULL,
CONSTRAINT pri_copy
PRIMARY KEY (`code`),
CONSTRAINT for_copy
FOREIGN KEY (isbn) REFERENCES book (isbn),
CONSTRAINT chk_copy
CHECK (duration IN (7, 14, 21))
);
CREATE TABLE loan(
`code` INT NOT NULL,
`no` INT NOT NULL,
taken DATE NOT NULL,
due DATE NOT NULL,
returned DATE DEFAULT NULL,
CONSTRAINT for_loan_code
FOREIGN KEY (`code`) REFERENCES copy (`code`),
CONSTRAINT for_loan_no
FOREIGN KEY (`no`) REFERENCES student (`no`),
CONSTRAINT pri_loan
PRIMARY KEY (`code`,`no`,taken)
);
Indexes
CREATE
CREATE
CREATE
CREATE
CREATE
INDEX
INDEX
INDEX
INDEX
INDEX
in_student_name ON student (`name`);
in_student_school ON student (school);
in_book_title ON book (title);
in_loan_taken ON loan (taken);
in_loan_due ON loan (due);
Insert Into
Book
INSERT INTO book VALUE ('111-2-33-444444-5', 'Pro JavaFX', 'Dave Smith');
INSERT INTO book VALUE ('222-3-44-555555-6', 'Oracle Systems', 'Kate
Roberts');
INSERT INTO book VALUE ('333-4-55-666666-7', 'Expert jQuery', 'Mike
Smith');
Student
INSERT
INSERT
INSERT
INSERT
INSERT
INTO
INTO
INTO
INTO
INTO
student
student
student
student
student
INTO
INTO
INTO
INTO
INTO
INTO
copy
copy
copy
copy
copy
copy
VALUE
VALUE
VALUE
VALUE
VALUE
(2001,
(2002,
(2003,
(2004,
(2005,
'Mike', 'CMP', 0);
'Andy', 'CMP', 1);
'Sarah', 'ENG', 0);
'Karen', 'ENG', 1);
'Lucy', 'BUE', 0);
Copy
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
VALUE
VALUE
VALUE
VALUE
VALUE
VALUE
(1011,
(1012,
(1013,
(2011,
(3011,
(3012,
'111-2-33-444444-5',
'111-2-33-444444-5',
'111-2-33-444444-5',
'222-3-44-555555-6',
'333-4-55-666666-7',
'333-4-55-666666-7',
21);
14);
7);
21);
7);
14);
Loan
INSERT
INSERT
10');
INSERT
16');
INSERT
20');
INSERT
INSERT
20');
INTO loan VALUE (1011, 2003, '2017-05-10', '2017-05-31', NULL);
INTO loan VALUE (1013, 2003, '2016-03-02', '2016-03-16', '2016-03INTO loan VALUE (1013, 2002, '2016-08-02', '2016-08-16', '2016-08INTO loan VALUE (2011, 2004, '2015-02-01', '2015-02-22', '2015-02INTO loan VALUE (3011, 2002, '2017-07-03', '2017-07-10', NULL);
INTO loan VALUE (3011, 2005, '2016-10-10', '2016-10-17', '2016-10-
Create View
View
CREATE VIEW student_cmp AS
SELECT `no`, `name`, school, embargo
FROM student
WHERE school = 'CMP'
WITH CHECK OPTION;
;
Check Data
INSERT INTO student_cmp VALUE (1234, 'John Doe', 'ABC', 0);
Create Trigger
Overdue Table
CREATE TABLE overdue (
overdue_no INT NOT NULL AUTO_INCREMENT,
`no` INT NOT NULL,
taken DATE NOT NULL,
due_date DATE NOT NULL,
returned DATE,
CONSTRAINT pri_overdue PRIMARY KEY (overdue_no),
CONSTRAINT for_no FOREIGN KEY (`no`) REFERENCES student(`no`)
);
Trigger
DELIMITER $$
CREATE TRIGGER `loan_overdue` AFTER UPDATE ON loan FOR EACH ROW
BEGIN
IF NEW.returned > OLD.due THEN
INSERT INTO overdue (`no`, taken, due, returned)
VALUES (OLD.`no`, OLD.taken, OLD.due, NEW.returned);
END IF;
END$$
DELIMITER ;
Create Procedure
DELIMITER $$
CREATE PROCEDURE new_loan(IN loan_isbn CHAR(17), IN loan_student INT(11) )
BEGIN
DECLARE student_embargoed BIT DEFAULT NULL;
DECLARE complete BOOLEAN DEFAULT FALSE;
DECLARE loan_code INT;
DECLARE loan_duration TINYINT;
DECLARE loan_available BIT DEFAULT NULL;
DECLARE code_c CURSOR FOR
SELECT `code`
FROM copy
WHERE loan_isbn = isbn;
DECLARE duration_c CURSOR FOR
SELECT duration
FROM copy
WHERE loan_isbn = isbn;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET complete = TRUE;
OPEN code_c;
OPEN duration_c;
loan_loop : LOOP
FETCH code_c INTO loan_code;
FETCH duration_c INTO loan_duration;
IF complete THEN
LEAVE loan_loop;
END IF;
END LOOP;
IF (loan_code IS NOT NULL) THEN
SET loan_available = 1;
ELSEIF (SELECT returned FROM loan WHERE loan_code = `code` IS
NOT NULL) THEN
SET loan_available = 1;
END IF;
IF (SELECT embargo FROM student WHERE loan_student = `no` = 1)
THEN
SET student_embargoed = 1;
ELSE SET student_embargoed = 0;
END IF;
IF (student_embargoed = 1) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'WARNING: STUDENT UNDER EMBARGO,
LOAN NOT ISSUED.', MYSQL_ERRNO = 1001;
ELSEIF (loan_available = NULL) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'WARNING : NO COPIES OF
BOOK AVAILABLE, LOAN NOT ISSUED.', MYSQL_ERRNO = 1001;
ELSE
INSERT INTO loan VALUE (loan_code, loan_student,
NOW(), DATE_ADD(NOW(), INTERVAL loan_duration DAY), NULL);
END IF;
END$$
DELIMITER ;
Queries
Fetch Every Book’s Isbn, Title & Author
SELECT isbn,title,author
FROM book;
Fetch Every Student’s No, Name & School in Descending Order by School
SELECT `no`,`name`,school
FROM student
ORDER BY school DESC;
Fetch Any Book’s Isbn & Title Where That Book’s Author Contains the String “Smith”
SELECT isbn,title
FROM book
WHERE author LIKE '%Smith%';
Calculate the Latest Due Date for Any Book Copy
SELECT MAX(due)
FROM loan;
Modify the Query from Q4 to Now Fetch Only the Student No
SELECT `no`
FROM loan
WHERE due IN (SELECT MAX(due) FROM loan);
Modify the Query from Q5 to Also Fetch the Student Name
SELECT `no`, `name`
FROM student
WHERE `no` IN (SELECT `no` FROM loan
WHERE due IN (SELECT MAX(due) FROM loan));
Fetch the Student No, Copy Code & Due Date for Loans in the Current Year Which Have Not
Yet Been Returned
SELECT `no`,`code`,due
FROM loan
WHERE YEAR(taken) = YEAR(CURRENT_DATE()) AND returned IS NULL;
Solve the Problem from Q6 Using JOINS Where Possible
SELECT student.`no`, `name`
FROM student
INNER JOIN loan
ON student.`no` = loan.`no`
WHERE due IN (SELECT MAX(due) FROM loan);
Uniquely Fetch the Student No & Name Along With the Book Isbn & Title For Students Who
Have Loaned A 7 Day Duration Book
SELECT DISTINCT student.`no`, student.`name`, book.title, book.isbn
FROM loan
INNER JOIN student
ON loan.`no` = student.`no`
INNER JOIN copy
ON loan.`code` = copy.`code`
INNER JOIN book
ON copy.isbn = book.isbn
WHERE copy.duration = 7;
Calculate Then Display the Loan Frequency for Every Book Which Has Been Loaned
Two or More Times
SELECT book.isbn, book.title, COUNT(loan.`code`) AS frequency
FROM book
INNER JOIN copy
ON book.isbn = copy.isbn
INNER JOIN loan
ON copy.`code` = loan.`code`
GROUP BY isbn
HAVING COUNT(loan.`code`) >= 2;
© Copyright 2026 Paperzz