DBMS School Management Report Final-1
DBMS School Management Report Final-1
A PROJECT REPORT
Submitted by
SAI VASANTH G (RA2212702010030)
BACHELOR OF TECHNOLOGY
in
COMPUTER SCIENCE AND ENGINEERING
1
SRM INSTITUTE OF SCIENCE AND TECHNOLOGY
KATTANKULATHUR–603 203
BONAFIDE CERTIFICATE
Date:
2
ABSTRACT
3
PROBLEM STATEMENT
4
TABLE OF CONTENTS
5
CHAPTER – 1
1.1 Introduction
The School Management System (SMS) project presents an innovative approach to
revolutionizing school administrative processes. Traditionally, educational institutions have
relied on manual methods for student enrollment, attendance tracking, and academic record-
keeping, resulting in inefficiencies, inaccuracies, and security risks. However, the SMS
project seeks to address these issues by introducing a modern, automated system that
streamlines key operations, enhances data accuracy, and strengthens security protocols.
Through the utilization of technology to centralize data management, implement unique
identifiers for students and staff, and enforce secure login credentials for authorized users,
the SMS project aims to transform traditional school management practices. By doing so, it
promises to significantly improve efficiency, accuracy, and confidentiality within educational
institutions, ultimately fostering a more productive and student-focused learning
environment. This introduction lays the foundation for understanding the importance and
objectives of the SMS project in modernizing school management practices for enhanced
effectiveness and student success.
1.2 Problem Understanding
The School Management System (SMS) project aims to modernize educational institutions
by replacing manual processes with automation. Traditional methods, such as paper-based
records, result in errors, redundancies, and security vulnerabilities. The SMS proposes a
centralized digital platform to streamline operations, ensuring data accuracy and
safeguarding student and staff information through encryption and user authentication. It
enhances efficiency and coordination with clear task assignments, automated reminders, and
real-time visibility into school activities. Administrators can continuously monitor
performance metrics to improve operational processes. Ultimately, the SMS project seeks to
optimize efficiency, accuracy, and security while enhancing the overall quality of education
and student experiences within the school.
6
1.3 Modules Involved
1 Login
2 Admin Dashboard
3 Student Management
4 Add Student
5 Update Student Information
6 Delete Student
7 Staff Management
8 Add Staff
9 Update Staff Information
10 Delete Staff
11 Class Management
12 Add Class
13 Update Class Information
14 Delete Class
7
1.4 Identification Of Entities
SCHOOL :
Attributes: affliation id , name , location , branch , contactno.
STUDENTS :
Attributes: Studentid, Name, emailid , contactno.
BUILDINGS :
Attributes: Buildingname , Buildingno, location , floors.
EMPLOYEES:
Attributes: Employeeid, name , department , position .
COURSES:
Attributes: Courseid , Coursename , Coursetype , studentid(Foreign key).
REGISTRATIONS :
Attributes: Regid, regtype , courseid(Foreign key)
SUBJECTS :
Attributes: Subjectid , Subjectname , sylabus , coursetype.
PLAYGROUNDS:
Attributes : Capacity , groundtype , location.
PAYMENT :
Attributes : Paymentid , mode , amount , paymentdate.
CLASSROOMS:
Attributes : Roomno , buildingname , floor.
8
1.5 Construction Of ER Diagram
Fig1.ER Diagram
1.6 Construction of a database
Using the entities we have and through following the guidelines to develop a database. We constructed a
database named database4 in ORACLE SQL
1.5.1 Rules followed
In our project we have only strong entity set so if we wanted to convert that ER diagram into tables we
should follow these rules
1. Entity becomes table
2. Single valued attribute /simple attributes becomes columns
3. Ignore derived attributes
4. Simple attributes of composite attributes are considered but ignore composite attributes
5. Multivalued attributes are represented by a separate table
9
6. Ket attribute becomes primary key
7. Strong entity – entity which uses primary key is called as strong entity.
CHAPTER – 2
2.1 Architecture
The architecture of our project is as follows:
10
2.2 Design Of Relational Schemas
SCHOOL MANAGEMENT SYSTEM :
Schools’s table:
Affliationid schoolname contactno Location Branch
Student’s table:
Studentid Name Contactno emailid
Admission’s table:
Applicationid applicationno appdate
Course’s table:
Courseid Coursename Coursetype Studentid
Employee’s table:
Employeeid name Department position
Payment’s table:
Paymentid Paymentmode amount Paymentdate
Registration’s table:
Regid Regtype Courseid
Subjects table:
Subjectid Subjectname Sylabus Coursetype
Teacher’s table:
Teacherid Teachername Emailed contactno
Building’s table:
Buildingname Buildingno Floors Location
Playground’s table:
Groundtype Capacity Location
Washroom’s table:
Washroomtype Buildingname Floor
Busdriver’s:
Driverid Name contactno Busnos
Classroom’s table:
Roomno Buildingname Floors
ADMISSION
BUILDINGS
12
CONSTRAINT "BUILDINGS_PK" PRIMARY KEY ("BUILDINGNAME")
BUSDRIVERS
CLASSROOMS
CONTACT NO
13
Fig. CONTACT NO TABLE
COURSES
DEPARTMENT
EMPLOYEE
PAYMENT
PLAYGROUNDS
15
Fig. PLAYGROUNDS TABLE
REGISTRATION
SCHOOL
STUDENTS
16
Fig. STUDENTS TABLE
SUBJECTS
TEACHERS
TRANSACTION _LOG
CHAPTER – 3
3.2 QUERIES
PROGRAM
1.Cursor
DECLARE
CURSOR admission_cursor IS
SELECT APPLICATIONID, APPLICATIONNAME, APP_DATE FROM ADMISSION;
v_APPLICATIONID ADMISSION.APPLICATIONID%TYPE;
v_APPLICATIONNAME ADMISSION.APPLICATIONNAME%TYPE;
v_APP_DATE ADMISSION.APP_DATE%TYPE;
BEGIN
OPEN admission_cursor;
LOOP
FETCH admission_cursor INTO v_APPLICATIONID, v_APPLICATIONNAME, v_APP_DATE;
EXIT WHEN admission_cursor%NOTFOUND;
2.Join
3. Trigger
CREATE OR REPLACE TRIGGER UpdateBuildingStatus
AFTER INSERT OR UPDATE OR DELETE ON ADMISSION
FOR EACH ROW
BEGIN
-- Example action: Update building status based on changes in ADMISSION table
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('New admission record inserted. Update building status here...');
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('Admission record updated. Update building status here...');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Admission record deleted. Update building status here...');
END IF;
END;
4. Set Operation
SELECT APPLICATIONID, APPLICATIONNAME, APP_DATE FROM ADMISSION
UNION ALL
SELECT NAME AS APPLICATIONID, DEPARTMENT AS APPLICATIONNAME, POSITION AS APP_DATE
FROM EMPLOYEE;
5. View
CREATE VIEW AdmissionDetailsss AS
SELECT APPLICATIONID, APPLICATIONNAME, APP_DATE FROM ADMISSION;
6.Constraint
20
---BUILDINGS---
1.CURSOR
DECLARE
CURSOR building_cursor IS
SELECT BUILDINGNAME, BUILDINGNO, FLOORS, LOCATION FROM BUILDINGS;
v_BUILDINGNAME BUILDINGS.BUILDINGNAME%TYPE;
v_BUILDINGNO BUILDINGS.BUILDINGNO%TYPE;
v_FLOORS BUILDINGS.FLOORS%TYPE;
v_LOCATION BUILDINGS.LOCATION%TYPE;
BEGIN
OPEN building_cursor;
LOOP
21
FETCH building_cursor INTO v_BUILDINGNAME, v_BUILDINGNO, v_FLOORS, v_LOCATION;
EXIT WHEN building_cursor%NOTFOUND;
2.JOIN
SELECT A.BUILDINGNAME, A.BUILDINGNO, A.FLOORS, B.APPLICATIONID, B.APPLICATIONNAME,
B.APP_DATE
FROM BUILDINGS A
INNER JOIN ADMISSION B ON A.BUILDINGNO = B.APPLICATIONID;
3.TRIGGER
4.VIEW
CREATE VIEW BuildingDetailss AS
SELECT BUILDINGNAME, BUILDINGNO, FLOORS, LOCATION FROM BUILDINGS;
5.CONSTRAINT
ALTER TABLE BUILDINGS
ADD CONSTRAINT chk_buildingname_length CHECK (LENGTH(BUILDINGNAME) <= 50);
6.SET OPERATIONS
22
---BUSDRIVERS---
1.CURSOR
DECLARE
CURSOR driver_cursor IS
SELECT DRIVERID, NAME, CONTACTNO, BUSNOS FROM BUSDRIVERS;
v_DRIVERID BUSDRIVERS.DRIVERID%TYPE;
23
v_NAME BUSDRIVERS.NAME%TYPE;
v_CONTACTNO BUSDRIVERS.CONTACTNO%TYPE;
v_BUSNOS BUSDRIVERS.BUSNOS%TYPE;
BEGIN
OPEN driver_cursor;
LOOP
FETCH driver_cursor INTO v_DRIVERID, v_NAME, v_CONTACTNO, v_BUSNOS;
EXIT WHEN driver_cursor%NOTFOUND;
2.VIEW
3.TRIGGER
4.SET OPERATIONS
5.CONSTRAINT
6. JOIN OPERATION
24
SELECT
A.DriverID AS DriverID_1,
A.Name AS DriverName_1,
A.ContactNo AS ContactNo_1,
B.DriverID AS DriverID_2,
B.Name AS DriverName_2,
B.ContactNo AS ContactNo_2
FROM
BUSDRIVERS A
INNER JOIN
BUSDRIVERS B
ON
A.ContactNo = B.ContactNo
AND
A.DriverID < B.DriverID;
25
---CLASSROOMS----
1.CURSOR
DECLARE
v_ROOMNO CLASSROOMS.ROOMNO%TYPE;
v_BUILDINGNAME CLASSROOMS.BUILDINGNAME%TYPE;
v_FLOOR CLASSROOMS.FLOOR%TYPE;
BEGIN
FOR rec IN (SELECT ROOMNO, BUILDINGNAME, FLOOR FROM CLASSROOMS) LOOP
-- Assign values to variables
v_ROOMNO := rec.ROOMNO;
v_BUILDINGNAME := rec.BUILDINGNAME;
v_FLOOR := rec.FLOOR;
2.VIEW
3.TRIGGER
CREATE OR REPLACE TRIGGER UpdateClassroomStatus
AFTER INSERT OR UPDATE OR DELETE ON CLASSROOMS
FOR EACH ROW
BEGIN
-- Example action: Update classroom status based on changes in CLASSROOMS table
IF INSERTING THEN
26
DBMS_OUTPUT.PUT_LINE('New classroom record inserted. Update classroom status here...');
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('Classroom record updated. Update classroom status here...');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Classroom record deleted. Update classroom status here...');
END IF;
END;
4.SETOPERATION
5.JOIN
SELECT
A.ROOMNO AS RoomNo_1,
A.BUILDINGNAME AS BuildingName_1,
A.FLOOR AS Floor_1,
B.ROOMNO AS RoomNo_2,
B.BUILDINGNAME AS BuildingName_2,
B.FLOOR AS Floor_2
FROM
CLASSROOMS A
INNER JOIN
CLASSROOMS B
ON
A.BUILDINGNAME = B.BUILDINGNAME
AND
A.ROOMNO < B.ROOMNO;
6.CONSTRAINT
27
--CONTACTNO—
1. Cursor
DECLARE
CURSOR contactno_cursor IS
SELECT CONTACTNO1, CONTACTNO2, CONTACTNO3, DRIVERID FROM CONTACTNO;
v_CONTACTNO1 CONTACTNO.CONTACTNO1%TYPE;
v_CONTACTNO2 CONTACTNO.CONTACTNO2%TYPE;
v_CONTACTNO3 CONTACTNO.CONTACTNO3%TYPE;
v_DRIVERID CONTACTNO.DRIVERID%TYPE;
BEGIN
OPEN contactno_cursor;
LOOP
FETCH contactno_cursor INTO v_CONTACTNO1, v_CONTACTNO2, v_CONTACTNO3, v_DRIVERID;
EXIT WHEN contactno_cursor%NOTFOUND;
28
2. TRIGGER
3.VIEW
4.CONSTRAINT
ALTER TABLE CONTACTNO
ADD CONSTRAINT check_contactno_not_null CHECK (CONTACTNO1 IS NOT NULL OR CONTACTNO2 IS
NOT NULL OR CONTACTNO3 IS NOT NULL);
5.JOIN
SELECT
A.CONTACTNO1 AS ContactNo1_1,
A.CONTACTNO2 AS ContactNo2_1,
A.CONTACTNO3 AS ContactNo3_1,
A.DRIVERID AS DriverID_1,
B.CONTACTNO1 AS ContactNo1_2,
B.CONTACTNO2 AS ContactNo2_2,
B.CONTACTNO3 AS ContactNo3_2,
B.DRIVERID AS DriverID_2
FROM
CONTACTNO A
INNER JOIN
CONTACTNO B
ON
A.DRIVERID < B.DRIVERID;
6.SET OPERATIONS
SELECT ROOMNO AS ID, FLOOR AS Attribute
FROM CLASSROOMS
MINUS
SELECT CONTACTNO1 AS ID, CONTACTNO2 AS Attribute
FROM CONTACTNO;
29
-- COURSES--
1.CURSOR
DECLARE
CURSOR courses_cursor IS
SELECT COURSEID, COURSENAME, COURSETYPE, STUDENTID FROM COURSES;
v_COURSEID COURSES.COURSEID%TYPE;
v_COURSENAME COURSES.COURSENAME%TYPE;
v_COURSETYPE COURSES.COURSETYPE%TYPE;
v_STUDENTID COURSES.STUDENTID%TYPE;
BEGIN
FOR rec IN courses_cursor LOOP
-- Assign values to variables
v_COURSEID := rec.COURSEID;
v_COURSENAME := rec.COURSENAME;
v_COURSETYPE := rec.COURSETYPE;
v_STUDENTID := rec.STUDENTID;
2.TRIGGER
30
DBMS_OUTPUT.PUT_LINE('New course record inserted. Update course status here...');
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('Course record updated. Update course status here...');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Course record deleted. Update course status here...');
END IF;
END;
3.VIEW
4.CONSTRAINT
5.JOIN
SELECT
A.COURSEID AS CourseID_1,
A.COURSENAME AS CourseName_1,
A.COURSETYPE AS CourseType_1,
A.STUDENTID AS StudentID_1,
B.COURSEID AS CourseID_2,
B.COURSENAME AS CourseName_2,
B.COURSETYPE AS CourseType_2,
B.STUDENTID AS StudentID_2
FROM
COURSES A
INNER JOIN
COURSES B
ON
A.STUDENTID < B.STUDENTID;
6.SET OPERATION
31
--EMPLOYEE--
1.VIEW
CREATE VIEW EmployeeDetails AS
SELECT EMPLOYEEID, NAME, DEPARTMENT, POSITION FROM EMPLOYEE;
2.TRIGGER
CREATE OR REPLACE TRIGGER UpdateEmployeeStatus
AFTER INSERT OR UPDATE OR DELETE ON EMPLOYEE
FOR EACH ROW
BEGIN
-- Example action: Update employee status based on changes in EMPLOYEES table
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('New employee record inserted. Update employee status here...');
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('Employee record updated. Update employee status here...');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Employee record deleted. Update employee status here...');
END IF;
END;
3.CONSTRAINT
4.JOIN
SELECT
A.EMPLOYEEID AS EmployeeID_1,
A.NAME AS Name_1,
A.DEPARTMENT AS Department_1,
A.POSITION AS Position_1,
B.EMPLOYEEID AS EmployeeID_2,
B.NAME AS Name_2,
B.DEPARTMENT AS Department_2,
B.POSITION AS Position_2
FROM
EMPLOYEE A
INNER JOIN
EMPLOYEE B
ON
A.EMPLOYEEID < B.EMPLOYEEID;
5.SETOPERATIONS
32
6.CURSOR
DECLARE
CURSOR employees_cursor IS
SELECT EMPLOYEEID, NAME, DEPARTMENT, POSITION FROM EMPLOYEES;
v_EMPLOYEEID EMPLOYEES.EMPLOYEEID%TYPE;
v_NAME EMPLOYEES.NAME%TYPE;
v_DEPARTMENT EMPLOYEES.DEPARTMENT%TYPE;
v_POSITION EMPLOYEES.POSITION%TYPE;
BEGIN
FOR rec IN employees_cursor LOOP
-- Assign values to variables
v_EMPLOYEEID := rec.EMPLOYEEID;
v_NAME := rec.NAME;
v_DEPARTMENT := rec.DEPARTMENT;
v_POSITION := rec.POSITION;
--PARENTS--
1.VIEW
CREATE VIEW ParentDetails AS
SELECT NAME, CONTACTNO, LOCATION FROM PARENTS;
2.TRIGGER
33
CREATE OR REPLACE TRIGGER UpdateParentStatus
AFTER INSERT OR UPDATE OR DELETE ON PARENTS
FOR EACH ROW
BEGIN
-- Example action: Update parent status based on changes in PARENTS table
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('New parent record inserted. Update parent status here...');
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('Parent record updated. Update parent status here...');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Parent record deleted. Update parent status here...');
END IF;
END;
3.CONSTRAINT
4.JOIN
SELECT
A.NAME AS Name_1,
A.CONTACTNO AS ContactNo_1,
A.LOCATION AS Location_1,
B.NAME AS Name_2,
B.CONTACTNO AS ContactNo_2,
B.LOCATION AS Location_2
FROM
PARENTS A
INNER JOIN
PARENTS B
ON
A.NAME < B.NAME;
5.SET OPERATIONS
SELECT LOCATION AS ID, NAME AS Attribute
FROM PARENTS
UNION ALL
SELECT NAME AS ID, TO_CHAR(CONTACTNO) AS Attribute
FROM PARENTS
6.CURSOR
-- Declare the cursor
DECLARE
CURSOR parents_cursor IS
SELECT NAME, CONTACTNO, LOCATION FROM PARENTS;
-- PAYMENT--
1.VIEW
CREATE VIEW PaymentDetails AS
SELECT PAYMENTID, AMOUNT, PAYMENTDATE, PAYMENTMODE FROM PAYMENT;
2.TRIGGER
CREATE OR REPLACE TRIGGER UpdatePaymentStatus
AFTER INSERT OR UPDATE OR DELETE ON PAYMENT
FOR EACH ROW
BEGIN
-- Example action: Update payment status based on changes in PAYMENT table
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('New payment record inserted. Update payment status here...');
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('Payment record updated. Update payment status here...');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Payment record deleted. Update payment status here...');
END IF;
END;
35
3.CONSTRAINT
ALTER TABLE PAYMENT
ADD CONSTRAINT check_positive_paymentid CHECK (PAYMENTID > 0);
4.JOIN
SELECT
A.PAYMENTID AS PaymentID_1,
A.AMOUNT AS Amount_1,
A.PAYMENTDATE AS PaymentDate_1,
A.PAYMENTMODE AS PaymentMode_1,
B.PAYMENTID AS PaymentID_2,
B.AMOUNT AS Amount_2,
B.PAYMENTDATE AS PaymentDate_2,
B.PAYMENTMODE AS PaymentMode_2
FROM
PAYMENT A
INNER JOIN
PAYMENT B
ON
A.PAYMENTID < B.PAYMENTID;
5. SETOPERATIONS
6.CURSOR
DECLARE
CURSOR payment_cursor IS
SELECT PAYMENTID, AMOUNT, PAYMENTDATE, PAYMENTMODE FROM PAYMENT;
v_PAYMENTID PAYMENT.PAYMENTID%TYPE;
v_AMOUNT PAYMENT.AMOUNT%TYPE;
v_PAYMENTDATE PAYMENT.PAYMENTDATE%TYPE;
v_PAYMENTMODE PAYMENT.PAYMENTMODE%TYPE;
BEGIN
FOR rec IN payment_cursor LOOP
-- Assign values to variables
v_PAYMENTID := rec.PAYMENTID;
v_AMOUNT := rec.AMOUNT;
v_PAYMENTDATE := rec.PAYMENTDATE;
v_PAYMENTMODE := rec.PAYMENTMODE;
1.VIEW
CREATE VIEW WashroomDetails AS
SELECT WASHROOMTYPE, BUILDINGNAME, FLOOR FROM WASHROOMS;
2.TRIGGER
3.CONSTRAINT
4.JOIN
SELECT
A.WASHROOMTYPE AS WashroomType_1,
A.BUILDINGNAME AS BuildingName_1,
A.FLOOR AS Floor_1,
B.WASHROOMTYPE AS WashroomType_2,
B.BUILDINGNAME AS BuildingName_2,
B.FLOOR AS Floor_2
FROM
WASHROOMS A
INNER JOIN
WASHROOMS B
ON
A.BUILDINGNAME = B.BUILDINGNAME
AND
A.WASHROOMTYPE < B.WASHROOMTYPE;
5.SET OPERATION
6.CURSOR
DECLARE
CURSOR washrooms_cursor IS
SELECT WASHROOMTYPE, BUILDINGNAME, FLOOR FROM WASHROOMS;
v_WASHROOMTYPE WASHROOMS.WASHROOMTYPE%TYPE;
v_BUILDINGNAME WASHROOMS.BUILDINGNAME%TYPE;
v_FLOOR WASHROOMS.FLOOR%TYPE;
BEGIN
FOR rec IN washrooms_cursor LOOP
-- Assign values to variables
v_WASHROOMTYPE := rec.WASHROOMTYPE;
v_BUILDINGNAME := rec.BUILDINGNAME;
v_FLOOR := rec.FLOOR;
7.
8.
38
-- PLAYGROUNDS--
1.VIEW
2.TRIGGER
CREATE OR REPLACE TRIGGER UpdatePlaygroundStatus
AFTER INSERT OR UPDATE OR DELETE ON PLAYGROUNDS
FOR EACH ROW
BEGIN
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('New playground record inserted. Update playground status here...');
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('Playground record updated. Update playground status here...');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Playground record deleted. Update playground status here...');
END IF;
END;
3.CONSTRAINT
ALTER TABLE PLAYGROUNDS
ADD CONSTRAINT check_capacity_positive CHECK (CAPACITY > 0);
4.JOIN
SELECT
A.LOCATION AS Location_1,
A.GROUNDTYPE AS GroundType_1,
39
A.CAPACITY AS Capacity_1,
B.LOCATION AS Location_2,
B.GROUNDTYPE AS GroundType_2,
B.CAPACITY AS Capacity_2
FROM
PLAYGROUNDS A
INNER JOIN
PLAYGROUNDS B
ON
A.LOCATION < B.LOCATION;
5.SET OPERATIONS
6.CURSOR
DECLARE
CURSOR playgrounds_cursor IS
SELECT LOCATION, GROUNDTYPE, CAPACITY
FROM PLAYGROUNDS;
v_LOCATION PLAYGROUNDS.LOCATION%TYPE;
v_GROUNDTYPE PLAYGROUNDS.GROUNDTYPE%TYPE;
v_CAPACITY PLAYGROUNDS.CAPACITY%TYPE;
BEGIN
FOR rec IN playgrounds_cursor LOOP
v_LOCATION := rec.LOCATION;
v_GROUNDTYPE := rec.GROUNDTYPE;
v_CAPACITY := rec.CAPACITY;
DBMS_OUTPUT.PUT_LINE('Location: ' || v_LOCATION || ', Ground Type: ' || v_GROUNDTYPE || ', Capacity: '
|| v_CAPACITY);
END LOOP;
END;
--REGISTRATION--
1.VIEW
2.TRIGGER
3.JOIN
SELECT
A.REGID AS RegID_1,
A.COURSEID AS CourseID_1,
A.REGTYPE AS RegType_1,
B.REGID AS RegID_2,
B.COURSEID AS CourseID_2,
B.REGTYPE AS RegType_2
FROM
REGISTRATION A
INNER JOIN
REGISTRATION B
ON
A.REGID < B.REGID;
4.SETOPERATIONS
5.CURSOR
DECLARE
CURSOR registration_cursor IS
SELECT REGID, COURSEID, REGTYPE
FROM REGISTRATION;
v_REGID REGISTRATION.REGID%TYPE;
v_COURSEID REGISTRATION.COURSEID%TYPE;
v_REGTYPE REGISTRATION.REGTYPE%TYPE;
BEGIN
FOR rec IN registration_cursor LOOP
v_REGID := rec.REGID;
v_COURSEID := rec.COURSEID;
v_REGTYPE := rec.REGTYPE;
DBMS_OUTPUT.PUT_LINE('Registration ID: ' || v_REGID || ', Course ID: ' || v_COURSEID || ', Registration
Type: ' || v_REGTYPE);
END LOOP;
END;
6.CONSTRAINT
41
ALTER TABLE REGISTRATION
ADD CONSTRAINT check_course_id_positive CHECK (COURSEID > 0);
--SCHOOL--
1.VIEW
CREATE VIEW SchoolDetails AS
SELECT SCHOOLNAME, CONTACTNO, LOCATION, BRANCH FROM SCHOOL;
2.TRIGGER
3.CONSTRAINT
4.JOIN
SELECT
A.SCHOOLNAME AS SchoolName_1,
A.LOCATION AS Location_1,
B.SCHOOLNAME AS SchoolName_2,
B.LOCATION AS Location_2
FROM
SCHOOL A
INNER JOIN
SCHOOL B
ON
A.LOCATION = B.LOCATION
AND
A.SCHOOLNAME < B.SCHOOLNAME;
5.SETOPERATION
6.CURSOR
DECLARE
CURSOR school_cursor IS
SELECT SCHOOLNAME, CONTACTNO, LOCATION, BRANCH FROM SCHOOL;
42
v_SCHOOLNAME SCHOOL.SCHOOLNAME%TYPE;
v_CONTACTNO SCHOOL.CONTACTNO%TYPE;
v_LOCATION SCHOOL.LOCATION%TYPE;
v_BRANCH SCHOOL.BRANCH%TYPE;
BEGIN
FOR rec IN school_cursor LOOP
-- Assign values to variables
v_SCHOOLNAME := rec.SCHOOLNAME;
v_CONTACTNO := rec.CONTACTNO;
v_LOCATION := rec.LOCATION;
v_BRANCH := rec.BRANCH;
--STUDENTS--
1.VIEW
2.TRIGGER
3.CONSTRAINT
4. JOIN
SELECT
A.STUDENTID AS StudentID_1,
A.FIRST_NAME AS FirstName_1,
B.STUDENTID AS StudentID_2,
B.FIRST_NAME AS FirstName_2
FROM
STUDENTS A
INNER JOIN
STUDENTS B
43
ON
A.CONTACTNO = B.CONTACTNO
AND
A.STUDENTID < B.STUDENTID;
5.SET OPERATIONS
6.CURSOR
DECLARE
CURSOR students_cursor IS
SELECT STUDENTID, CONTACTNO, EMAILID, FIRST_NAME, LAST_NAME FROM STUDENTS;
v_STUDENTID STUDENTS.STUDENTID%TYPE;
v_CONTACTNO STUDENTS.CONTACTNO%TYPE;
v_EMAILID STUDENTS.EMAILID%TYPE;
v_FIRST_NAME STUDENTS.FIRST_NAME%TYPE;
v_LAST_NAME STUDENTS.LAST_NAME%TYPE;
BEGIN
FOR rec IN students_cursor LOOP
-- Assign values to variables
v_STUDENTID := rec.STUDENTID;
v_CONTACTNO := rec.CONTACTNO;
v_EMAILID := rec.EMAILID;
v_FIRST_NAME := rec.FIRST_NAME;
v_LAST_NAME := rec.LAST_NAME;
-- SUBJECTS--
1.CURSOR
DECLARE
CURSOR subject_cursor IS
SELECT SUBJECTID, SUBJECTNAME FROM SUBJECTS;
BEGIN
FOR subject_rec IN subject_cursor LOOP
DBMS_OUTPUT.PUT_LINE(subject_rec.SUBJECTNAME);
END LOOP;
END;
44
2.JOIN
3.CONSTRAINT
4.TRIGGER
5.VIEW
6.SET OPERATIONS
UNION
--TEACHERS--
1.CURSOR
DECLARE
45
CURSOR teacher_cursor IS
SELECT TEACHERNAME FROM TEACHERS;
BEGIN
FOR teacher_rec IN teacher_cursor LOOP
DBMS_OUTPUT.PUT_LINE(teacher_rec.TEACHERNAME);
END LOOP;
END;
2.CONSTRAINTS
3.TRIGGER
4.VIEW
5. JOIN
6. SET OPERATIONS
INTERSECT
7.
46
SELECT TEACHERID, TEACHERNAME, EMAILID
FROM TEACHERS
WHERE EMAILID LIKE '%@gmail.com';
8.
SELECT TEACHERID, TEACHERNAME, CONTACTNO
FROM TEACHERS
WHERE CONTACTNO LIKE '123%';
-- PLAYGROUNDS--
1.VIEW
2.TRIGGER
CREATE OR REPLACE TRIGGER UpdatePlaygroundStatus
AFTER INSERT OR UPDATE OR DELETE ON PLAYGROUNDS
FOR EACH ROW
BEGIN
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('New playground record inserted. Update playground status here...');
ELSIF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('Playground record updated. Update playground status here...');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Playground record deleted. Update playground status here...');
END IF;
END;
3.CONSTRAINT
ALTER TABLE PLAYGROUNDS
ADD CONSTRAINT check_capacity_positive CHECK (CAPACITY > 0);
4.JOIN
SELECT
A.LOCATION AS Location_1,
A.GROUNDTYPE AS GroundType_1,
A.CAPACITY AS Capacity_1,
B.LOCATION AS Location_2,
B.GROUNDTYPE AS GroundType_2,
B.CAPACITY AS Capacity_2
FROM
PLAYGROUNDS A
INNER JOIN
PLAYGROUNDS B
ON
A.LOCATION < B.LOCATION;
5.SET OPERATIONS
6.CURSOR
DECLARE
CURSOR playgrounds_cursor IS
SELECT LOCATION, GROUNDTYPE, CAPACITY
FROM PLAYGROUNDS;
v_LOCATION PLAYGROUNDS.LOCATION%TYPE;
v_GROUNDTYPE PLAYGROUNDS.GROUNDTYPE%TYPE;
v_CAPACITY PLAYGROUNDS.CAPACITY%TYPE;
BEGIN
FOR rec IN playgrounds_cursor LOOP
v_LOCATION := rec.LOCATION;
v_GROUNDTYPE := rec.GROUNDTYPE;
v_CAPACITY := rec.CAPACITY;
DBMS_OUTPUT.PUT_LINE('Location: ' || v_LOCATION || ', Ground Type: ' || v_GROUNDTYPE || ', Capacity: '
|| v_CAPACITY);
END LOOP;
END;
--REGISTRATION--
1.VIEW
2.TRIGGER
3.JOIN
SELECT
A.REGID AS RegID_1,
A.COURSEID AS CourseID_1,
48
A.REGTYPE AS RegType_1,
B.REGID AS RegID_2,
B.COURSEID AS CourseID_2,
B.REGTYPE AS RegType_2
FROM
REGISTRATION A
INNER JOIN
REGISTRATION B
ON
A.REGID < B.REGID;
4.SETOPERATIONS
5.CURSOR
DECLARE
CURSOR registration_cursor IS
SELECT REGID, COURSEID, REGTYPE
FROM REGISTRATION;
v_REGID REGISTRATION.REGID%TYPE;
v_COURSEID REGISTRATION.COURSEID%TYPE;
v_REGTYPE REGISTRATION.REGTYPE%TYPE;
BEGIN
FOR rec IN registration_cursor LOOP
v_REGID := rec.REGID;
v_COURSEID := rec.COURSEID;
v_REGTYPE := rec.REGTYPE;
DBMS_OUTPUT.PUT_LINE('Registration ID: ' || v_REGID || ', Course ID: ' || v_COURSEID || ', Registration
Type: ' || v_REGTYPE);
END LOOP;
END;
6.CONSTRAINT
--SCHOOL--
1.VIEW
CREATE VIEW SchoolDetails AS
SELECT SCHOOLNAME, CONTACTNO, LOCATION, BRANCH FROM SCHOOL;
2.TRIGGER
3.CONSTRAINT
4.JOIN
SELECT
A.SCHOOLNAME AS SchoolName_1,
A.LOCATION AS Location_1,
B.SCHOOLNAME AS SchoolName_2,
B.LOCATION AS Location_2
FROM
SCHOOL A
INNER JOIN
SCHOOL B
ON
A.LOCATION = B.LOCATION
AND
A.SCHOOLNAME < B.SCHOOLNAME;
5.SETOPERATION
6.CURSOR
DECLARE
CURSOR school_cursor IS
SELECT SCHOOLNAME, CONTACTNO, LOCATION, BRANCH FROM SCHOOL;
v_SCHOOLNAME SCHOOL.SCHOOLNAME%TYPE;
v_CONTACTNO SCHOOL.CONTACTNO%TYPE;
v_LOCATION SCHOOL.LOCATION%TYPE;
v_BRANCH SCHOOL.BRANCH%TYPE;
BEGIN
FOR rec IN school_cursor LOOP
-- Assign values to variables
v_SCHOOLNAME := rec.SCHOOLNAME;
v_CONTACTNO := rec.CONTACTNO;
v_LOCATION := rec.LOCATION;
v_BRANCH := rec.BRANCH;
--STUDENTS--
1.VIEW
2.TRIGGER
3.CONSTRAINT
7. JOIN
SELECT
A.STUDENTID AS StudentID_1,
A.FIRST_NAME AS FirstName_1,
B.STUDENTID AS StudentID_2,
B.FIRST_NAME AS FirstName_2
FROM
STUDENTS A
INNER JOIN
STUDENTS B
ON
A.CONTACTNO = B.CONTACTNO
AND
A.STUDENTID < B.STUDENTID;
5.SET OPERATIONS
6.CURSOR
51
DECLARE
CURSOR students_cursor IS
SELECT STUDENTID, CONTACTNO, EMAILID, FIRST_NAME, LAST_NAME FROM STUDENTS;
v_STUDENTID STUDENTS.STUDENTID%TYPE;
v_CONTACTNO STUDENTS.CONTACTNO%TYPE;
v_EMAILID STUDENTS.EMAILID%TYPE;
v_FIRST_NAME STUDENTS.FIRST_NAME%TYPE;
v_LAST_NAME STUDENTS.LAST_NAME%TYPE;
BEGIN
FOR rec IN students_cursor LOOP
-- Assign values to variables
v_STUDENTID := rec.STUDENTID;
v_CONTACTNO := rec.CONTACTNO;
v_EMAILID := rec.EMAILID;
v_FIRST_NAME := rec.FIRST_NAME;
v_LAST_NAME := rec.LAST_NAME;
-- SUBJECTS--
1.CURSOR
DECLARE
CURSOR subject_cursor IS
SELECT SUBJECTID, SUBJECTNAME FROM SUBJECTS;
BEGIN
FOR subject_rec IN subject_cursor LOOP
DBMS_OUTPUT.PUT_LINE(subject_rec.SUBJECTNAME);
END LOOP;
END;
2.JOIN
3.CONSTRAINT
4.TRIGGER
52
CREATE OR REPLACE TRIGGER SYLLABUS_LENGTH_TRIGGER
BEFORE INSERT OR UPDATE ON SUBJECTS
FOR EACH ROW
BEGIN
IF LENGTH(:NEW.SYLABUS) > 1000 THEN
RAISE_APPLICATION_ERROR(-20001, 'Syllabus length exceeds limit.');
END IF;
END;
5.VIEW
6.SET OPERATIONS
UNION
--TEACHERS--
1.CURSOR
DECLARE
CURSOR teacher_cursor IS
SELECT TEACHERNAME FROM TEACHERS;
BEGIN
FOR teacher_rec IN teacher_cursor LOOP
DBMS_OUTPUT.PUT_LINE(teacher_rec.TEACHERNAME);
END LOOP;
END;
2.CONSTRAINTS
3.TRIGGER
4.VIEW
8. JOIN
9. SET OPERATIONS
INTERSECT
7.
8.
SELECT TEACHERID, TEACHERNAME, CONTACTNO
FROM TEACHERS
WHERE CONTACTNO LIKE '123%'
54
CHAPTER – 4
4.1 Analyzing the pitfalls, identifying the dependencies, and applying normalizations
STUDENT TABLE :
STUDENT
------------------------------------------------------
| studentid | contact_no | emailid | first_name | last_name |
|1 | 1234567890 | [email protected]| John | Doe |
|2 | 9876543210 | [email protected]| Jane | Smith |
|3 | 5551234567 | [email protected]| Mike | Johnson |
|4 | 7778889990 | [email protected]| Sarah | Brown |
Department
----------------------
| department_id | department_name |
|1 | Computer Science |
|2 | Mathematics |
|3 | Biology |
|4 | Physics |
The table is further normalized to 2NF by removing partial dependencies. A new attribute "department_id" is
introduced, which is a foreign key referencing the primary key of the DEPARTMENT table. This ensures that
each non-key attribute is fully functionally dependent on the primary key.
DepartmentLocation
--------------------------------
| department_id | department_location |
|1 | Location A |
|2 | Location B |
|3 | Location C |
|4 | Location D |
56
Functional Dependency: department_id → department_name
DepartmentLocation
--------------------------------
| department_id | department_location |
|1 | Location A |
|2 | Location B |
|3 | Location C |
|4 | Location D |
department_id → department_location
Course
--------------------------------
| course_id | course_name |
| 101 | Calculus |
| 102 | Biology 101 |
| 103 | Physics 101 |
| 104 | Computer Science |
Functional Dependency: course_id → course_name
StudentCourse
----------------
| student_id | course_id |
|1 | 101 |
|2 | 104 |
|3 | 102 |
|4 | 103 |
PITFALLS: Pitfalls include dependency on external tables, redundancy in non-key attributes and
increased query complexity due to join operations
1. SUBJECTS TABLE
2NF
Subject
Functional Dependencies: subject_id → subject_name, syllabus, course_id
---------------------------------------------------------
| subject_id | subject_name | syllabus | course_id |
|1 | Mathematics | Calculus | 101 |
|2 | Physics | Mechanics | 102 |
|3 | Literature | Poetry, Prose | 103 |
Since all non-prime attributes (subject_name, syllabus, and course_id) are fully functionally dependent on the entire
primary key (subject_id), the Subject table satisfies the requirements of the second normal form (2NF). Therefore, it
57
can be concluded that the Subject table is in 2NF.
CONVERSION TO 3NF :
MODIFIED TABLES :
Functional Dependencies: subject_id → subject_name, syllabus
Subject
---------------------------------------------------------
| subject_id | subject_name | syllabus | course_id |
|1 | Mathematics | Calculus | 101 |
|2 | Physics | Mechanics | 102 |
|3 | Literature | Poetry, Prose | 103 |
Now, course_name is a transitive dependency because it depends on course_id, which is not part of the primary key.
To convert this into 3NF, we split the table:
Subject
Functional Dependencies: subject_id → subject_name, syllabus
---------------------------------------------------------
| subject_id | subject_name | syllabus | course_id |
|1 | Mathematics | Calculus | 101 |
|2 | Physics | Mechanics | 102 |
|3 | Literature | Poetry, Prose | 103 |
course_id → course_name
Course
------------------------------------
| course_id | course_name |
| 101 | Mathematics Course |
| 102 | Physics Course |
| 103 | Literature Course |
CONVERSION TO 4NF :
Let's say we introduce a new attribute, textbook, which represents the textbooks used for each subject. Since multiple
textbooks can be used for a single subject, this introduces a multi-valued dependency between subject_id and textbook.
MODIFIED TABLE :
Functional Dependencies: subject_id → subject_name, syllabus
Subject
---------------------------------------------------------------
| subject_id | subject_name | syllabus | course_id | textbook |
|1 | Mathematics | Calculus | 101 | Calculus Book1 |
|1 | Mathematics | Calculus | 101 | Calculus Book2 |
|2 | Physics | Mechanics | 102 | Physics Book1 |
58
|3 | Literature | Poetry, Prose | 103 | Literature Book |
2. TEACHERS TABLE :
1NF
Functional Dependencies: teacher_id → teacher_name, specialization, course_id
Teachers
---------------------------------------------------------
| teacher_id | teacher_name | specialization | course_id |
| 101 | John Doe | Mathematics | 1 |
| 102 | Jane Smith | Physics |2 |
| 103 | Alice Brown | Literature | 3 |
Teachers table is in 1NF as it has atomic values, unique column names, no repeating groups, and unordered rows.
CONVERSION TO 2NF :
We'll create two tables: one for teachers and another for courses. The courses table will include the course_id and
course_name to remove the partial dependency.
Teachers
Functional Dependencies: teacher_id → teacher_name, specialization
---------------------------------------------------
| teacher_id | teacher_name | specialization |
| 101 | John Doe | Mathematics |
| 102 | Jane Smith | Physics |
| 103 | Alice Brown | Literature |
Courses
59
Functional Dependencies: course_id → course_name
-------------------
| course_id | course_name |
|1 | Math |
|2 | Physics |
|3 | Literature |
The Courses table includes the course_id and course_name, removing the partial dependency and ensuring each
attribute is fully dependent on the primary key.
Each table represents a single entity, meeting the requirements of the second normal form (2NF).
CONVERSION TO 3NF :
To remove the transitive dependency, we need to create a separate table for specialization.
Teachers
Functional Dependencies: teacher_id → teacher_name
---------------------------------------------------
| teacher_id | teacher_name | specialization_id |
| 101 | John Doe | 1 |
| 102 | Jane Smith | 2 |
| 103 | Alice Brown | 3 |
Specializations
PITFALLS: Pitfalls include increased join complexity and potential for data inconsistency due to dependency on
external tables, which may impact query performance and maintenance.
3. COURSES TABLE :
3NF
Courses
60
CONVERSION TO 4NF :
To add multi-valued dependencies to the Courses table in the third normal form (3NF), we can introduce another table
to represent the relationship between courses and their prerequisites.
Course_Prerequisites
Now, both tables are in the fourth normal form (4NF). Each table's attributes are fully functionally dependent on the
primary key, and there are no multi-valued dependencies present.
PITFALLS: Pitfalls include increased join complexity and potential data redundancy, as
well as the possibility of introducing NULL values for prerequisites, which could impact
query efficiency and data integrity.
4. PAYMENT TABLE :
4NF
Payment
62
CHAPTER – 5
BY LOCKS
LOCK TABLE employeez IN EXCLUSIVE MODE;
LOCK TABLE parents IN EXCLUSIVE MODE;
LOCK TABLE payment IN EXCLUSIVE MODE;
COMMIT;
63
Here we apply locks to the employeez , parents and payment table so when trying to update values in
employee table it shows 0 rows updated which shows that the lock command is working and commit is
complete.
TRANSACTION LOG
COMMIT;
The SQL script updates the salary of the employee with ID '234' by doubling the current salary in the
'EMPLOYEEZ' table, and it logs this update operation in the 'transaction_log' table with details of the
old and new salary values before committing the transaction .Here we can also see that 1 row
inserted showing the transaction_log is working and commit is complete.
ROLLBACK
savepoint checkpoint;
64
INSERT INTO transaction_log (transaction_id, operation_type, table_name, old_value, new_value)
VALUES ('txn_005', 'UPDATE', 'EMPLOYEEZ', 'SALARY=30000', 'SALARY=');
rollback to checkpoint;
The "rollback to checkpoint" command undoes changes made after the savepoint, effectively
reverting the database to its state at the savepoint.
65
CHAPTER-6
6.1 CODE FOR PROJECT
Server.js
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql2');
// Connect to MySQL
connection.connect((err) => {
if (err) throw err;
console.log('Connected to MySQL database');
});
// Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
// Routes
app.get('/api/buildings', (req, res) => {
connection.query('SELECT * FROM buildings', (err, rows) => {
if (err) throw err;
res.json(rows);
});
});
// Delete a washroom
app.delete('/api/washrooms/:washroomType', (req, res) => {
const washroomType = req.params.washroomType;
const query = `DELETE FROM washrooms WHERE WASHROOMTYPE = '${washroomType}'`;
connection.query(query, (err, result) => {
if (err) throw err;
res.send('Washroom deleted successfully');
});
});
// Retrieve all classrooms
app.get('/api/classrooms', (req, res) => {
connection.query('SELECT * FROM classrooms', (err, rows) => {
if (err) throw err;
res.json(rows);
});
});
// Delete a classroom
app.delete('/api/classrooms/:roomNo', (req, res) => {
const roomNo = req.params.roomNo;
const query = `DELETE FROM classrooms WHERE ROOMNO = '${roomNo}'`;
connection.query(query, (err, result) => {
if (err) throw err;
res.send('Classroom deleted successfully');
});
});
68
Buildings.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manage Buildings</title>
<link rel="stylesheet" href="styles.css">
</head>
<body style="background-image:
url('https://media.istockphoto.com/id/1418427011/vector/seamless-back-to-school-
education-background-pattern.jpg?s=612x612&w=0&k=20&c=egoX1-
oWx8INpLOFQ9J3ypt1pZSq3vGf4eaoiJpv9bQ='); /* Replace 'school-background.jpg' with
your image file */
">
<body>
<h1>Manage Buildings</h1>
<table id="buildingTable">
<thead>
<tr>
<th>Building Name</th>
<th>Building Number</th>
<th>Floors</th>
<th>Location</th>
<th>Action</th>
</tr>
</thead>
<tbody></tbody>
</table>
<form id="buildingForm">
<input type="text" name="BUILDINGNAME" placeholder="Building Name" required>
<input type="number" name="BUILDINGNO" placeholder="Building Number" required>
<input type="number" name="FLOORS" placeholder="Floors" required>
<input type="text" name="LOCATION" placeholder="Location" required>
<button type="submit">Add Building</button>
</form>
<script>
document.addEventListener('DOMContentLoaded', () => {
// Function to fetch and display buildings
function fetchBuildings() {
fetch('/api/buildings')
69
.then(response => response.json())
.then(buildings => {
const buildingTableBody = document.querySelector('#buildingTable
tbody');
buildingTableBody.innerHTML = ''; // Clear existing table rows
buildings.forEach(building => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${building.BUILDINGNAME}</td>
<td>${building.BUILDINGNO}</td>
<td>${building.FLOORS}</td>
<td>${building.LOCATION}</td>
<td><button onclick="deleteBuilding('$
{building.BUILDINGNAME}')">Delete</button></td>
`;
buildingTableBody.appendChild(row);
});
});
}
71
CHAPTER-7
7.1 Result and Discussion (Screen shots of the implementation with front end).
DISPLAY PAGE:
MANAGE BUILDINGS:
72
MANA
GE CLASSROOMS:
MANAGE PAYMENTS:
73
MANAGE WASHROOMS:
74
10.CONCLUSION
75
10. ONLINE COURSE CERTIFICATE
76
77