Saturday, January 24, 2026

SYBCS-DBMS-II-Triggers

 Assignment 5: Triggers.


SET A

Movie – Actor Database

Consider the following database

Movie (m_name varchar (25), release_year integer, budget money)

Actor (a_name varchar(30), role varchar(30), charges money, a_address varchar(30) ) Movie

and Actor are related with many to many relationship.

Create the above database in PostGreSQL and insert sufficient records.

a. Write a trigger which will be executed whenever an actor is deleted from the actor table, display

appropriate message.

b. Write a trigger which will be executed whenever a movie is deleted from the movie table, display

appropriate message.

c. Write a trigger which will be executed whenever insertion is made to the movie table. If the

budget is less than 1,00,000 do not allow the insertion. Give appropriate message.

-- Movie Table

CREATE TABLE Movie (

m_name VARCHAR(25) PRIMARY KEY,

release_year INT,

budget MONEY

);

-- Actor Table

CREATE TABLE Actor (

a_name VARCHAR(30) PRIMARY KEY,

role VARCHAR(30),

charges MONEY,

a_address VARCHAR(30)

);

-- Junction Table for Many-to-Many Relationship

CREATE TABLE Movie_Actor (

m_name VARCHAR(25),

a_name VARCHAR(30),

PRIMARY KEY (m_name, a_name),

FOREIGN KEY (m_name) REFERENCES Movie(m_name),

FOREIGN KEY (a_name) REFERENCES Actor(a_name)

);

2. Insert Sample Records

sql

-- Insert into Movie

INSERT INTO Movie VALUES

('Inception', 2010, 160000000),

('Titanic', 1997, 200000000),

('The Matrix', 1999, 63000000);

-- Insert into Actor

INSERT INTO Actor VALUES

('Leonardo DiCaprio', 'Lead', 20000000, 'LA'),

('Kate Winslet', 'Lead', 15000000, 'UK'),

('Keanu Reeves', 'Lead', 10000000, 'Canada');

-- Insert into Movie_Actor

INSERT INTO Movie_Actor VALUES

('Inception', 'Leonardo DiCaprio'),

('Titanic', 'Leonardo DiCaprio'),

('Titanic', 'Kate Winslet'),

('The Matrix', 'Keanu Reeves');

3. Triggers

a) Trigger on Actor deletion Display message whenever an actor is deleted

sql

-- Function for Actor deletion

CREATE OR REPLACE FUNCTION actor_delete_msg()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

RAISE NOTICE 'Actor "%" is deleted from Actor table', OLD.a_name;

RETURN OLD;

END;

$$;

-- Trigger on DELETE

CREATE TRIGGER trg_actor_delete

AFTER DELETE ON Actor

FOR EACH ROW

EXECUTE FUNCTION actor_delete_msg();

Test

sql

DELETE FROM Actor WHERE a_name = 'Keanu Reeves';

-- NOTICE: Actor "Keanu Reeves" is deleted from Actor table

b) Trigger on Movie deletion Display message whenever a movie is deleted

sql

-- Function for Movie deletion

CREATE OR REPLACE FUNCTION movie_delete_msg()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

RAISE NOTICE 'Movie "%" is deleted from Movie table', OLD.m_name;

RETURN OLD;

END;

$$;

-- Trigger on DELETE

CREATE TRIGGER trg_movie_delete

AFTER DELETE ON Movie

FOR EACH ROW

EXECUTE FUNCTION movie_delete_msg();

Test

sql

DELETE FROM Movie WHERE m_name = 'Titanic';

-- NOTICE: Movie "Titanic" is deleted from Movie table

c) Trigger on Movie insertion to check budget Prevent insertion if budget < 100,000

sql

-- Function for Movie insertion

CREATE OR REPLACE FUNCTION check_movie_budget()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$


BEGIN

IF NEW.budget < 100000 THEN

RAISE EXCEPTION 'Insertion not allowed. Budget less than 1,00,000: %', NEW.budget;

END IF;

RETURN NEW;

END;

$$;

-- Trigger on INSERT

CREATE TRIGGER trg_movie_insert

BEFORE INSERT ON Movie

FOR EACH ROW

EXECUTE FUNCTION check_movie_budget();

Test

sql

-- Valid insertion

INSERT INTO Movie VALUES ('Avatar', 2009, 237000000); -- Works fine

-- Invalid insertion

INSERT INTO Movie VALUES ('LowBudgetMovie', 2026, 50000);

-- ERROR: Insertion not allowed. Budget less than 1,00,000: 50000


SET B

Doctor – Hospital Database

Consider the following database

Doctor (d_no int, d_name varchar(30), specialization varchar(35), charges int)

Hospital (h_no int, h_name varchar(20), city varchar(10))

Doctor and Hospital are related with many to one relationship.

Create the above database in PostGreSQL and insert sufficient records.

a. Write a trigger before insert/update on Doctor table. Raise exception if charges are <0.

b. Write a trigger that restricts insertion of charges value greater than 400.

-- Create Hospital table

CREATE TABLE Hospital (

h_no int PRIMARY KEY,

h_name varchar(20),

city varchar(10)

);

-- Create Doctor table (Many-to-One: Many doctors belong to one hospital)

CREATE TABLE Doctor (

d_no int PRIMARY KEY,

d_name varchar(30),

specialization varchar(35),

charges int,

h_no int REFERENCES Hospital(h_no)

);


-- Insert sample records

INSERT INTO Hospital VALUES (1, 'City Care', 'Mumbai'), (2, 'Life Line', 'Pune');

INSERT INTO Doctor VALUES (101, 'Dr. Sharma', 'Cardiology', 500, 1);

CREATE OR REPLACE FUNCTION validate_doctor_charges()

RETURNS TRIGGER AS $$

BEGIN

-- a. Check if charges are less than 0

IF NEW.charges < 0 THEN

RAISE EXCEPTION 'Invalid Charges: Charges cannot be negative.';

END IF;

-- b. Restrict insertion of charges greater than 400

IF NEW.charges > 400 THEN

RAISE EXCEPTION 'Invalid Charges: Charges cannot exceed 400.';

END IF;

RETURN NEW;

END;

$$ LANGUAGE plpgsql;

Create the Trigger

CREATE TRIGGER trg_check_charges

BEFORE INSERT OR UPDATE ON Doctor

FOR EACH ROW

EXECUTE FUNCTION validate_doctor_charges();

SET C

Student – Subject database

Consider the following database :

Student (rollno integer, name varchar(30),city varchar(50),class varchar(10))

Subject(Scode varchar(10),subject name varchar(20))

Student and subject are related with M-M relationship with attributes marks_scored.

Create the above database in PostGreSQL and insert sufficient records

a. Write a trigger before insert/update the marks_scored. Raise exception if Marks are negative.

b. Write a trigger which is executed when insertion is made in the student-subject table. If

marks_scored is less than 0, give appropriate message and do not allow the insertion.

c. Write a trigger which will prevent deleting students from ‘Mumbai’ city.

-- Student Table

CREATE TABLE Student (

rollno INT PRIMARY KEY,

name VARCHAR(30),

city VARCHAR(50),

class VARCHAR(10)

);


-- Subject Table

CREATE TABLE Subject (

scode VARCHAR(10) PRIMARY KEY,

subject_name VARCHAR(20)

);

-- Student_Subject Table (junction table with marks_scored)

CREATE TABLE Student_Subject (

rollno INT,

scode VARCHAR(10),

marks_scored INT,

PRIMARY KEY (rollno, scode),

FOREIGN KEY (rollno) REFERENCES Student(rollno),

FOREIGN KEY (scode) REFERENCES Subject(scode)

);

2. Insert Sample Records

sql

-- Insert into Student

INSERT INTO Student VALUES

(1, 'Amit', 'Mumbai', 'BScCS'),

(2, 'Sneha', 'Pune', 'BScIT'),

(3, 'Rahul', 'Mumbai', 'BCA');

-- Insert into Subject

INSERT INTO Subject VALUES

('S101', 'DBMS'),

('S102', 'AI'),

('S103', 'OS');

-- Insert into Student_Subject

INSERT INTO Student_Subject VALUES

(1, 'S101', 85),

(1, 'S102', 90),

(2, 'S101', 70),

(3, 'S103', 60);

3. Triggers

a) Trigger BEFORE INSERT/UPDATE on marks_scored Raise exception if marks are negative

sql

-- Function to check marks before insert/update

CREATE OR REPLACE FUNCTION check_marks_before_insert_update()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

IF NEW.marks_scored < 0 THEN

RAISE EXCEPTION 'Marks cannot be negative: %', NEW.marks_scored;


END IF;

RETURN NEW;

END;

$$;

-- Trigger BEFORE INSERT

CREATE TRIGGER trg_marks_before_insert

BEFORE INSERT ON Student_Subject

FOR EACH ROW

EXECUTE FUNCTION check_marks_before_insert_update();

-- Trigger BEFORE UPDATE

CREATE TRIGGER trg_marks_before_update

BEFORE UPDATE ON Student_Subject

FOR EACH ROW

EXECUTE FUNCTION check_marks_before_insert_update();

Test


INSERT INTO Student_Subject VALUES (2, 'S102', -10);

-- ERROR: Marks cannot be negative: -10

b) Trigger on INSERT in Student_Subject to prevent negative marks Display message and prevent insertion

sql

-- Function to prevent negative marks on insert

CREATE OR REPLACE FUNCTION prevent_negative_marks_insert()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

IF NEW.marks_scored < 0 THEN

RAISE EXCEPTION 'Insertion not allowed: Marks are negative (%).', NEW.marks_scored;

END IF;

RETURN NEW;

END;

$$;

-- Trigger BEFORE INSERT

CREATE TRIGGER trg_prevent_negative_marks

BEFORE INSERT ON Student_Subject

FOR EACH ROW

EXECUTE FUNCTION prevent_negative_marks_insert();

Test

sql

INSERT INTO Student_Subject VALUES (3, 'S102', -5);

-- ERROR: Insertion not allowed: Marks are negative (-5).

✅ Note: This trigger complements the previous one; ensures marks validation during insert.


c) Trigger to prevent deleting students from 'Mumbai'

sql

-- Function to prevent deletion of Mumbai students

CREATE OR REPLACE FUNCTION prevent_mumbai_student_delete()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

IF OLD.city = 'Mumbai' THEN

RAISE EXCEPTION 'Cannot delete student from Mumbai: %', OLD.name;

END IF;

RETURN OLD;

END;

$$;

-- Trigger BEFORE DELETE

CREATE TRIGGER trg_prevent_mumbai_delete

BEFORE DELETE ON Student

FOR EACH ROW

EXECUTE FUNCTION prevent_mumbai_student_delete();

Test

sql

DELETE FROM Student WHERE rollno = 1;

-- ERROR: Cannot delete student from Mumbai: Amit

DELETE FROM Student WHERE rollno = 2;

-- Works fine (Sneha is from Pune)


SET D

Customer – Account database

Consider the following database

Customer (cno integer, cname varchar(20), city varchar(20))

Account (a_no int, a_type varchar(10), opening_date date, balance money) Customer

and Account are related with one to many relationship

Create the above database in PostGreSQL and insert sufficient records.

a. Write a trigger which is executed whenever update is made to the account table. If the balance

becomes less than 1000, print an error message that balance cannot be less than 1000.

b. Write a trigger before deleting an account record from Account table. Raise a notice and display

the message “Account record is being deleted.”

c. Write a trigger before inserting an account record in Account table and raise exception if

balance is <500.

-- Customer Table

CREATE TABLE Customer (

cno INT PRIMARY KEY,

cname VARCHAR(20),

city VARCHAR(20)

);


-- Account Table

CREATE TABLE Account (

a_no INT PRIMARY KEY,

cno INT REFERENCES Customer(cno),

a_type VARCHAR(10),

opening_date DATE,

balance MONEY

);

2. Insert Sample Records

-- Insert into Customer

INSERT INTO Customer VALUES

(1, 'Amit', 'Mumbai'),

(2, 'Sneha', 'Pune'),

(3, 'Rahul', 'Delhi');

-- Insert into Account

INSERT INTO Account VALUES

(101, 1, 'Savings', '2022-01-10', 5000),

(102, 2, 'Current', '2022-05-15', 1500),

(103, 3, 'Savings', '2022-03-20', 2000);

3. Triggers

a) Trigger on UPDATE of Account balance Raise exception if balance < 1000

sql

-- Function for balance check on update

CREATE OR REPLACE FUNCTION check_balance_update()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

IF NEW.balance < 1000 THEN

RAISE EXCEPTION 'Balance cannot be less than 1000. Current balance: %', NEW.balance;

END IF;

RETURN NEW;

END;

$$;

-- Trigger BEFORE UPDATE

CREATE TRIGGER trg_check_balance_update

BEFORE UPDATE ON Account

FOR EACH ROW

EXECUTE FUNCTION check_balance_update();

Test

sql

UPDATE Account SET balance = 900 WHERE a_no = 101;

-- ERROR: Balance cannot be less than 1000. Current balance: 900

b) Trigger BEFORE DELETE on Account Display notice “Account record is being deleted.”

sql

-- Function for delete notice

CREATE OR REPLACE FUNCTION account_delete_notice()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

RAISE NOTICE 'Account record is being deleted. Account No: %', OLD.a_no;

RETURN OLD;

END;

$$;

-- Trigger BEFORE DELETE

CREATE TRIGGER trg_account_delete_notice

BEFORE DELETE ON Account

FOR EACH ROW

EXECUTE FUNCTION account_delete_notice();

Test

sql

DELETE FROM Account WHERE a_no = 103;

-- NOTICE: Account record is being deleted. Account No: 103

c) Trigger BEFORE INSERT on Account Raise exception if balance < 500

sql

-- Function for insert validation

CREATE OR REPLACE FUNCTION check_balance_insert()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

IF NEW.balance < 500 THEN

RAISE EXCEPTION 'Insertion not allowed. Balance cannot be less than 500. Entered: %',

NEW.balance;

END IF;

RETURN NEW;

END;

$$;

-- Trigger BEFORE INSERT

CREATE TRIGGER trg_check_balance_insert

BEFORE INSERT ON Account

FOR EACH ROW

EXECUTE FUNCTION check_balance_insert();

Test


sql

-- Valid insertion

INSERT INTO Account VALUES (104, 2, 'Savings', '2023-01-01', 2000);

-- Invalid insertion

INSERT INTO Account VALUES (105, 1, 'Current', '2023-01-05', 400);

-- ERROR: Insertion not allowed. Balance cannot be less than 500. Entered: 400


SET E

Project-Employee Database

Consider the following Entities and their Relationships for Project-Employee database.

Project (pno integer, pname char (30), ptype char (20), duration integer)

Employee (eno integer, ename char (20), qualification char (15), joining_date date)

Relationship between Project and Employee is many to many with descriptive

attribute start_date date, no_of_hours_worked integer.

Constraints: Primary Key, pname should not be null.

Create trigger for the following:

a. Write a trigger before inserting into an employee table to check current date should be always

greater than joining date. Display appropriate message.

b. Write a trigger before inserting into a project table to check duration should be always greater

than zero. Display appropriate message.

c. Write a trigger before deleting an employee record from employee table. Raise a notice and

display the message “Employee record is being deleted”.

-- Project Table

CREATE TABLE Project (

pno INT PRIMARY KEY,

pname CHAR(30) NOT NULL,

ptype CHAR(20),

duration INT

);

-- Employee Table

CREATE TABLE Employee (

eno INT PRIMARY KEY,

ename CHAR(20),

qualification CHAR(15),

joining_date DATE

);

-- Junction Table for Many-to-Many Relationship

CREATE TABLE Project_Employee (

pno INT,

eno INT,

start_date DATE,

no_of_hours_worked INT,

PRIMARY KEY (pno, eno),

FOREIGN KEY (pno) REFERENCES Project(pno),


FOREIGN KEY (eno) REFERENCES Employee(eno)

);

2. Insert Sample Records

sql

-- Insert into Project

INSERT INTO Project VALUES

(1, 'ERP System', 'Software', 12),

(2, 'Website Dev', 'Web', 6);

-- Insert into Employee

INSERT INTO Employee VALUES

(101, 'Amit', 'MScCS', '2020-01-10'),

(102, 'Sneha', 'MCA', '2019-07-15');

-- Insert into Project_Employee

INSERT INTO Project_Employee VALUES

(1, 101, '2022-01-01', 120),

(2, 102, '2023-02-01', 80);

3. Triggers

a) Trigger before inserting into Employee Check: joining_date should be less than or equal to

current_date

sql

-- Function for Employee insertion validation

CREATE OR REPLACE FUNCTION check_joining_date()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

IF NEW.joining_date > CURRENT_DATE THEN

RAISE EXCEPTION 'Joining date % cannot be in the future', NEW.joining_date;

ELSE

RAISE NOTICE 'Employee joining date is valid: %', NEW.joining_date;

END IF;

RETURN NEW;

END;

$$;

-- Trigger BEFORE INSERT on Employee

CREATE TRIGGER trg_check_joining_date

BEFORE INSERT ON Employee

FOR EACH ROW

EXECUTE FUNCTION check_joining_date();

Test

sql

INSERT INTO Employee VALUES (103, 'Rahul', 'BScCS', '2027-01-01');

-- ERROR: Joining date 2027-01-01 cannot be in the future


INSERT INTO Employee VALUES (104, 'Neha', 'BCA', '2025-01-15');

-- NOTICE: Employee joining date is valid: 2025-01-15

b) Trigger before inserting into Project Check: duration should be greater than zero

sql

-- Function for Project insertion validation

CREATE OR REPLACE FUNCTION check_project_duration()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

IF NEW.duration <= 0 THEN

RAISE EXCEPTION 'Project duration must be greater than 0. Entered: %', NEW.duration;

ELSE

RAISE NOTICE 'Project duration is valid: %', NEW.duration;

END IF;

RETURN NEW;

END;

$$;

-- Trigger BEFORE INSERT on Project

CREATE TRIGGER trg_check_project_duration

BEFORE INSERT ON Project

FOR EACH ROW

EXECUTE FUNCTION check_project_duration();

Test

sql

INSERT INTO Project VALUES (3, 'AI Research', 'Research', -5);

-- ERROR: Project duration must be greater than 0. Entered: -5

INSERT INTO Project VALUES (3, 'AI Research', 'Research', 18);

-- NOTICE: Project duration is valid: 18

c) Trigger before deleting an Employee record Display notice: “Employee record is being deleted”

sql

-- Function for Employee deletion notice

CREATE OR REPLACE FUNCTION employee_delete_notice()

RETURNS TRIGGER

LANGUAGE plpgsql

AS $$

BEGIN

RAISE NOTICE 'Employee record is being deleted. Employee No: %', OLD.eno;

RETURN OLD;

END;

$$;

-- Trigger BEFORE DELETE on Employee


CREATE TRIGGER trg_employee_delete_notice

BEFORE DELETE ON Employee

FOR EACH ROW

EXECUTE FUNCTION employee_delete_notice();

Test

sql

DELETE FROM Employee WHERE eno = 102;

-- NOTICE: Employee record is being deleted. Employee No: 102

SYBCS-DBMS-II-Error Handling

 Assignment 4: Handling errors and Exceptions


SET A

Project-Employee database

Consider the following database:

Project (pno int, pname char (30), ptype char (20), duration int)

Employee (empno int, ename char (20), joining_date date)

The relationship between Project and Employee is many to many with descriptive attribute

start_date.

Create the above database in PostGreSQL and insert sufficient records.

a. Write a stored function to accept project name as input and print the names of employees

working on the project. Also print the total number of employees working on that project.

Raise an exception for an invalid project name.

b. Write a stored function to accept empno as an input parameter from the user and count the

number of projects of a given employee. Raise an exception if the employee number is invalid.


1. Database Creation (PostgreSQL)

Since Project and Employee have a many-to-many relationship with descriptive attribute

start_date, a relationship table is required.

-- Project Table

CREATE TABLE Project (

pno INT PRIMARY KEY,

pname CHAR(30),

ptype CHAR(20),

duration INT

);

-- Employee Table

CREATE TABLE Employee (

empno INT PRIMARY KEY,

ename CHAR(20),

joining_date DATE

);

-- Relationship Table with descriptive attribute

CREATE TABLE Project_Employee (


pno INT,

empno INT,

start_date DATE,

PRIMARY KEY (pno, empno),

FOREIGN KEY (pno) REFERENCES Project(pno),

FOREIGN KEY (empno) REFERENCES Employee(empno)

);


2. Insert Sufficient Records

-- Insert into Project

INSERT INTO Project VALUES

(1, 'ERP System', 'Software', 12),

(2, 'Website Dev', 'Web', 6),

(3, 'AI Research', 'Research', 18);

-- Insert into Employee

INSERT INTO Employee VALUES

(101, 'Amit', '2020-01-10'),

(102, 'Sneha', '2019-07-15'),

(103, 'Rahul', '2021-03-20'),

(104, 'Neha', '2022-06-01');

-- Insert into Project_Employee

INSERT INTO Project_Employee VALUES

(1, 101, '2022-01-01'),

(1, 102, '2022-01-15'),

(2, 101, '2023-02-01'),

(2, 103, '2023-02-10'),

(3, 102, '2023-03-01'),

(3, 104, '2023-03-15');


3. Stored Functions

a) Stored function to accept project name

Display employee names and total count Raise exception for invalid project name

CREATE OR REPLACE FUNCTION employees_by_project(prj_name CHAR)

RETURNS VOID

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

emp_count INT;

prj_no INT;

emp_cursor CURSOR FOR

SELECT e.ename

FROM Employee e

JOIN Project_Employee pe ON e.empno = pe.empno

WHERE pe.pno = prj_no;

BEGIN

-- Check if project exists

SELECT pno INTO prj_no

FROM Project

WHERE pname = prj_name;

IF NOT FOUND THEN


RAISE EXCEPTION 'Invalid Project Name: %', prj_name;

END IF;

OPEN emp_cursor;

emp_count := 0;

LOOP

FETCH emp_cursor INTO rec;

EXIT WHEN NOT FOUND;

emp_count := emp_count + 1;

RAISE NOTICE 'Employee Name: %', rec.ename;

END LOOP;

CLOSE emp_cursor;

RAISE NOTICE 'Total Employees Working on % : %', prj_name, emp_count;

END;

$$;

Execution

SELECT employees_by_project('ERP System');


b) Stored function to accept empno

Count number of projects Raise exception for invalid employee number

CREATE OR REPLACE FUNCTION project_count_by_employee(e_no INT)

RETURNS INT

LANGUAGE plpgsql

AS $$

DECLARE

proj_count INT;

BEGIN

-- Validate employee

IF NOT EXISTS (SELECT 1 FROM Employee WHERE empno = e_no) THEN

RAISE EXCEPTION 'Invalid Employee Number: %', e_no;

END IF;

SELECT COUNT(*) INTO proj_count

FROM Project_Employee

WHERE empno = e_no;

RETURN proj_count;

END;

$$;

Execution

SELECT project_count_by_employee(101);


SET B

Person – Area database

Person (pno int, name varchar (20), birthdate date, income money) Area

(aid int, aname varchar (20), area_type varchar (5))

The person and area related to many to one relationship. The attribute ‘area_type’ can have values

either ‘urban’ or ‘rural’.


Create the above database in PostGreSQL and insert sufficient records.

a. Write a stored function that accepts the area name as an input parameter from the user

and displays the details of persons living in that area. Raise an exception if area name is invalid.

-- Area Table

CREATE TABLE Area (

aid INT PRIMARY KEY,

aname VARCHAR(20),

area_type VARCHAR(5)

CHECK (area_type IN ('urban', 'rural'))

);

-- Person Table

CREATE TABLE Person (

pno INT PRIMARY KEY,

name VARCHAR(20),

birthdate DATE,

income MONEY,

aid INT,

FOREIGN KEY (aid) REFERENCES Area(aid)

);

2. Insert Sufficient Records


-- Insert into Area

INSERT INTO Area VALUES

(1, 'Nashik', 'urban'),

(2, 'Lasalgaon', 'rural'),

(3, 'Pune', 'urban');

-- Insert into Person

INSERT INTO Person VALUES

(101, 'Amit', '1995-03-15', 75000, 1),

(102, 'Sneha', '1998-07-10', 52000, 2),

(103, 'Rahul', '1996-03-25', 98000, 3),

(104, 'Neha', '1997-12-05', 45000, 1),

(105, 'Suresh','1994-07-18', 60000, 3);

3. Stored Function

Accept area name and display details of persons living in that area Raise exception for invalid area name

sql

CREATE OR REPLACE FUNCTION persons_by_area(area_name VARCHAR)

RETURNS TABLE (

pno INT,

pname VARCHAR,

birthdate DATE,

income MONEY

)


LANGUAGE plpgsql

AS $$

DECLARE

area_id INT;

BEGIN

-- Validate area name

SELECT aid INTO area_id

FROM Area

WHERE aname = area_name;

IF NOT FOUND THEN

RAISE EXCEPTION 'Invalid Area Name: %', area_name;

END IF;

-- Return person details

RETURN QUERY

SELECT p.pno, p.name, p.birthdate, p.income

FROM Person p

WHERE p.aid = area_id;

END;

$$;

4. Execution

SELECT * FROM persons_by_area('Nashik');

SELECT * FROM persons_by_area('Mumbai');

Output:

ERROR: Invalid Area Name: Mumbai


SET C

Wholesaler – Product database

Consider the following entities and their relationships.

Wholesaler (w_no, w_name, address, city)

Product (product_no, product_name, rate)

Relation between Wholesaler and Product is Many to Many with quantity as descriptive attribute.

Create the above database in PostGreSQL and insert sufficient records.

a. Write a function to accept quantity from user. Quantity must be within range 50-200. If user

enters the quantity out of range, then raise a user defined exception “quantity_out_of _range”

otherwise enter the record in table.

b. Write a function which accept rate from user. If user enters rate less than or equal to zero then

raise an user defined exception “Invalid_Rate_Value” otherwise display message “Correct Input”.

c. Write a function to accept product name as parameter. If entered product name is not valid then

raise an user defined exception”Invalid_Product_Name” otherwise display product details of

Specified product.

-- Wholesaler Table

CREATE TABLE Wholesaler (

w_no INT PRIMARY KEY,


w_name VARCHAR(50),

address VARCHAR(100),

city VARCHAR(30)

);

-- Product Table

CREATE TABLE Product (

product_no INT PRIMARY KEY,

product_name VARCHAR(50),

rate NUMERIC(10,2)

);

-- Junction Table with descriptive attribute Quantity

CREATE TABLE Wholesaler_Product (

w_no INT,

product_no INT,

quantity INT,

PRIMARY KEY (w_no, product_no),

FOREIGN KEY (w_no) REFERENCES Wholesaler(w_no),

FOREIGN KEY (product_no) REFERENCES Product(product_no)

);

2. Insert Sample Records


-- Insert into Wholesaler

INSERT INTO Wholesaler VALUES

(1, 'ABC Traders', '123 Main Street', 'Mumbai'),

(2, 'XYZ Enterprises', '456 Park Avenue', 'Pune');

-- Insert into Product

INSERT INTO Product VALUES

(101, 'Laptop', 50000),

(102, 'Mobile', 15000),

(103, 'Printer', 8000);

-- Sample Junction Table Entry (quantity between 50-200)

INSERT INTO Wholesaler_Product VALUES

(1, 101, 100),

(1, 102, 150),

(2, 102, 50);

3. Stored Functions with User-Defined Exceptions

a) Function to accept quantity Must be between 50-200 Raise exception quantity_out_of_range if

invalid Otherwise insert record into Wholesaler_Product

sql

CREATE OR REPLACE FUNCTION insert_wholesaler_product(

w INT, p INT, q INT

)


RETURNS VOID

LANGUAGE plpgsql

AS $$

BEGIN

IF q < 50 OR q > 200 THEN

RAISE EXCEPTION 'quantity_out_of_range: %', q;

END IF;

-- Insert into Wholesaler_Product

INSERT INTO Wholesaler_Product (w_no, product_no, quantity)

VALUES (w, p, q);

RAISE NOTICE 'Record inserted successfully: Wholesaler %, Product %, Quantity %', w, p, q;

END;

$$;

Execution Examples

sql

-- Valid quantity

SELECT insert_wholesaler_product(2, 103, 100);

-- Invalid quantity

SELECT insert_wholesaler_product(2, 103, 30);

-- ERROR: quantity_out_of_range: 30

b) Function to accept rate If rate ≤ 0, raise Invalid_Rate_Value Otherwise display “Correct Input”

CREATE OR REPLACE FUNCTION validate_rate(r NUMERIC)

RETURNS VOID

LANGUAGE plpgsql

AS $$

BEGIN

IF r <= 0 THEN

RAISE EXCEPTION 'Invalid_Rate_Value: %', r;

ELSE

RAISE NOTICE 'Correct Input';

END IF;

END;

$$;

Execution Examples

sql

SELECT validate_rate(15000);

-- NOTICE: Correct Input

SELECT validate_rate(-500);

-- ERROR: Invalid_Rate_Value: -500

c) Function to accept product_name If product name does not exist, raise Invalid_Product_Name

Otherwise display product details

sql


CREATE OR REPLACE FUNCTION product_details_by_name(pname VARCHAR)

RETURNS TABLE (

product_no INT,

product_name VARCHAR,

rate NUMERIC

)

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

BEGIN

-- Check if product exists

SELECT * INTO rec

FROM Product

WHERE product_name = pname;

IF NOT FOUND THEN

RAISE EXCEPTION 'Invalid_Product_Name: %', pname;

END IF;

-- Return product details

RETURN QUERY

SELECT product_no, product_name, rate

FROM Product

WHERE product_name = pname;

END;

$$;

Execution Examples


SELECT * FROM product_details_by_name('Laptop');

SELECT * FROM product_details_by_name('Tablet');

-- ERROR: Invalid_Product_Name: Tablet


SET D

Student Teacher Database

Student (sno integer, s_name char(30), s_class char(10), s_addr Char(50))

Teacher (tno integer, t_name char (20), qualification char (15), experience integer)

The relationship is as follows:

Student-Teacher: Many to Many with descriptive attribute Subject.

a. Write a stored function to count the number of the teachers teaching to a student named “ ”. (Accept student name as input parameter). Raise an exception if student name does not exist.

b. Write a stored function to count the number of the students who are studying subject named “ ” (Accept subject name as input parameter). Display error message if subject name is not valid.

c. Write a stored function to display teacher details who have qualification as “ ” (Accept teacher’s  qualification as input parameter). Raise an exception for invalid qualification.


-- Student Table

CREATE TABLE Student (

sno INT PRIMARY KEY,

s_name CHAR(30),

s_class CHAR(10),

s_addr CHAR(50)

);

-- Teacher Table

CREATE TABLE Teacher (

tno INT PRIMARY KEY,

t_name CHAR(20),

qualification CHAR(15),

experience INT

);

-- Junction Table with descriptive attribute Subject

CREATE TABLE Student_Teacher (

sno INT,

tno INT,

subject CHAR(30),

PRIMARY KEY (sno, tno, subject),

FOREIGN KEY (sno) REFERENCES Student(sno),

FOREIGN KEY (tno) REFERENCES Teacher(tno)

);

2. Insert Sample Records

sql

-- Insert into Student

INSERT INTO Student VALUES

(1, 'Amit', 'BScCS', '123 Main Street'),

(2, 'Sneha', 'BScIT', '456 Park Avenue'),

(3, 'Rahul', 'BCA', '789 Oak Street');

-- Insert into Teacher

INSERT INTO Teacher VALUES

(101, 'Ramesh', 'MScCS', 10),

(102, 'Suresh', 'MCA', 8),

(103, 'Mahesh', 'BScCS', 5);

-- Insert into Student_Teacher

INSERT INTO Student_Teacher VALUES

(1, 101, 'DBMS'),

(1, 102, 'AI'),

(2, 101, 'DBMS'),

(2, 103, 'ComputerNet'),

(3, 102, 'AI');

3. Stored Functions


a) Count teachers teaching a student Accept student name as input Raise exception if student name does not exist

sql

CREATE OR REPLACE FUNCTION count_teachers_by_student(student_name CHAR)

RETURNS INT

LANGUAGE plpgsql

AS $$

DECLARE

student_id INT;

teacher_count INT;

BEGIN

-- Validate student

SELECT sno INTO student_id

FROM Student

WHERE s_name = student_name;

IF NOT FOUND THEN

RAISE EXCEPTION 'Student Name Not Found: %', student_name;

END IF;

-- Count teachers teaching this student

SELECT COUNT(DISTINCT tno) INTO teacher_count

FROM Student_Teacher

WHERE sno = student_id;

RETURN teacher_count;

END;

$$;

Execution Example

sql

SELECT count_teachers_by_student('Amit');

b) Count students studying a given subject Accept subject name as input Raise error if subject

name not found

sql

CREATE OR REPLACE FUNCTION count_students_by_subject(sub_name CHAR)

RETURNS INT

LANGUAGE plpgsql

AS $$

DECLARE

total_students INT;

BEGIN

-- Validate subject exists

IF NOT EXISTS (

SELECT 1 FROM Student_Teacher WHERE subject = sub_name

) THEN


RAISE EXCEPTION 'Invalid Subject Name: %', sub_name;

END IF;

-- Count students

SELECT COUNT(DISTINCT sno) INTO total_students

FROM Student_Teacher

WHERE subject = sub_name;

RETURN total_students;

END;

$$;

Execution Example

sql

SELECT count_students_by_subject('DBMS');

c) Display teacher details by qualification Accept teacher qualification as input Raise exception if

qualification not found

sql

CREATE OR REPLACE FUNCTION teachers_by_qualification(q CHAR)

RETURNS TABLE (

tno INT,

t_name CHAR(20),

qualification CHAR(15),

experience INT

)

LANGUAGE plpgsql

AS $$

BEGIN

-- Validate qualification exists

IF NOT EXISTS (SELECT 1 FROM Teacher WHERE qualification = q) THEN

RAISE EXCEPTION 'Invalid Qualification: %', q;

END IF;

-- Return teacher details

RETURN QUERY

SELECT tno, t_name, qualification, experience

FROM Teacher

WHERE qualification = q;

END;

$$;

Execution Example

sql

SELECT * FROM teachers_by_qualification('MCA');

SET E

Railway Reservation System Database

TRAIN: (train_no int, train_name varchar(20), depart_time time , arrival_time time, source_stn


varchar (20),dest_stn varchar (20), no_of_res_bogies int ,bogie_capacity int)

PASSENGER : (passenger_id int, passenger_name varchar(20), address varchar(30), age int

gender char)

Relationships:

Train _Passenger: Many to Many relationship named ticket with descriptive attributes as follows

TICKET: ( train_no int, passenger_id int, ticket_no int ,bogie_no int, no_of_berths int ,tdate date ,

ticket_amt decimal(7,2),status char)

Constraints: The status of a berth can be 'W' (waiting) or 'C' (confirmed).

a. Write a stored function to print the details of train wise confirmed bookings on date “ ” (Accept

date as input parameter).Raise an error in case of invalid date.

b. Write a stored function to accept date and passenger name and display no of berths reserved

and ticket amount paid by him. Raise exception if passenger name is invalid.

c. Write a stored function to display the ticket details of a train. (Accept train name as input

parameter).Raise an exception in case of invalid train name.

-- TRAIN Table

CREATE TABLE TRAIN (

train_no INT PRIMARY KEY,

train_name VARCHAR(20),

depart_time TIME,

arrival_time TIME,

source_stn VARCHAR(20),

dest_stn VARCHAR(20),

no_of_res_bogies INT,

bogie_capacity INT

);

-- PASSENGER Table

CREATE TABLE PASSENGER (

passenger_id INT PRIMARY KEY,

passenger_name VARCHAR(20),

address VARCHAR(30),

age INT,

gender CHAR

);

-- TICKET Table (Many-to-Many relationship)

CREATE TABLE TICKET (

train_no INT,

passenger_id INT,

ticket_no INT,

bogie_no INT,

no_of_berths INT,

tdate DATE,

ticket_amt DECIMAL(7,2),

status CHAR CHECK (status IN ('W', 'C')),

PRIMARY KEY (ticket_no),

FOREIGN KEY (train_no) REFERENCES TRAIN(train_no),


FOREIGN KEY (passenger_id) REFERENCES PASSENGER(passenger_id)

);

2. Insert Sample Records


-- Insert into TRAIN

INSERT INTO TRAIN VALUES

(101, 'Express1', '06:00', '12:00', 'Mumbai', 'Delhi', 10, 50),

(102, 'Express2', '08:00', '14:00', 'Pune', 'Mumbai', 8, 40);

-- Insert into PASSENGER

INSERT INTO PASSENGER VALUES

(1, 'Amit', 'Mumbai', 30, 'M'),

(2, 'Sneha', 'Pune', 25, 'F'),

(3, 'Rahul', 'Delhi', 28, 'M');

-- Insert into TICKET

INSERT INTO TICKET VALUES

(101, 1, 1001, 1, 2, '2026-01-25', 3000, 'C'),

(101, 2, 1002, 1, 1, '2026-01-25', 1500, 'C'),

(101, 3, 1003, 2, 1, '2026-01-25', 1500, 'W'),

(102, 1, 1004, 1, 1, '2026-01-26', 2000, 'C');

3. Stored Functions

a) Train-wise confirmed bookings on a given date

sql

CREATE OR REPLACE FUNCTION confirmed_bookings_by_date(b_date DATE)

RETURNS TABLE(

train_no INT,

train_name VARCHAR,

passenger_name VARCHAR,

ticket_no INT,

bogie_no INT,

no_of_berths INT,

ticket_amt DECIMAL(7,2)

)

LANGUAGE plpgsql

AS $$

BEGIN

-- Validate date

IF b_date IS NULL THEN

RAISE EXCEPTION 'Invalid Date Input';

END IF;

RETURN QUERY

SELECT t.train_no, t.train_name, p.passenger_name, tk.ticket_no, tk.bogie_no, tk.no_of_berths,

tk.ticket_amt

FROM TRAIN t

JOIN TICKET tk ON t.train_no = tk.train_no


JOIN PASSENGER p ON tk.passenger_id = p.passenger_id

WHERE tk.tdate = b_date AND tk.status = 'C';

END;

$$;

Execution Example

sql

SELECT * FROM confirmed_bookings_by_date('2026-01-25');

b) Berths and ticket amount for a passenger on a given date

sql

CREATE OR REPLACE FUNCTION berths_by_passenger(b_date DATE, pname VARCHAR)

RETURNS TABLE(

no_of_berths INT,

ticket_amt DECIMAL(7,2)

)

LANGUAGE plpgsql

AS $$

DECLARE

pid INT;

BEGIN

-- Validate passenger

SELECT passenger_id INTO pid

FROM PASSENGER

WHERE passenger_name = pname;

IF NOT FOUND THEN

RAISE EXCEPTION 'Invalid Passenger Name: %', pname;

END IF;

RETURN QUERY

SELECT SUM(no_of_berths), SUM(ticket_amt)

FROM TICKET

WHERE passenger_id = pid AND tdate = b_date;

END;

$$;

Execution Example

sql


SELECT * FROM berths_by_passenger('2026-01-25', 'Amit');

c) Display ticket details of a train by train name

sql

CREATE OR REPLACE FUNCTION ticket_details_by_train(tname VARCHAR)

RETURNS TABLE(

ticket_no INT,

passenger_name VARCHAR,

bogie_no INT,

no_of_berths INT,

tdate DATE,


ticket_amt DECIMAL(7,2),

status CHAR

)

LANGUAGE plpgsql

AS $$

DECLARE

tno INT;

BEGIN

-- Validate train name

SELECT train_no INTO tno

FROM TRAIN

WHERE train_name = tname;

IF NOT FOUND THEN

RAISE EXCEPTION 'Invalid Train Name: %', tname;

END IF;

RETURN QUERY

SELECT tk.ticket_no, p.passenger_name, tk.bogie_no, tk.no_of_berths, tk.tdate, tk.ticket_amt,

tk.status

FROM TICKET tk

JOIN PASSENGER p ON tk.passenger_id = p.passenger_id

WHERE tk.train_no = tno;

END;

$$;

Execution Example

sql

SELECT * FROM ticket_details_by_train('Express1');

SYBCS-DBMS-II- Cursors

 Assignment 3: Cursors

SET A

Bus – Route Database

Consider the following database

Bus (bus_no int, capacity int , depot_name varchar(20))

Route (route_no int, source varchar(20), destination varchar(20), No_of_stations int) Bus and

Route are related with many to many relationship.

Create the above database in PostGreSQL and insert sufficient records.

a. Write a stored function using cursor, which will give details of all routes on which bus no

108 is running.

b. Write a stored function using cursor, which will give details of all buses on route from

“Station” to “Airport”.

-- Bus Table

CREATE TABLE Bus (

bus_no INT PRIMARY KEY,

capacity INT,

depot_name VARCHAR(20)

);

-- Route Table

CREATE TABLE Route (

route_no INT PRIMARY KEY,

source VARCHAR(20),

destination VARCHAR(20),

no_of_stations INT

);

-- Junction Table for Many-to-Many Relationship

CREATE TABLE Bus_Route (

bus_no INT,

route_no INT,

PRIMARY KEY (bus_no, route_no),

FOREIGN KEY (bus_no) REFERENCES Bus(bus_no),

FOREIGN KEY (route_no) REFERENCES Route(route_no)

);

2. Insert Sufficient Records

sql

-- Insert into Bus

INSERT INTO Bus VALUES

(101, 45, 'Nashik'),

(108, 50, 'Mumbai'),

(112, 40, 'Pune'),

(120, 55, 'Nashik');

-- Insert into Route

INSERT INTO Route VALUES

(1, 'Station', 'Airport', 10),


(2, 'CityCenter', 'Station', 8),

(3, 'Station', 'BusStand', 6),

(4, 'Airport', 'CityCenter', 12);

-- Insert into Bus_Route

INSERT INTO Bus_Route VALUES

(108, 1),

(108, 2),

(101, 1),

(112, 3),

(120, 1),

(120, 4);

3. Stored Function Using Cursor

a) Details of all routes on which bus no 108 is running

sql

CREATE OR REPLACE FUNCTION routes_of_bus_108()

RETURNS TABLE (

route_no INT,

source VARCHAR,

destination VARCHAR,

no_of_stations INT

)

LANGUAGE plpgsql

AS $$

DECLARE

route_cursor CURSOR FOR

SELECT r.route_no, r.source, r.destination, r.no_of_stations

FROM Route r

JOIN Bus_Route br ON r.route_no = br.route_no

WHERE br.bus_no = 108;

rec RECORD;

BEGIN

OPEN route_cursor;

LOOP

FETCH route_cursor INTO rec;

EXIT WHEN NOT FOUND;

route_no := rec.route_no;

source := rec.source;

destination := rec.destination;

no_of_stations := rec.no_of_stations;

RETURN NEXT;

END LOOP;

CLOSE route_cursor;

END;

$$;

Execution

SELECT * FROM routes_of_bus_108();

4. Stored Function Using Cursor

b) Details of all buses running on route from “Station” to “Airport”

sql

CREATE OR REPLACE FUNCTION buses_station_to_airport()

RETURNS TABLE (

bus_no INT,

capacity INT,

depot_name VARCHAR

)

LANGUAGE plpgsql

AS $$

DECLARE

bus_cursor CURSOR FOR

SELECT b.bus_no, b.capacity, b.depot_name

FROM Bus b

JOIN Bus_Route br ON b.bus_no = br.bus_no

JOIN Route r ON br.route_no = r.route_no

WHERE r.source = 'Station'

AND r.destination = 'Airport';

rec RECORD;

BEGIN

OPEN bus_cursor;

LOOP

FETCH bus_cursor INTO rec;

EXIT WHEN NOT FOUND;

bus_no := rec.bus_no;

capacity := rec.capacity;

depot_name := rec.depot_name;

RETURN NEXT;

END LOOP;

CLOSE bus_cursor;

END;

$$;

Execution


SELECT * FROM buses_station_to_airport();


SET B

Student –Teacher database

Consider the following database

Teacher( t_no int, t_name varchar(20), age int, yr_experience int)

Subject (s_no int, s_namevarchar(15))

Teacher and Subject are related with many to many relationship


Create the above database in PostGreSQL and insert sufficient records.

a. Write a stored function using cursor which will accept the subject name and print the

names of all teachers teaching that subject.

b. Write a cursor to accept the subject's name from the user as an input and display names

of all teachers teaching that student.

-- Teacher Table

CREATE TABLE Teacher (

t_no INT PRIMARY KEY,

t_name VARCHAR(20),

age INT,

yr_experience INT

);

-- Subject Table

CREATE TABLE Subject (

s_no INT PRIMARY KEY,

s_name VARCHAR(15)

);

-- Junction Table

CREATE TABLE Teacher_Subject (

t_no INT,

s_no INT,

PRIMARY KEY (t_no, s_no),

FOREIGN KEY (t_no) REFERENCES Teacher(t_no),

FOREIGN KEY (s_no) REFERENCES Subject(s_no)

);

2. Insert Sufficient Records

sql

-- Insert into Teacher

INSERT INTO Teacher VALUES

(1, 'Anita', 40, 15),

(2, 'Rahul', 35, 10),

(3, 'Sneha', 45, 20),

(4, 'Amit', 30, 6);

-- Insert into Subject

INSERT INTO Subject VALUES

(101, 'DBMS'),

(102, 'ComputerNet'),

(103, 'AI');

-- Insert into Teacher_Subject

INSERT INTO Teacher_Subject VALUES

(1, 101),

(2, 101),

(3, 102),


(1, 103),

(4, 101),

(3, 103);

3. Stored Function Using Cursor

a) Accept subject name and display names of teachers teaching that subject

sql

CREATE OR REPLACE FUNCTION teachers_by_subject(sub_name VARCHAR)

RETURNS TABLE (

teacher_name VARCHAR

)

LANGUAGE plpgsql

AS $$

DECLARE

teacher_cursor CURSOR FOR

SELECT t.t_name

FROM Teacher t

JOIN Teacher_Subject ts ON t.t_no = ts.t_no

JOIN Subject s ON ts.s_no = s.s_no

WHERE s.s_name = sub_name;

rec RECORD;

BEGIN

OPEN teacher_cursor;

LOOP

FETCH teacher_cursor INTO rec;

EXIT WHEN NOT FOUND;

teacher_name := rec.t_name;

RETURN NEXT;

END LOOP;

CLOSE teacher_cursor;

END;

$$;

Execution

sql

SELECT * FROM teachers_by_subject('DBMS');

4. Cursor Program Accepting Subject Name from User

b) Display names of teachers teaching the given subject

(Implemented as a stored procedure using cursor and user input parameter)

sql

CREATE OR REPLACE PROCEDURE display_teachers(sub_name VARCHAR)

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

teacher_cursor CURSOR FOR

SELECT t.t_name

FROM Teacher t


JOIN Teacher_Subject ts ON t.t_no = ts.t_no

JOIN Subject s ON ts.s_no = s.s_no

WHERE s.s_name = sub_name;

BEGIN

OPEN teacher_cursor;

LOOP

FETCH teacher_cursor INTO rec;

EXIT WHEN NOT FOUND;

RAISE NOTICE 'Teacher Name: %', rec.t_name;

END LOOP;

CLOSE teacher_cursor;

END;

$$;

Execution

CALL display_teachers('AI');


SET C

Person - Area Database

Person (pno int, name varchar (20), birthdate date, income money) Area

(aid int, aname varchar (20), area_type varchar (5) )

The person and area related to many to one relationship. The attribute ‘area_type’ can have values

either ‘urban’ or ‘rural’.

Create the above database in PostGreSQL and insert sufficient records.

a. Write a cursor to accept a month as an input parameter from the user and display the

names of persons whose birthday falls in that particular month.

b. Write a cursor to display the names of persons living in urban area.

c. Write a cursor to print names of all persons having income between50,000 and 1,00,000.

-- Area Table

CREATE TABLE Area (

aid INT PRIMARY KEY,

aname VARCHAR(20),

area_type VARCHAR(5) CHECK (area_type IN ('urban', 'rural'))

);

-- Person Table

CREATE TABLE Person (

pno INT PRIMARY KEY,

name VARCHAR(20),

birthdate DATE,

income MONEY,

aid INT,

FOREIGN KEY (aid) REFERENCES Area(aid)

);

2. Insert Sufficient Records


sql

-- Insert into Area

INSERT INTO Area VALUES

(1, 'Nashik', 'urban'),

(2, 'Lasalgaon', 'rural'),

(3, 'Pune', 'urban');

-- Insert into Person

INSERT INTO Person VALUES

(101, 'Amit', '1995-03-15', 75000, 1),

(102, 'Sneha', '1998-07-10', 52000, 2),

(103, 'Rahul', '1996-03-25', 98000, 3),

(104, 'Neha', '1997-12-05', 45000, 1),

(105, 'Suresh', '1994-07-18', 60000, 3);

3. Cursor Programs

a) Cursor to accept month and display persons whose birthday falls in that month

sql

CREATE OR REPLACE PROCEDURE birthday_in_month(m INT)

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

bday_cursor CURSOR FOR

SELECT name

FROM Person

WHERE EXTRACT(MONTH FROM birthdate) = m;

BEGIN

OPEN bday_cursor;

LOOP

FETCH bday_cursor INTO rec;

EXIT WHEN NOT FOUND;

RAISE NOTICE 'Person Name: %', rec.name;

END LOOP;

CLOSE bday_cursor;

END;

$$;

Execution


CALL birthday_in_month(3);

b) Cursor to display names of persons living in urban area

CREATE OR REPLACE PROCEDURE persons_in_urban_area()

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;


urban_cursor CURSOR FOR

SELECT p.name

FROM Person p

JOIN Area a ON p.aid = a.aid

WHERE a.area_type = 'urban';

BEGIN

OPEN urban_cursor;

LOOP

FETCH urban_cursor INTO rec;

EXIT WHEN NOT FOUND;

RAISE NOTICE 'Person Name: %', rec.name;

END LOOP;

CLOSE urban_cursor;

END;

$$;

Execution

sql

Copy code

CALL persons_in_urban_area();

c) Cursor to print names of persons having income between 50,000 and 1,00,000

(Money type safely cast to numeric)


CREATE OR REPLACE PROCEDURE income_range_persons()

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

income_cursor CURSOR FOR

SELECT name

FROM Person

WHERE income::numeric BETWEEN 50000 AND 100000;

BEGIN

OPEN income_cursor;

LOOP

FETCH income_cursor INTO rec;

EXIT WHEN NOT FOUND;

RAISE NOTICE 'Person Name: %', rec.name;

END LOOP;

CLOSE income_cursor;

END;

$$;

Execution


CALL income_range_persons();


SET D

Student – Competition Database

Consider the following entities and their relationship.

Student (s_reg_no int, s_name varchar(20), s_class varchar(20))

Competition (comp_no int, comp_name varchar(20), comp_type varchar(20))

Relationship between Student and Competition is many-to-many with descriptive attribute rank

and year.

a) Write a cursor which will display year wise details of competitions held. (Use

parameterized cursor)

b) Write a cursor which will display student wise total count of competition participated.

-- Student Table

CREATE TABLE Student (

s_reg_no INT PRIMARY KEY,

s_name VARCHAR(20),

s_class VARCHAR(20)

);

-- Competition Table

CREATE TABLE Competition (

comp_no INT PRIMARY KEY,

comp_name VARCHAR(20),

comp_type VARCHAR(20)

);

-- Relationship Table with descriptive attributes

CREATE TABLE Student_Competition (

s_reg_no INT,

comp_no INT,

rank INT,

year INT,

PRIMARY KEY (s_reg_no, comp_no, year),

FOREIGN KEY (s_reg_no) REFERENCES Student(s_reg_no),

FOREIGN KEY (comp_no) REFERENCES Competition(comp_no)

);

2. Insert Sufficient Records

sql

-- Insert into Student

INSERT INTO Student VALUES

(1, 'Amit', 'BSc CS'),

(2, 'Sneha', 'BSc IT'),

(3, 'Rahul', 'BCA');

-- Insert into Competition

INSERT INTO Competition VALUES

(101, 'CodeFest', 'Technical'),

(102, 'QuizMania', 'Academic'),


(103, 'Hackathon', 'Technical');

-- Insert into Student_Competition

INSERT INTO Student_Competition VALUES

(1, 101, 1, 2023),

(1, 102, 2, 2023),

(2, 101, 3, 2022),

(2, 103, 1, 2023),

(3, 102, 1, 2022),

(3, 103, 2, 2023);

3. Cursor Programs

a) Parameterized Cursor to display year-wise competition details


CREATE OR REPLACE PROCEDURE competitions_by_year(y INT)

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

comp_cursor CURSOR (yr INT) FOR

SELECT DISTINCT c.comp_name, c.comp_type, sc.year

FROM Competition c

JOIN Student_Competition sc ON c.comp_no = sc.comp_no

WHERE sc.year = yr;

BEGIN

OPEN comp_cursor(y);

LOOP

FETCH comp_cursor INTO rec;

EXIT WHEN NOT FOUND;

RAISE NOTICE 'Year: %, Competition: %, Type: %',

rec.year, rec.comp_name, rec.comp_type;

END LOOP;

CLOSE comp_cursor;

END;

$$;

Execution

CALL competitions_by_year(2023);

b) Cursor to display student-wise total count of competitions participated


CREATE OR REPLACE PROCEDURE student_competition_count()

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

count_cursor CURSOR FOR

SELECT s.s_name, COUNT(sc.comp_no) AS total_competitions


FROM Student s

LEFT JOIN Student_Competition sc

ON s.s_reg_no = sc.s_reg_no

GROUP BY s.s_name;

BEGIN

OPEN count_cursor;

LOOP

FETCH count_cursor INTO rec;

EXIT WHEN NOT FOUND;

RAISE NOTICE 'Student: %, Competitions Participated: %',

rec.s_name, rec.total_competitions;

END LOOP;

CLOSE count_cursor;

END;

$$;

Execution

CALL student_competition_count();


SET E

Car – Driver Database

Consider the following database:

Car (c_no int, owner varchar(20), model varchar(10), color varchar(10)

Driver (driver_no int, driver_namevarchar(20), license_no int, d_age int, salary float) Car

and Driver are related with many to many relationship

Create the above database in PostGreSQL and insert sufficient records.

a. Write a stored function with cursor which accepts the color and prints the names of all owners

who own a car of that color.

b. Write a cursor which accepts the driver name and prints the details of all cars that this driver

has driven, if the driver name is invalid, print an appropriate message.

-- Car Table

CREATE TABLE Car (

c_no INT PRIMARY KEY,

owner VARCHAR(20),

model VARCHAR(10),

color VARCHAR(10)

);

-- Driver Table

CREATE TABLE Driver (

driver_no INT PRIMARY KEY,

driver_name VARCHAR(20),

license_no INT,

d_age INT,

salary FLOAT


);

-- Junction Table

CREATE TABLE Car_Driver (

c_no INT,

driver_no INT,

PRIMARY KEY (c_no, driver_no),

FOREIGN KEY (c_no) REFERENCES Car(c_no),

FOREIGN KEY (driver_no) REFERENCES Driver(driver_no)

);

2. Insert Sufficient Records


-- Insert into Car

INSERT INTO Car VALUES

(1, 'Amit', 'Swift', 'Red'),

(2, 'Neha', 'City', 'White'),

(3, 'Rahul', 'i20', 'Red'),

(4, 'Sneha', 'Creta', 'Black');

-- Insert into Driver

INSERT INTO Driver VALUES

(101, 'Ramesh', 5551, 35, 25000),

(102, 'Suresh', 5552, 40, 30000),

(103, 'Mahesh', 5553, 30, 22000);

-- Insert into Car_Driver

INSERT INTO Car_Driver VALUES

(1, 101),

(2, 101),

(3, 102),

(4, 103),

(1, 102);

3. Cursor-Based Programs

a) Stored function using cursor Accept color and print names of owners who own a car of that color


CREATE OR REPLACE FUNCTION owners_by_color(c_color VARCHAR)

RETURNS TABLE (

owner_name VARCHAR

)

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

owner_cursor CURSOR FOR

SELECT DISTINCT owner

FROM Car


WHERE color = c_color;

BEGIN

OPEN owner_cursor;

LOOP

FETCH owner_cursor INTO rec;

EXIT WHEN NOT FOUND;

owner_name := rec.owner;

RETURN NEXT;

END LOOP;

CLOSE owner_cursor;

END;

$$;

Execution

SELECT * FROM owners_by_color('Red');


b) Cursor accepting driver name and displaying details of all cars driven If driver name is invalid,

print an appropriate message


CREATE OR REPLACE PROCEDURE cars_driven_by_driver(dname VARCHAR)

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

driver_count INT;

car_cursor CURSOR FOR

SELECT c.c_no, c.owner, c.model, c.color

FROM Car c

JOIN Car_Driver cd ON c.c_no = cd.c_no

JOIN Driver d ON cd.driver_no = d.driver_no

WHERE d.driver_name = dname;

BEGIN

-- Check if driver exists

SELECT COUNT(*) INTO driver_count

FROM Driver

WHERE driver_name = dname;

IF driver_count = 0 THEN

RAISE NOTICE 'Invalid Driver Name: %', dname;

RETURN;

END IF;

OPEN car_cursor;

LOOP

FETCH car_cursor INTO rec;

EXIT WHEN NOT FOUND;


RAISE NOTICE 'Car No: %, Owner: %, Model: %, Color: %',

rec.c_no, rec.owner, rec.model, rec.color;

END LOOP;

CLOSE car_cursor;

END;

$$;

Execution

sql

CALL cars_driven_by_driver('Ramesh');

sql

CALL cars_driven_by_driver('Unknown');

SYBCS -DBMS-II-Stored Functions

 Assignment 2 - Stored Functions

SET A

Using If.-Then-else,case,for,while and unconditional loops

1. Find maximum and minimum from two numbers

create or replace function max_min (x int , y int )returns int as $$

declare

max int;

min int;

begin

if x>y then

max:=x;

min:=y;

else

max:=y;

min:=x;

end if;

raise NOtice ' Max:=% Min:=% ',max,min;

return 1;

end;

$$ language plpgsql;

select max_min(10,5);

NOTICE: Max:=10 Min:=5

max_min

---------

1

(1 row)

postgres=# select max_min(2,5);

NOTICE: Max:=5 Min:=2

max_min


---------

1

(1 row)

2. Check the number is positive, negative or zero.

create or replace function chk_no (n int )returns int as $$

begin

if n>0 then

raise Notice ' % is Positive',n;

else if n<0 then

raise Notice ' % is Negative',n;

else

raise Notice ' % is Zero',n;

end if;

end if;

return 1;

end;

$$ language plpgsql;


postgres=# select chk_no(5);

NOTICE: 5 is Positive

chk_no

--------

1

(1 row)

postgres=# select chk_no(-2);

NOTICE: -2 is Negative

chk_no

--------

1

(1 row)

postgres=# select chk_no(0);

NOTICE: 0 is Zero

chk_no

--------

1

(1 row)

3. Find maximum and minimum from three numbers

create or replace function max_min (x int , y int, z int )returns int as $$

declare

max int;

min int;

begin

if x>y AND x>z then


max:=x;

else if y>x AND y>z then

max:=y;

else

max:=z;

end if;

end if;

return max;

end;

$$ language plpgsql;

4. Find number is even or odd

create or replace function even_odd (n int )returns int as $$

declare

rem int;

begin

rem:=n%2;

if rem=0 then

raise Notice ' % is Even',n;

else

raise Notice ' % is Odd',n;

end if;

return 1;

end;

$$ language plpgsql;

postgres=# select even_odd(4);

NOTICE: 4 is Even

even_odd

----------

1

(1 row)

postgres=# select even_odd(9);

NOTICE: 9 is Odd

even_odd

----------

1

(1 row)

5. Find sum of first 10 numbers (using unconditional loop)

CREATE OR REPLACE FUNCTION getSum() RETURNS int AS $$

DECLARE

SUM Int := 0;

BEGIN

FOR I IN 1 .. 10

LOOP

SUM := SUM + I;


END LOOP;

Return SUM;

END;

$$ language 'plpgsql';

CREATE FUNCTION

assignment=# select getSum();

getsum

--------

55

(1 row)

6. Display all odd numbers from 1 to 50.

create or replace function oddno ()returns void as $$

declare

rem int;

begin

FOR I IN 1 .. 50

LOOP

rem:=I%2;

if rem=1 then

raise Notice ' % is odd',I;

end if;

End Loop;

end;

$$ language plpgsql;

CREATE FUNCTION

assignment=# select oddno();

NOTICE: 1 is odd

NOTICE: 3 is odd

NOTICE: 5 is odd

NOTICE: 7 is odd

NOTICE: 9 is odd

NOTICE: 11 is odd

NOTICE: 13 is odd

NOTICE: 15 is odd

NOTICE: 17 is odd

NOTICE: 19 is odd

NOTICE: 21 is odd

NOTICE: 23 is odd

NOTICE: 25 is odd

NOTICE: 27 is odd

NOTICE: 29 is odd

NOTICE: 31 is odd

NOTICE: 33 is odd

NOTICE: 35 is odd

NOTICE: 37 is odd

NOTICE: 39 is odd

NOTICE: 41 is odd


NOTICE: 43 is odd

NOTICE: 45 is odd

NOTICE: 47 is odd

NOTICE: 49 is odd

oddno

-------

(1 row)


7. Find sum and average of first n numbers using conditional loop(while)

CREATE OR REPLACE FUNCTION nautral_sum(num integer) RETURNS int AS $$

DECLARE

sum integer = 0;

avg float =0.0;

i integer = 1;

BEGIN

IF (num <= 1) THEN

RETURN 1;

END IF;

WHILE(i <= num) LOOP

sum = sum + i;

i = i+1;

END LOOP;

avg=sum/num;

raise notice 'Sum = %',sum;

raise Notice 'Avg = %',avg;

return 0;

END;

$$ LANGUAGE plpgsql;

CREATE FUNCTION

assignment=# select nautral_sum(5);

NOTICE: Sum = 15

NOTICE: Avg = 3

nautral_sum

-------------

0

(1 row)


8. Count even numbers from given range(m to n) (for)

create or replace function Even_No (m int , n int )returns void as $$

declare

rem int;


begin

FOR I IN m .. n

LOOP

rem:=I%2;

if rem=0 then

raise Notice ' % is even',I;

end if;

End Loop;

end;

$$ language plpgsql;

CREATE FUNCTION

select Even_No(5,10);

NOTICE: 6 is even

NOTICE: 8 is even

NOTICE: 10 is even

even_no

---------

(1 row)

9. Search the given number is in given range.

create or replace function find_no (m int , n int, no int )returns int as $$

begin

FOR I IN m .. n

LOOP

if I=no then

raise notice '% is found', no;

return 1;

end if;

end loop;

raise notice '% is not found',no;

return 0;

end;

$$ language plpgsql;

CREATE FUNCTION

assignment=# select find_no(5,10,6);

NOTICE: 6 is found

find_no

---------

1

(1 row)

10.Display a number in word (Using Case) and loop.

CREATE OR REPLACE FUNCTION no_word (x integer) RETURNS text AS $$

DECLARE

num text;


BEGIN

CASE

WHEN x = 0 THEN num := 'ZERO';

WHEN x = 1 THEN num := 'ONE';

WHEN x = 2 THEN num := 'TWO';

WHEN x = 3 THEN num := 'THREE';

WHEN x = 4 THEN num := 'FOUR';

WHEN x = 5 THEN num := 'FIVE';

WHEN x = 6 THEN num := 'SIX';

WHEN x = 7 THEN num := 'SEVEN';

WHEN x = 8 THEN num := 'EIGHT';

WHEN x = 9 THEN num := 'NINE';

END CASE;

RETURN num;

END;

$$

LANGUAGE plpgsql;

CREATE FUNCTION

assignment=# select no_word(5);

no_word

---------

FIVE


SET B

Bank database

Consider the following database maintained by a Bank. The Bank maintains information about its

branches, customers and their loan applications.

Following are the tables:

branch (bid integer, brname char (30), brcity char (10))

customer (cno integer, cname char (20), caddr char (35), city char(20))

loan_application (lno integer, lamtrequired money, lamtapproved money, l_date date)

The relationship is as follows: branch, customer, loan_application are related with ternary

relationship. TERNARY (bid integer, cno integer, lno integer).

a) Write a function that returns the total number of customers of a particular branch.(Accept

branch name as input parameter.)

b) Write a function to find the minimum loan amount approved.

c) Create a function which returns the total number of customers who have applied for a loan

more than Rs.200000. (Accept loan amount as input parameter)


Create Tables

CREATE TABLE branch (

bid INTEGER PRIMARY KEY,

brname CHAR(30),

brcity CHAR(10)

);

CREATE TABLE customer (


cno INTEGER PRIMARY KEY,

cname CHAR(20),

caddr CHAR(35),

city CHAR(20)

);

CREATE TABLE loan_application (

lno INTEGER PRIMARY KEY,

lamtrequired MONEY,

lamtapproved MONEY,

l_date DATE

);

CREATE TABLE ternary (

bid INTEGER REFERENCES branch(bid),

cno INTEGER REFERENCES customer(cno),

lno INTEGER REFERENCES loan_application(lno),

PRIMARY KEY (bid, cno, lno)

);


a) Function to Return Total Number of Customers of a Particular Branch (Input: Branch Name)

CREATE OR REPLACE FUNCTION total_customers_of_branch(bname CHAR)

RETURNS INTEGER

LANGUAGE plpgsql

AS $$

DECLARE

total INTEGER;

BEGIN

SELECT COUNT(DISTINCT t.cno)

INTO total

FROM ternary t

JOIN branch b ON b.bid = t.bid

WHERE b.brname = bname;

RETURN total;

END;

$$;

Execute

SELECT total_customers_of_branch('MainBranch');


b) Function to Find Minimum Loan Amount Approved

CREATE OR REPLACE FUNCTION min_loan_amount_approved()

RETURNS MONEY

LANGUAGE plpgsql

AS $$

DECLARE

min_amt MONEY;

BEGIN

SELECT MIN(lamtapproved)

INTO min_amt

FROM loan_application;

RETURN min_amt;


END;

$$;

Execute

SELECT min_loan_amount_approved();


c) Function to Return Total Number of Customers (Who Applied for Loan More Than Given Amount)

CREATE OR REPLACE FUNCTION customers_with_loan_above(amount MONEY)

RETURNS INTEGER

LANGUAGE plpgsql

AS $$

DECLARE

total INTEGER;

BEGIN

SELECT COUNT(DISTINCT t.cno)

INTO total

FROM ternary t

JOIN loan_application l ON l.lno = t.lno

WHERE l.lamtrequired > amount;

RETURN total;

END;

$$;

Execute

SELECT customers_with_loan_above(200000);


SET C

Student- Teacher database

Consider the following database maintained by a school. The school maintains information about

students and the teachers. It also gives information of the subject taught by the teacher.

Following are the tables:

student (sno integer, s_name char(30), s_class char(10), s_addr char(50))

teacher (tno integer, t_name char (20), qualification char (15), experience integer)

The relationship is as follows: STUDENT-TEACHER: Many to Many with descriptive attribute

SUBJECT.

a) Write a function to find name of the most experienced teacher for “Computer”.

b) Write a function to find the teacher teaching maximum number of subjects.

c) Write a function to find the number of teachers having qualification “NET”.


Create Tables

CREATE TABLE student (

sno INTEGER PRIMARY KEY,

s_name CHAR(30),

s_class CHAR(10),

s_addr CHAR(50)


);

CREATE TABLE teacher (

tno INTEGER PRIMARY KEY,

t_name CHAR(20),

qualification CHAR(15),

experience INTEGER

);

CREATE TABLE teaches (

sno INTEGER REFERENCES student(sno),

tno INTEGER REFERENCES teacher(tno),

subject CHAR(20),

PRIMARY KEY (sno, tno, subject)

);


a) Function to Find Name of the Most Experienced Teacher for “Computer”

CREATE OR REPLACE FUNCTION most_experienced_computer_teacher()

RETURNS CHAR(20)

LANGUAGE plpgsql

AS $$

DECLARE

teacher_name CHAR(20);

BEGIN

SELECT t.t_name

INTO teacher_name

FROM teacher t

JOIN teaches te ON t.tno = te.tno

WHERE te.subject = 'Computer'

ORDER BY t.experience DESC

LIMIT 1;

RETURN teacher_name;

END;

$$;

Execute

SELECT most_experienced_computer_teacher();


b) Function to Find the Teacher Teaching Maximum Number of Subjects

CREATE OR REPLACE FUNCTION teacher_with_max_subjects()

RETURNS CHAR(20)

LANGUAGE plpgsql

AS $$

DECLARE

teacher_name CHAR(20);

BEGIN

SELECT t.t_name

INTO teacher_name

FROM teacher t

JOIN teaches te ON t.tno = te.tno

GROUP BY t.tno, t.t_name

ORDER BY COUNT(DISTINCT te.subject) DESC

LIMIT 1;


RETURN teacher_name;

END;

$$;

Execute

SELECT teacher_with_max_subjects();


c) Function to Find Number of Teachers Having Qualification “NET”

CREATE OR REPLACE FUNCTION count_net_qualified_teachers()

RETURNS INTEGER

LANGUAGE plpgsql

AS $$

DECLARE

total INTEGER;

BEGIN

SELECT COUNT(*)

INTO total

FROM teacher

WHERE qualification = 'NET';

RETURN total;

END;

$$;

Execute

SELECT count_net_qualified_teachers();


SET D

Project – Employee Database

Consider the following database

Project (pno int, pname char (30), ptype char (20), duration int)

Employee (empno int, ename char (20), joining_date date)

The relationship between Project and Employee is many to many with descriptive attribute

start_date.

Create the above database in PostGreSQL and insert sufficient records.

Execute any two of the following using PL/pgSQL

a. Write a stored function to accept project type as an input and display all project names of

that type.

b. Write a function which accepts employee name and prints the details of the project which

the employee works on.

c. Write a function to accept project name as input and returns the number of employees

working on the project.


Project Table

CREATE TABLE Project (

pno INT PRIMARY KEY,

pname CHAR(30),

ptype CHAR(20),


duration INT

);

Employee Table

CREATE TABLE Employee (

empno INT PRIMARY KEY,

ename CHAR(20),

joining_date DATE

);

Many-to-Many Relationship Table (Descriptive attribute: start_date)

CREATE TABLE Works_On (

pno INT REFERENCES Project(pno),

empno INT REFERENCES Employee(empno),

start_date DATE,

PRIMARY KEY (pno, empno)

);


2 ⃣ Insert Sample Records Insert into Project

INSERT INTO Project VALUES

(1, 'ERP System', 'Software', 12),

(2, 'Payroll App', 'Software', 6),

(3, 'Bridge Design', 'Civil', 18);

Insert into Employee

INSERT INTO Employee VALUES

(101, 'Amit', '2021-01-10'),

(102, 'Sneha', '2020-07-15'),

(103, 'Rahul', '2019-03-20');

Insert into Works_On

INSERT INTO Works_On VALUES

(1, 101, '2022-01-01'),

(1, 102, '2022-02-01'),

(2, 101, '2022-03-10'),

(3, 103, '2022-04-15');


a) Function to Accept Project Type and Display All Project Names

CREATE OR REPLACE FUNCTION projects_by_type(ptype_input CHAR)

RETURNS VOID

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

BEGIN


FOR rec IN

SELECT pname

FROM Project

WHERE ptype = ptype_input

LOOP

RAISE NOTICE 'Project Name: %', rec.pname;

END LOOP;

IF NOT FOUND THEN

RAISE NOTICE 'No projects found for this type';

END IF;

END;

$$;

Execute

SELECT projects_by_type('Software');


b) Function Accepting Employee Name and Display Project Details

CREATE OR REPLACE FUNCTION project_details_by_employee(emp_name CHAR)

RETURNS VOID

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

BEGIN

FOR rec IN

SELECT p.pno, p.pname, p.ptype, p.duration

FROM Project p

JOIN Works_On w ON p.pno = w.pno

JOIN Employee e ON e.empno = w.empno

WHERE e.ename = emp_name

LOOP

RAISE NOTICE 'Project No: %, Name: %, Type: %, Duration: % months',

rec.pno, rec.pname, rec.ptype, rec.duration;

END LOOP;

IF NOT FOUND THEN

RAISE NOTICE 'Employee not assigned to any project';

END IF;

END;

$$;

Execute

SELECT project_details_by_employee('Amit');


c) Function to Accept Project Name and Return Number of Employees

CREATE OR REPLACE FUNCTION employee_count_for_project(proj_name CHAR)

RETURNS INTEGER

LANGUAGE plpgsql

AS $$

DECLARE

total INTEGER;

BEGIN


SELECT COUNT(*)

INTO total

FROM Works_On w

JOIN Project p ON p.pno = w.pno

WHERE p.pname = proj_name;

RETURN total;

END;

$$;

Execute

SELECT employee_count_for_project('ERP System');


SET E

Student - Subject Database

Consider the following database

Student (roll_no integer, name varchar(30), address varchar(50), class varchar(10)) Subject

(scode varchar(10), subject_name varchar(20))

Student-Subject are related with Many to Many relationship with attributes marks_scored. Create

the above database in PostGreSQL and insert sufficient records.

a.Write a function which will accept the name and print all the details of that student.

b. Write a function to accept student roll_no as input and displays details of that student.

c.Write a stored function using cursors, to accept class from the user and display the details of the

students of that class.


Student Table

CREATE TABLE Student (

roll_no INTEGER PRIMARY KEY,

name VARCHAR(30),

address VARCHAR(50),

class VARCHAR(10)

);

Subject Table

CREATE TABLE Subject (

scode VARCHAR(10) PRIMARY KEY,

subject_name VARCHAR(20)

);

Many-to-Many Relationship Table (Descriptive attribute: marks_scored)

CREATE TABLE Student_Subject (

roll_no INTEGER REFERENCES Student(roll_no),

scode VARCHAR(10) REFERENCES Subject(scode),

marks_scored INTEGER,

PRIMARY KEY (roll_no, scode)

);


2 ⃣ Insert Sufficient Records Insert into Student

INSERT INTO Student VALUES

(1, 'Amit', 'Nashik', 'FY'),

(2, 'Sneha', 'Pune', 'FY'),

(3, 'Rahul', 'Mumbai', 'SY'),

(4, 'Priya', 'Nashik', 'SY');

Insert into Subject

INSERT INTO Subject VALUES

('CS101', 'Computer'),

('MA101', 'Maths'),

('EN101', 'English');

Insert into Student_Subject

INSERT INTO Student_Subject VALUES

(1, 'CS101', 78),

(1, 'MA101', 65),

(2, 'CS101', 82),

(3, 'EN101', 70),

(4, 'MA101', 88);


a) Function to Accept Student Name and Print All Details

CREATE OR REPLACE FUNCTION student_details_by_name(sname VARCHAR)

RETURNS VOID

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

BEGIN

FOR rec IN

SELECT * FROM Student

WHERE name = sname

LOOP

RAISE NOTICE 'Roll No: %, Name: %, Address: %, Class: %',

rec.roll_no, rec.name, rec.address, rec.class;

END LOOP;

IF NOT FOUND THEN

RAISE NOTICE 'Student not found';

END IF;

END;

$$;

Execute

SELECT student_details_by_name('Amit');


b) Function to Accept Roll No and Display Student Details

CREATE OR REPLACE FUNCTION student_details_by_roll(rno INTEGER)

RETURNS VOID

LANGUAGE plpgsql


AS $$

DECLARE

rec Student%ROWTYPE;

BEGIN

SELECT * INTO rec

FROM Student

WHERE roll_no = rno;

IF NOT FOUND THEN

RAISE NOTICE 'Student not found';

ELSE

RAISE NOTICE 'Roll No: %, Name: %, Address: %, Class: %',

rec.roll_no, rec.name, rec.address, rec.class;

END IF;

END;

$$;

Execute

SELECT student_details_by_roll(2);


c) Stored Function Using Cursor

(Accept Class and Display Details of Students of that Class)

CREATE OR REPLACE FUNCTION students_by_class(class_input VARCHAR)

RETURNS VOID

LANGUAGE plpgsql

AS $$

DECLARE

cur_students CURSOR FOR

SELECT roll_no, name, address, class

FROM Student

WHERE class = class_input;

rec RECORD;

BEGIN

OPEN cur_students;

LOOP

FETCH cur_students INTO rec;

EXIT WHEN NOT FOUND;

RAISE NOTICE 'Roll No: %, Name: %, Address: %, Class: %',

rec.roll_no, rec.name, rec.address, rec.class;

END LOOP;

CLOSE cur_students;

END;

$$;

Execute

SELECT students_by_class('FY');

SYBCS-DBMS-II- Stored Procedure

Assignment 1.Stored Procedure 

SET A

a. Write a procedure to display addition, subtraction and multiplication of three numbers.

CREATE OR REPLACE PROCEDURE calc_three_numbers(a NUMERIC, b NUMERIC, c NUMERIC)

LANGUAGE plpgsql

AS $$

DECLARE

addition NUMERIC;

subtraction NUMERIC;

multiplication NUMERIC;

BEGIN

addition := a + b + c;

subtraction := a - b - c;

multiplication := a * b * c;

RAISE NOTICE 'Addition of %, %, % = %', a, b, c, addition;

RAISE NOTICE 'Subtraction of %, %, % = %', a, b, c, subtraction;

RAISE NOTICE 'Multiplication of %, %, % = %', a, b, c, multiplication;

END;

$$;

Run Query :-

CALL calc_three_numbers(10, 5, 2);


b. Write a procedure to display division of two numbers use raise to display error messages.

CREATE OR REPLACE PROCEDURE divide_two_numbers(a NUMERIC, b NUMERIC)

LANGUAGE plpgsql

AS $$

DECLARE

result NUMERIC;

BEGIN

IF b = 0 THEN


RAISE EXCEPTION 'Error: Division by zero is not allowed';

ELSE

result := a / b;

RAISE NOTICE 'Division of % by % = %', a, b, result;

END IF;

END;

$$;

Run Query:-

CALL divide_two_numbers(10, 2);


c.Create table Department (dno, dname, empname, city ).

i) Write a procedure to insert values in Department table.

ii) Write a procedure to display all employees working in ‘Pune’ city

CREATE TABLE Department (

dno INT,

dname VARCHAR(50),

empname VARCHAR(50),

city VARCHAR(30)

);

i) Write a procedure to insert values in Department table.

CREATE OR REPLACE PROCEDURE insert_department(

pdno INT,

pdname VARCHAR,

pempname VARCHAR,

pcity VARCHAR

)

LANGUAGE plpgsql

AS $$

BEGIN


INSERT INTO Department (dno, dname, empname, city)

VALUES (pdno, pdname, pempname, pcity);


RAISE NOTICE 'Record inserted successfully';

END;

$$;

Run Query using :-

CALL insert_department(1, 'IT', 'Amit', 'Pune');

CALL insert_department(2, 'HR', 'Sneha', 'Mumbai');

CALL insert_department(3, 'Finance', 'Rahul', 'Pune');


ii) Write a procedure to display all employees working in ‘Pune’ city

CREATE OR REPLACE PROCEDURE display_pune_employees()

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

BEGIN

FOR rec IN

SELECT empname, dname

FROM Department

WHERE city = 'Pune'

LOOP

RAISE NOTICE 'Employee Name: %, Department: %',

rec.empname, rec.dname;

END LOOP;

END;

$$;

Run Query Using :-

CALL display_pune_employees();


SET B

A) Consider the following relationship

Route(route_no,source, destination, no_of_station) Bus

(bus_no, capacity, depot_name)

Relationship between Route and Bus is one-to-many

a. Write a procedure which display all bus details for a given route.

b. Write a procedure to update source of route no 101


Route(route_no, source, destination, no_of_station)

Bus(bus_no, capacity, depot_name, route_no)

CREATE TABLE Route (

route_no INT PRIMARY KEY,

source VARCHAR(50),

destination VARCHAR(50),

no_of_station INT

);


CREATE TABLE Bus (

bus_no INT PRIMARY KEY,

capacity INT,

depot_name VARCHAR(50),

route_no INT REFERENCES Route(route_no)

);

a) Write a procedure which display all bus details for a given route.

CREATE OR REPLACE PROCEDURE display_bus_by_route(rno INT)

LANGUAGE plpgsql

AS $$

DECLARE


rec RECORD;

BEGIN

FOR rec IN

SELECT bus_no, capacity, depot_name

FROM Bus

WHERE route_no = rno

LOOP

RAISE NOTICE 'Bus No: %, Capacity: %, Depot: %',

rec.bus_no, rec.capacity, rec.depot_name;

END LOOP;


IF NOT FOUND THEN

RAISE NOTICE 'No buses found for route no %', rno;

END IF;

END;

$$;

Execute :-

CALL display_bus_by_route(101);

b) PL/pgSQL Procedure to Update Source of Route No 101

CREATE OR REPLACE PROCEDURE update_route_source(new_source VARCHAR)

LANGUAGE plpgsql

AS $$

BEGIN

UPDATE Route

SET source = new_source

WHERE route_no = 101;

IF FOUND THEN

RAISE NOTICE 'Source updated successfully for route no 101';

ELSE


RAISE NOTICE 'Route no 101 not found';

END IF;

END;

$$;

Execute :-

CALL update_route_source('Pune');


B) Consider the following relationship

Patient (p_no, p_name, p_addr) Doctor

(d_no, d_name, d_addr, city)

Relationship between Patient and Doctor is many-to-many with descriptive attribute disease and

no_of_visits.

a. Write a procedure which display patient detail who has visited more than 3 times to the

given doctor for ‘Diabetes’.

b. Write a procedure which displays total number of visits of Dr.Kumar.

Patient (p_no, p_name, p_addr)

Doctor (d_no, d_name, d_addr, city)

Consultation (

p_no,

d_no,

disease,

no_of_visits

)

CREATE TABLE Patient (

p_no INT PRIMARY KEY,

p_name VARCHAR(50),

p_addr VARCHAR(100)

);


CREATE TABLE Doctor (

d_no INT PRIMARY KEY,

d_name VARCHAR(50),

d_addr VARCHAR(100),


city VARCHAR(50)

);


CREATE TABLE Consultation (

p_no INT REFERENCES Patient(p_no),

d_no INT REFERENCES Doctor(d_no),

disease VARCHAR(50),

no_of_visits INT,

PRIMARY KEY (p_no, d_no, disease)

);

a) Procedure to Display Patient Details (Visited more than 3 times to a given doctor for

‘Diabetes’)

CREATE OR REPLACE PROCEDURE display_diabetes_patients(

doc_name VARCHAR

)

LANGUAGE plpgsql

AS $$

DECLARE

rec RECORD;

BEGIN

FOR rec IN

SELECT p.p_no, p.p_name, p.p_addr, c.no_of_visits

FROM Patient p

JOIN Consultation c ON p.p_no = c.p_no

JOIN Doctor d ON d.d_no = c.d_no

WHERE d.d_name = doc_name

AND c.disease = 'Diabetes'

AND c.no_of_visits > 3

LOOP

RAISE NOTICE 'Patient No: %, Name: %, Address: %, Visits: %',

rec.p_no, rec.p_name, rec.p_addr, rec.no_of_visits;

END LOOP;

IF NOT FOUND THEN

RAISE NOTICE 'No such patients found';

END IF;

END;

$$;

Execute

CALL display_diabetes_patients('Dr.Kumar');


b) Procedure to Display Total Number of Visits of Dr. Kumar

CREATE OR REPLACE PROCEDURE total_visits_of_dr_kumar()

LANGUAGE plpgsql

AS $$

DECLARE

total_visits INT;

BEGIN

SELECT SUM(c.no_of_visits)

INTO total_visits

FROM Consultation c

JOIN Doctor d ON d.d_no = c.d_no

WHERE d.d_name = 'Dr.Kumar';

IF total_visits IS NULL THEN

RAISE NOTICE 'Dr. Kumar has no visits recorded';

ELSE

RAISE NOTICE 'Total number of visits of Dr. Kumar = %', total_visits;

END IF;

END;

$$;

Execute :-

CALL total_visits_of_dr_kumar();

Friday, January 31, 2025

WT-II Assignment 5

 ASSIGNMENT 5: PHP Framework CODEIGNITER

Set A 

1. Create a CSS file to apply the following styling for an HTML document.  

Background color: blue, 

H1 

Color : red, 

Font-family : Verdana, 

Font-size : 8 

Color : green, 

Font-family : Monospace, 

Font-size :10 



2. Add a Javascript file in codeigniter. The javascript code should check whether a 

number is positive or negative.  




Set B 

1. Create a table student having attributes (rollno, name, class). Assume appropriate data types for the attributes. Using Codeigniter , connect to the database and insert minimum 5 records in it. 



2. For the above table student, display all its records using Codeigniter. 



Set C 

1. Create a form to accept personal details of customer (name, age, address). Once the personal information is accepted, on the next page accept order details such as (product name, quantity). Display the personal details and order details on the third page. (Use cookies) 




2.  Write a PHP script to accept Employee details ( Eno, Ename, address) on first page. On second page accept earning (Basic, Da, HRA). On third page print Employee information( ENO,Ename, Address, BASIC, DA, HRA, TOTAL) (Use Session)



Wednesday, January 8, 2025

WT-II Assignment-4

 ASSIGNMENT NO. 4: AJAX

 Set A
1. Write AJAX program to read contact.dat file and print the contents of the file in a tabular format when the user clicks on print button. Contact.dat file should contain srno, name, residence number, mobile number, Address. [Enter at least 3 record in contact.dat file]

Solution:-

 HTML file :

<html>

<head>

<style>

span

{

                font-size: 25px;

}

table

{

                color: blueviolet; ;

}

</style>


<script type="text/javascript" >

                function print()

                {

                                var ob=false;

                                ob=new XMLHttpRequest();

             

                                ob.open("GET","slip14_Q2.php?");//emailid="+eid);

                                ob.send();         

             

                                ob.onreadystatechange=function()

                                {

                                                if(ob.readyState==4 && ob.status==200)

                                                {

                                                                document.getElementById("i").innerHTML=ob.responseText;

                                                }

                                }

                }           

</script>

</head>


<body>

<center>

<h3>Display the contents of a contact.dat file </h3>

<br><input  type="button"  value=Print onclick="print()" >

<span id="i"></span>

</center>

</body>

</html>


Dat file : contact.dat


1  Isha  65768798  98765432  Daughter

2  Megha  65235689  87654329  Mother


PHP file :


<?php

                $fp = fopen('contact.dat','r');

                echo "<table border=1>";

                echo "<tr><th>Sr. No.</th><th>Name</th><th>Residence No.</th><th>Mob. no.</th><th>Relation</th></tr>";

             

while($row =  fscanf($fp,"%s %s %s %s %s"))

                {

                                echo "<tr>";

                                foreach($row as $r)

                                {

                                                echo "<td>$r</td>";                           

                                }                           

                                echo "</tr>";

                }

                                echo "</table>";

                fclose($fp);

?

2. Write AJAX program where the user is requested to write his or her name in a text box, and the server keeps sending back responses while the user is typing. If the user name is not entered then the message displayed will be, “Stranger, please tell me your name!”. If the name is Rohit, Virat, Dhoni, Ashwin or Harbhajan , the server responds with “Hello, master <user name>!”. If the name is anything else, the message will be “<user name>, I don’t know you!”.

Solution:-


 <!DOCTYPE html>

<html>

<head>

    <title>Live Name Check</title>

    <script>

        function checkName() {

            var name = document.getElementById("nameInput").value;

            var xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function() {

                if (xhr.readyState === 4 && xhr.status === 200) {

                    document.getElementById("response").innerHTML = xhr.responseText;

                }

            };

            xhr.open("GET", "check.php?name=" + name, true);

            xhr.send();

        }

    </script>

</head>

<body>

    <input type="text" id="nameInput" onkeyup="checkName()">

    <div id="response"></div>

</body>

</html>

check.php

<?php

    $name = $_GET["name"];

    

    $specialNames = array("Rohit", "Virat", "Dhoni", "Ashwin", "Harbhajan");


    if (empty($name)) {

        echo "Stranger, please tell me your name!"; 

    } else if (in_array($name, $specialNames)) {

        echo "Hello, master " . $name . "!";

    } else {

        echo $name . ", I don't know you!";

    }

?>


Set B
1. Create TEACHER table as follows TEACHER(tno, tname, qualification, salary). Write Ajax program to select a teachers name and print the selected teachers details.

Solution:-

getTeacherDetails.html

 <html>

 <head>

 <script>

 function showTeacher(str) {

 var xhttp;

 if (str == "") {

 document.getElementById("teacherDetails").innerHTML = "";

 return;

 }

 xhttp = new XMLHttpRequest();

 xhttp.onreadystatechange = function() {

 if (this.readyState == 4 && this.status == 200) {

 document.getElementById("teacherDetails").innerHTML = this.responseText;

 }

 };

 xhttp.open("GET", "getTeacherDetails.php?name="+str, true);

 xhttp.send();

 }

 </script>

 </head>

 <body>

 <form>

 <select name="teachers" onchange="showTeacher(this.value)">

 <option value="">Select a teacher:</option>

 <?php

 $con = mysqli_connect("localhost","my_user","my_password","my_db");

 $sql = "SELECT tname FROM teacher";

 $result = mysqli_query($con,$sql);

 while ($row = mysqli_fetch_array($result)) {

 echo "<option value='" . $row['tname'] ."'>" . $row['tname'] ."</option>";

 }

 mysqli_close($con);

 ?>

 </select>

 </form>

 <br>

 <div id="teacherDetails"><b>Details will be listed here.</b></div>

 </body>

</html>

//PHP Script getTeacherDetails.php

<?php

 $name = $_REQUEST['name'];

 $con = mysqli_connect("localhost","my_user","my_password","my_db");

 $sql = "SELECT * FROM teacher WHERE tname = '$name'";

 $result = mysqli_query($con,$sql);

 while ($row = mysqli_fetch_array($result)) {

 echo "<b>Teacher Number:</b> " . $row['tno'] . "<br>";

 echo "<b>Name:</b> " . $row['tname'] . "<br>";

 echo "<b>Qualification:</b> " . $row['qualification'] . "<br>";

 echo "<b>Salary:</b> " . $row['salary'] . "<br>";

 }

 mysqli_close($con);

?>

Database

Create database college

Create table teacher(tno int primary key,tname varchar(20),qualificationvarchar(10),salary int);

Insert 3 records


2. CUSTOMER (cno, cname, city) and  ORDER(ono, odate, shipping address)2. Write Ajax program to print Order details by selecting a Customer’s name. Create table Customer and Order as follows with 1 : M cardinality CUSTOMER (cno, cname, city) and  ORDER(ono, odate, shipping address)

Solution:-

 Create Table customer(cno int primary key,cname varchar(20),city varchar(20));

Create Table order(cno int references customer(cno),ono primary key,odate date,shipadd varchar(20));


<?php 

$cname=$_POST['cname'];

$con=pg_connect("host=localhost dbname=minal user=root") or die("could not connect");

$qry="select cname,city from customer,order where customer.cno=order.cno and cname=$cname"; $rs=pg_query($con,$qry) or die("Unable to execute query");

if($rs!=null) { echo"<table border=0>";

echo "<tr><td>Customer Name</td><td>City</td></tr>";

while($row=pg_fetch_row($rs))

 { echo "<tr>";

echo "<td>".$row[0]."</td>";

echo "<td>".$row[1]."</td>";

 echo "</tr>"; }

echo "</table>";

} else echo "No records found";

 pg_close($con);

?>

Set C
1. Write Ajax program to fetch suggestions when is user is typing in a textbox. (eg like google suggestions. Hint create array of suggestions and matching string will be displayed)

Solution:-

 <html>

<head>

<script type="text/javascript">

function suggest()

{

 var arr = ["apple","banana","mango","orange","strawberry","grapes"];

 var suggest = "";

 var input = document.getElementById("txt1").value;

 for(i=0;i<arr.length;i++)

 {

 if(arr[i].substring(0,input.length).toLowerCase() == input.toLowerCase())

 {

 suggest = suggest+" "+arr[i];

 }

 }

 document.getElementById("txt2").innerHTML = suggest;

}

</script>

</head>

<body>

<input type="text" id="txt1" onkeyup="suggest();">

<p>Suggestions: <span id="txt2"></span></p>

</body>

</html>


2. Write Ajax program to get book details from XML file when user select a book name. Create XML file for storing details of book(title, author, year, price).

Solution:-

 BookInfo.xml

 <?xml version="1.0" encoding="utf-8"?>

 <BookList>

 <Book>

 <Title>The Great Gatsby</Title>

 <Author>F. Scott Fitzgerald</Author>

 <Year>1925</Year>

 <Price>$7.99</Price>

 </Book>

 <Book>

 <Title>To Kill a Mockingbird</Title>

 <Author>Harper Lee</Author>

 <Year>1960</Year>

 <Price>$8.99</Price>

 </Book>

 <Book>

 <Title>The Catcher in the Rye</Title>

 <Author>J.D. Salinger</Author>

 <Year>1951</Year>

 <Price>$9.99</Price>

 </Book>

 </BookList>

Html file :

<!DOCTYPE html>

<html lang="en">

<head>

 <title>Document</title>

</head>

<body>

 <script>

 function getBookDetails(bookName) {

 var xhttp = new XMLHttpRequest();

 xhttp.onreadystatechange = function() {

 if (this.readyState == 4 && this.status == 200) {

 var xmlDoc = this.responseXML;

 var book = xmlDoc.getElementsByTagName("Book");

 for (var i = 0; i < book.length; i++) {

 if (book[i].getElementsByTagName("Title")[0].childNodes[0].nodeValue == bookName) {

 alert("Author: " + book[i].getElementsByTagName("Author")[0].childNodes[0].nodeValue + "\n"

+

 "Year: " + book[i].getElementsByTagName("Year")[0].childNodes[0].nodeValue + "\n" +

 "Price: " + book[i].getElementsByTagName("Price")[0].childNodes[0].nodeValue);

 }

 }

 }

 };

 xhttp.open("GET", "BookInfo.xml", true);

 xhttp.send();

 }

 // Call the getBookDetails function

 getBookDetails("The Catcher in the Rye");

 </script>

</body>

</html>