Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
3 views29 pages

Adbms Assignment 4

Uploaded by

khushibshah7
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views29 pages

Adbms Assignment 4

Uploaded by

khushibshah7
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 29

ADBMS ASSIGNMENT

J032

#Q1)
PROCEDURES :

1. Enroll New Student


Write a procedure that inserts a new student into the student table,
assigning them to a department and setting default GPA to 2.5.

SOLUTION:

CREATE OR REPLACE PROCEDURE enroll_new_student (


p_student_id IN NUMBER,
p_name IN VARCHAR2,
p_department_id IN NUMBER
)
IS
BEGIN
INSERT INTO student (
student_id,
name,
department_id,
gpa,
enrollment_date
)
VALUES (
p_student_id,
p_name,
p_department_id,
2.5,
SYSDATE
);

DBMS_OUTPUT.PUT_LINE('Student enrolled
successfully.');
END;

#TRY

BEGIN
enroll_new_student(105, 'Alice Smith', 2);
END;
2) Update Department Budget
A procedure to update the budget of a given department based on an increase
percentage.

SOLUTION:

CREATE OR REPLACE PROCEDURE update_department_budget (


p_department_id IN NUMBER,
p_increase_percent IN NUMBER
)
IS
BEGIN
UPDATE department
SET budget = budget + (budget * p_increase_percent / 100)
WHERE department_id = p_department_id;

DBMS_OUTPUT.PUT_LINE('Budget updated successfully.');


END;

#TRY

BEGIN
update_department_budget(2, 10); -- Increase budget of department 2 by
10%
END;
3)
Record Fine Payment
Write a procedure that updates the library table to mark a book as returned,
set the fine to 0, and log the return date.

SOLUTION:

CREATE OR REPLACE PROCEDURE record_fine_payment (


p_library_id IN NUMBER
)
IS
BEGIN
UPDATE library
SET
is_returned = 'Yes',
fine_amount = 0,
return_date = SYSDATE
WHERE library_id = p_library_id;

DBMS_OUTPUT.PUT_LINE('Book return recorded and fine cleared.');


END;

#try

BEGIN
record_fine_payment(201); -- Marks book as
returned for library_id 201
END;
#4)
Generate Department Report
Create a procedure to print or insert into a log table the number of students
and average GPA per department

Solution:
CREATE OR REPLACE PROCEDURE
generate_department_report
IS
CURSOR dept_cursor IS
SELECT d.department_id, d.department_name,
COUNT(s.student_id) AS student_count,
ROUND(AVG(s.gpa), 2) AS avg_gpa
FROM department d
LEFT JOIN student s ON d.department_id =
s.department_id
GROUP BY d.department_id, d.department_name;
v_dept_id department.department_id%TYPE;
v_dept_name department.department_name%TYPE;
v_student_count NUMBER;
v_avg_gpa NUMBER;
BEGIN
OPEN dept_cursor;
LOOP
FETCH dept_cursor INTO v_dept_id, v_dept_name,
v_student_count, v_avg_gpa;
EXIT WHEN dept_cursor%NOTFOUND;

DBMS_OUTPUT.PUT_LINE('Department: ' ||
v_dept_name ||
' | Students: ' || v_student_count ||
' | Avg GPA: ' || NVL(v_avg_gpa, 0));
END LOOP;
CLOSE dept_cursor;
END;

#try
BEGIN
generate_department_report;
END;
#5)
Clear Graduated Students
A procedure to delete students whose enrollment_date is more than 4 years
ago and have GPA above 3.0.

Solution:
CREATE OR REPLACE PROCEDURE
clear_graduated_students
IS
BEGIN
DELETE FROM student
WHERE enrollment_date < ADD_MONTHS(SYSDATE, -
48) -- 4 years = 48 months
AND gpa > 3.0;

DBMS_OUTPUT.PUT_LINE('Graduated students
cleared successfully.');
END;

#try

BEGIN
clear_graduated_students;
END;

FUNCTIONS
1)Calculate Outstanding Balance
Function that takes student_id and returns their total amount_due from the
finance table.

SOLUTION:

CREATE OR REPLACE FUNCTION


calculate_outstanding_balance (
p_student_id IN NUMBER
) RETURN NUMBER
IS
v_total_due NUMBER := 0;
BEGIN
SELECT NVL(SUM(amount_due), 0)
INTO v_total_due
FROM finance
WHERE student_id = p_student_id;

RETURN v_total_due;
END;

#TRY

DECLARE
v_balance NUMBER;
BEGIN
v_balance := calculate_outstanding_balance(101);
DBMS_OUTPUT.PUT_LINE('Outstanding Balance: ' ||
v_balance);
END;

2)
Get Department Name by Student ID
Function that returns the department name for a given student.

SOLUTION:

CREATE OR REPLACE FUNCTION get_department_name (


p_student_id IN NUMBER
) RETURN VARCHAR2
IS
v_department_name VARCHAR2(100);
BEGIN
SELECT d.department_name
INTO v_department_name
FROM student s
JOIN department d ON s.department_id = d.department_id
WHERE s.student_id = p_student_id;

RETURN v_department_name;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 'No Department Found';
WHEN OTHERS THEN
RETURN 'Error';
END;

#TRY

DECLARE
v_dept_name VARCHAR2(100);
BEGIN
v_dept_name := get_department_name(101);
DBMS_OUTPUT.PUT_LINE('Department: ' ||
v_dept_name);
END;

3)
Student Full Status
Return a string summary: 'Name (GPA), Department, Outstanding Due' given a
student_id.

SOLUTION:

CREATE OR REPLACE FUNCTION get_student_full_status (


p_student_id IN NUMBER
) RETURN VARCHAR2
IS
v_name student.name%TYPE;
v_gpa student.gpa%TYPE;
v_department_name department.department_name
%TYPE;
v_due NUMBER := 0;
v_status VARCHAR2(300);
BEGIN
-- Get student name, GPA, department_id
SELECT s.name, s.gpa, d.department_name
INTO v_name, v_gpa, v_department_name
FROM student s
JOIN department d ON s.department_id = d.department_id
WHERE s.student_id = p_student_id;

-- Calculate total outstanding due


SELECT NVL(SUM(amount_due), 0)
INTO v_due
FROM finance
WHERE student_id = p_student_id;

-- Combine into status string


v_status := v_name || ' (' || v_gpa || '), ' ||
v_department_name || ', Outstanding Due: ' || v_due;

RETURN v_status;

EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 'Student not found';
WHEN OTHERS THEN
RETURN 'Error occurred';
END;
/

#TRY

DECLARE
v_status VARCHAR2(300);
BEGIN
v_status := get_student_full_status(101);
DBMS_OUTPUT.PUT_LINE(v_status);
END;
/

#4)

Library Book Return Delay


Function that calculates the number of days late for a returned book.

SOLUTION:

CREATE OR REPLACE FUNCTION get_book_return_delay (


p_library_id IN NUMBER
) RETURN NUMBER
IS
v_issue_date DATE;
v_return_date DATE;
v_due_date DATE;
v_days_late NUMBER;
BEGIN
-- Get issue and return dates
SELECT issue_date, return_date
INTO v_issue_date, v_return_date
FROM library
WHERE library_id = p_library_id;

-- Calculate due date (14 days after issue)


v_due_date := v_issue_date + 14;

-- Calculate days late (if any)


v_days_late := v_return_date - v_due_date;

IF v_days_late < 0 THEN


v_days_late := 0; -- Not late
END IF;

RETURN v_days_late;

EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN -1; -- Book record not found
WHEN OTHERS THEN
RETURN -2; -- Error occurred
END;
/

#TRY
DECLARE
v_late_days NUMBER;
BEGIN
v_late_days := get_book_return_delay(201);
DBMS_OUTPUT.PUT_LINE('Days Late: ' || v_late_days);
END;
/

#5)
Scholarship Eligibility
Function that returns TRUE if GPA is above 3.5 and amount_due is 0.

SOLUTION:

CREATE OR REPLACE FUNCTION is_scholarship_eligible (


p_student_id IN NUMBER
) RETURN BOOLEAN
IS
v_gpa NUMBER;
v_due NUMBER;
BEGIN
-- Get GPA of the student
SELECT gpa
INTO v_gpa
FROM student
WHERE student_id = p_student_id;

-- Get total outstanding amount


SELECT NVL(SUM(amount_due), 0)
INTO v_due
FROM finance
WHERE student_id = p_student_id;

-- Check eligibility
IF v_gpa > 3.5 AND v_due = 0 THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;

EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN FALSE; -- Student not found or no finance record
WHEN OTHERS THEN
RETURN FALSE; -- On error, return false
END;
/

#TRY
DECLARE
eligible BOOLEAN;
BEGIN
eligible := is_scholarship_eligible(101);

IF eligible THEN
DBMS_OUTPUT.PUT_LINE('Eligible for Scholarship');
ELSE
DBMS_OUTPUT.PUT_LINE('Not Eligible');
END IF;
END;
/

TRIGGERS

1) Log Department Budget Changes


Trigger that logs before and after values of budget into an audit table on
update.

CREATE TABLE department_budget_audit (


audit_id NUMBER GENERATED ALWAYS AS IDENTITY,
department_id NUMBER,
old_budget NUMBER,
new_budget NUMBER,
changed_on DATE DEFAULT SYSDATE
);

CREATE OR REPLACE TRIGGER log_budget_change


BEFORE UPDATE OF budget ON department
FOR EACH ROW
BEGIN
INSERT INTO department_budget_audit (
department_id, old_budget, new_budget
) VALUES (
:OLD.department_id, :OLD.budget, :NEW.budget
);
END;
/

2)
Prevent Duplicate Emails
BEFORE INSERT trigger on student to prevent duplicate emails.

SOLUTION:
CREATE OR REPLACE TRIGGER
prevent_duplicate_emails
BEFORE INSERT ON student
FOR EACH ROW
DECLARE
v_count NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count
FROM student
WHERE email = :NEW.email;

IF v_count > 0 THEN


RAISE_APPLICATION_ERROR(-20001, 'Email already
exists. Duplicate not allowed.');
END IF;
END;
/

3)
Auto Fine on Late Return
AFTER UPDATE trigger on library.return_date that calculates fine if return_date
> due_date.

SOLUTION:

CREATE OR REPLACE TRIGGER


auto_fine_on_late_return
AFTER UPDATE OF return_date ON library
FOR EACH ROW
DECLARE
v_due_date DATE;
v_days_late NUMBER;
v_fine NUMBER;
BEGIN
-- Calculate due date as issue_date + 14 days
v_due_date := :OLD.issue_date + 14;

-- Calculate days late


v_days_late := :NEW.return_date - v_due_date;

IF v_days_late > 0 THEN


v_fine := v_days_late * 2; -- $2 per day fine
UPDATE library
SET fine_amount = v_fine
WHERE library_id = :NEW.library_id;
ELSE
UPDATE library
SET fine_amount = 0
WHERE library_id = :NEW.library_id;
END IF;
END;
/

#4)

Track High Payments


AFTER INSERT trigger on finance that logs transactions over $40,000 into a
high_value_payments table.

SOLUTION:

CREATE TABLE high_value_payments (


payment_id NUMBER GENERATED ALWAYS AS
IDENTITY,
student_id NUMBER,
amount_due NUMBER,
logged_on DATE DEFAULT SYSDATE
);
CREATE OR REPLACE TRIGGER track_high_payments
AFTER INSERT ON finance
FOR EACH ROW
BEGIN
IF :NEW.amount_due > 40000 THEN
INSERT INTO high_value_payments (
student_id, amount_due
) VALUES (
:NEW.student_id, :NEW.amount_due
);
END IF;
END;
/

5)

Restrict GPA Entry


BEFORE INSERT or UPDATE on student.gpa to ensure it's between 0.0 and 4.0.

SOLUTION:

CREATE OR REPLACE TRIGGER restrict_gpa_range


BEFORE INSERT OR UPDATE OF gpa ON student
FOR EACH ROW
BEGIN
IF :NEW.gpa < 0.0 OR :NEW.gpa > 4.0 THEN
RAISE_APPLICATION_ERROR(-20002, 'GPA must be
between 0.0 and 4.0');
END IF;
END;
/

CURSORS

1) List Students per Department


Cursor that iterates through departments and prints student names
enrolled in each.

SOLUTION:

DECLARE
-- Cursor for all departments
CURSOR dept_cursor IS
SELECT department_id, department_name
FROM department;

-- Variables to hold department info


v_dept_id department.department_id%TYPE;
v_dept_name department.department_name%TYPE;

-- Cursor for students in a department


CURSOR student_cursor(p_dept_id NUMBER) IS
SELECT name
FROM student
WHERE department_id = p_dept_id;

v_student_name student.name%TYPE;
BEGIN
OPEN dept_cursor;
LOOP
FETCH dept_cursor INTO v_dept_id, v_dept_name;
EXIT WHEN dept_cursor%NOTFOUND;

DBMS_OUTPUT.PUT_LINE('Department: ' || v_dept_name);

-- Open inner cursor for students


OPEN student_cursor(v_dept_id);
LOOP
FETCH student_cursor INTO v_student_name;
EXIT WHEN student_cursor%NOTFOUND;

DBMS_OUTPUT.PUT_LINE(' - ' || v_student_name);


END LOOP;
CLOSE student_cursor;

DBMS_OUTPUT.PUT_LINE('-----------------------------');
END LOOP;
CLOSE dept_cursor;
END;
/

2)
Outstanding Library Fines
Cursor that scans library and lists all students with unpaid fines over $100.

SOLUTION:

DECLARE
-- Cursor to find students with fines > $100
CURSOR fine_cursor IS
SELECT l.student_id, s.name, l.fine_amount
FROM library l
JOIN student s ON l.student_id = s.student_id
WHERE l.fine_amount > 100;

-- Variables to hold data


v_student_id library.student_id%TYPE;
v_name student.name%TYPE;
v_fine library.fine_amount%TYPE;
BEGIN
OPEN fine_cursor;
LOOP
FETCH fine_cursor INTO v_student_id, v_name, v_fine;
EXIT WHEN fine_cursor%NOTFOUND;

DBMS_OUTPUT.PUT_LINE('Student: ' || v_name ||


' | ID: ' || v_student_id ||
' | Fine: $' || v_fine);
END LOOP;
CLOSE fine_cursor;
END;
/

3)
Finance Summary Cursor
Loop through each student and show total amount_paid and amount_due.

SOLUTION:

DECLARE
-- Cursor to get total paid and due for each student
CURSOR finance_cursor IS
SELECT f.student_id, s.name,
NVL(SUM(f.amount_paid), 0) AS total_paid,
NVL(SUM(f.amount_due), 0) AS total_due
FROM finance f
JOIN student s ON f.student_id = s.student_id
GROUP BY f.student_id, s.name;

-- Variables to hold data


v_student_id finance.student_id%TYPE;
v_name student.name%TYPE;
v_total_paid NUMBER;
v_total_due NUMBER;
BEGIN
OPEN finance_cursor;
LOOP
FETCH finance_cursor INTO v_student_id, v_name, v_total_paid,
v_total_due;
EXIT WHEN finance_cursor%NOTFOUND;

DBMS_OUTPUT.PUT_LINE('Student: ' || v_name ||


' | ID: ' || v_student_id ||
' | Paid: $' || v_total_paid ||
' | Due: $' || v_total_due);
END LOOP;
CLOSE finance_cursor;
END;
/

4)

Overdue Books Notification


Cursor to fetch books not returned and issue notifications (simulate by
DBMS_OUTPUT).
DECLARE
-- Cursor to find overdue books
CURSOR overdue_cursor IS
SELECT l.library_id, l.student_id, s.name, l.book_title, l.issue_date
FROM library l
JOIN student s ON l.student_id = s.student_id
WHERE l.is_returned = 'No'
AND l.issue_date + 14 < SYSDATE; -- Overdue

-- Variables to hold data


v_library_id library.library_id%TYPE;
v_student_id library.student_id%TYPE;
v_name student.name%TYPE;
v_book_title library.book_title%TYPE;
v_issue_date DATE;
v_due_date DATE;
BEGIN
OPEN overdue_cursor;
LOOP
FETCH overdue_cursor INTO v_library_id, v_student_id, v_name,
v_book_title, v_issue_date;
EXIT WHEN overdue_cursor%NOTFOUND;

-- Calculate due date


v_due_date := v_issue_date + 14;

-- Simulate notification
DBMS_OUTPUT.PUT_LINE(' Overdue Notification: ' || v_name ||
' (ID: ' || v_student_id || ') has not returned "' ||
v_book_title || '". Due on ' || TO_CHAR(v_due_date, 'DD-
MON-YYYY'));
END LOOP;
CLOSE overdue_cursor;
END;
/
5)

Average GPA by Department


Use a cursor to compute and display the average GPA per department.

SOLUTION:

DECLARE
-- Cursor to iterate departments
CURSOR dept_cursor IS
SELECT department_id, department_name
FROM department;

-- Variables to hold department data


v_dept_id department.department_id%TYPE;
v_dept_name department.department_name%TYPE;
v_avg_gpa NUMBER;
BEGIN
OPEN dept_cursor;
LOOP
FETCH dept_cursor INTO v_dept_id, v_dept_name;
EXIT WHEN dept_cursor%NOTFOUND;

-- Compute average GPA for current department


SELECT ROUND(NVL(AVG(gpa), 0), 2)
INTO v_avg_gpa
FROM student
WHERE department_id = v_dept_id;

-- Output the result


DBMS_OUTPUT.PUT_LINE('Department: ' || v_dept_name ||
' | Average GPA: ' || v_avg_gpa);
END LOOP;
CLOSE dept_cursor;
END;
/

You might also like