RDBMS
Diploma – 3rd Semester, Computer Engineering
Unit 5
PL/SQL and Triggers
Prepared by:
Bharti D. Mulchandani
Lecturer, Computer Engineering Department
R. C. Technical Institute, Ahmedabad
Course Outcome (CO)
Develop PL/SQL programs incorporating control structures, exceptions, cursors, procedures, functions, and triggers for database automation.
BDM | RDBMS – Unit 5
1
5.1 What is PL/SQL?
DECLARE -- optional: variables, constants, cursors declared here
BEGIN -- mandatory: the executable SQL/PL-SQL statements
EXCEPTION -- optional: error-handling code
END;
BDM | RDBMS – Unit 5
2
Advantages of PL/SQL over SQL
Supports variables, loops & conditions
Processes a whole block in one trip to the server (faster)
Handles run-time errors gracefully
Reusable via procedures, functions & packages
Enables modular, structured code design
Tightly integrated with SQL statements
BDM | RDBMS – Unit 5
3
PL/SQL Data Types & %TYPE
DECLARE
v_name student.sname%TYPE; -- same type & size as student.sname
v_marks student.marks%TYPE;
BEGIN
SELECT sname, marks INTO v_name, v_marks FROM student WHERE roll_no = 1;
DBMS_OUTPUT.PUT_LINE(v_name || ' scored ' || v_marks);
END;
BDM | RDBMS – Unit 5
4
PL/SQL Data Types — %ROWTYPE
DECLARE
v_student student%ROWTYPE; -- one field for every column in 'student'
BEGIN
SELECT * INTO v_student FROM student WHERE roll_no = 1;
DBMS_OUTPUT.PUT_LINE(v_student.sname || ' - ' || v_student.marks);
END;
BDM | RDBMS – Unit 5
5
5.2 Control Structures — IF / ELSIF
IF condition1 THEN
statements;
ELSIF condition2 THEN
statements;
ELSE
statements;
END IF;
IF v_marks >= 75 THEN
DBMS_OUTPUT.PUT_LINE('Distinction');
ELSIF v_marks >= 50 THEN
DBMS_OUTPUT.PUT_LINE('Pass');
ELSE
DBMS_OUTPUT.PUT_LINE('Fail');
END IF;
BDM | RDBMS – Unit 5
6
Control Structures — CASE
CASE
WHEN v_marks >= 75 THEN DBMS_OUTPUT.PUT_LINE('Distinction');
WHEN v_marks >= 50 THEN DBMS_OUTPUT.PUT_LINE('Pass');
ELSE DBMS_OUTPUT.PUT_LINE('Fail');
END CASE;
BDM | RDBMS – Unit 5
7
Iterative Structures — LOOP & WHILE LOOP
Basic LOOP — runs until an explicit EXIT
i := 1;
LOOP
DBMS_OUTPUT.PUT_LINE(i);
i := i + 1;
EXIT WHEN i > 5;
END LOOP;
WHILE LOOP — condition checked BEFORE each pass
i := 1;
WHILE i <= 5 LOOP
DBMS_OUTPUT.PUT_LINE(i);
i := i + 1;
END LOOP;
BDM | RDBMS – Unit 5
8
Iterative Structures — FOR LOOP
FOR i IN 1..5 LOOP
DBMS_OUTPUT.PUT_LINE(i);
END LOOP;
FOR i IN REVERSE 1..5 LOOP -- counts down: 5, 4, 3, 2, 1
DBMS_OUTPUT.PUT_LINE(i);
END LOOP;
BDM | RDBMS – Unit 5
9
Sequential Control — GOTO & NULL
IF v_marks < 0 THEN
GOTO invalid_marks;
END IF;
...
<<invalid_marks>>
DBMS_OUTPUT.PUT_LINE('Invalid marks entered');
IF v_marks IS NULL THEN
NULL; -- placeholder: do nothing, intentionally
END IF;
BDM | RDBMS – Unit 5
10
5.3 Cursors — Introduction
BDM | RDBMS – Unit 5
11
Implicit Cursors
UPDATE student SET marks = marks + 5 WHERE dept_id = 10;
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' rows updated');
Attribute | Meaning |
SQL%FOUND | TRUE if the last statement affected at least one row |
SQL%NOTFOUND | TRUE if it affected zero rows |
SQL%ROWCOUNT | Number of rows affected |
BDM | RDBMS – Unit 5
12
Explicit Cursors
DECLARE
CURSOR c_student IS SELECT sname, marks FROM student;
v_name student.sname%TYPE;
v_marks student.marks%TYPE;
BEGIN
OPEN c_student;
LOOP
FETCH c_student INTO v_name, v_marks;
EXIT WHEN c_student%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_name || ': ' || v_marks);
END LOOP;
CLOSE c_student;
END;
BDM | RDBMS – Unit 5
13
Cursor FOR Loop & Cursor Attributes
FOR rec IN (SELECT sname, marks FROM student) LOOP
DBMS_OUTPUT.PUT_LINE(rec.sname || ': ' || rec.marks);
END LOOP;
Cursor Attribute | Meaning |
%FOUND | TRUE if the last FETCH returned a row |
%NOTFOUND | TRUE if the last FETCH found no row (used to EXIT) |
%ROWCOUNT | Number of rows fetched so far |
%ISOPEN | TRUE if the cursor is currently open |
BDM | RDBMS – Unit 5
14
5.4 Procedures — Create & Execute
CREATE OR REPLACE PROCEDURE raise_marks (
p_roll IN student.roll_no%TYPE, p_amount IN NUMBER)
IS
BEGIN
UPDATE student SET marks = marks + p_amount WHERE roll_no = p_roll;
COMMIT;
END raise_marks;
EXEC raise_marks(1, 5); -- or: CALL raise_marks(1, 5);
BDM | RDBMS – Unit 5
15
Procedures — IN, OUT & IN OUT Parameters
Mode | Direction | Default? |
IN | Passed INTO the procedure (read-only inside) | Yes — the default mode |
OUT | Passed back OUT to the caller | No — must be stated explicitly |
IN OUT | Value goes in, can be changed, and comes back out | No — must be stated explicitly |
CREATE OR REPLACE PROCEDURE get_marks (
p_roll IN student.roll_no%TYPE, p_marks OUT student.marks%TYPE)
IS
BEGIN
SELECT marks INTO p_marks FROM student WHERE roll_no = p_roll;
END;
BDM | RDBMS – Unit 5
16
5.4 Functions — Create & Execute
CREATE OR REPLACE FUNCTION get_grade (p_marks IN NUMBER)
RETURN VARCHAR2
IS
BEGIN
IF p_marks >= 75 THEN RETURN 'Distinction';
ELSIF p_marks >= 50 THEN RETURN 'Pass';
ELSE RETURN 'Fail';
END IF;
END get_grade;
SELECT sname, get_grade(marks) FROM student;
BDM | RDBMS – Unit 5
17
Procedure vs Function
Procedure | Function |
May or may not return a value | MUST return exactly one value |
Called as a standalone statement (EXEC) | Called inside an expression (e.g. within SELECT) |
Can have IN, OUT, and IN OUT parameters | Typically only IN parameters |
Used to PERFORM an action | Used to COMPUTE and return a value |
BDM | RDBMS – Unit 5
18
5.3 Exception Handling — Predefined Exceptions
Exception | Raised when… |
NO_DATA_FOUND | A SELECT INTO returns zero rows |
TOO_MANY_ROWS | A SELECT INTO returns more than one row |
ZERO_DIVIDE | Dividing a number by zero |
VALUE_ERROR | A value doesn't fit its assigned variable type |
OTHERS | Catches any exception not handled above |
BDM | RDBMS – Unit 5
19
Exception Handling — Example & User-Defined Exceptions
BEGIN
SELECT sname INTO v_name FROM student WHERE roll_no = 999;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No student with that roll number');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Unexpected error: ' || SQLERRM);
END;
DECLARE
invalid_marks EXCEPTION;
BEGIN
IF v_marks > 100 THEN
RAISE invalid_marks;
END IF;
EXCEPTION
WHEN invalid_marks THEN
DBMS_OUTPUT.PUT_LINE('Marks cannot exceed 100');
END;
BDM | RDBMS – Unit 5
20
5.5 Triggers — Fundamentals
CREATE OR REPLACE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name
[FOR EACH ROW]
BEGIN
-- trigger body
END;
BDM | RDBMS – Unit 5
21
Types of Triggers — BEFORE vs AFTER
BEFORE Trigger
AFTER Trigger
BDM | RDBMS – Unit 5
22
Types of Triggers — FOR EACH ROW vs FOR EACH STATEMENT
| FOR EACH ROW | FOR EACH STATEMENT (default) |
Fires | Once per affected row | Once per triggering statement, regardless of row count |
Access to data | Can use :OLD and :NEW to read/modify the row's values | Cannot reference individual row values |
Typical use | Per-row validation, computed columns | One summary audit entry, bulk checks |
BDM | RDBMS – Unit 5
23
Trigger Example — Audit Log
CREATE OR REPLACE TRIGGER trg_salary_audit
AFTER UPDATE OF salary ON employee
FOR EACH ROW
BEGIN
INSERT INTO salary_audit (emp_id, old_salary, new_salary, changed_on)
VALUES (:OLD.emp_id, :OLD.salary, :NEW.salary, SYSDATE);
END;
UPDATE employee SET salary = salary + 2000 WHERE emp_id = 101;
-- trigger fires automatically, inserting one row into salary_audit
BDM | RDBMS – Unit 5
24
Problem Solving Practice
BDM | RDBMS – Unit 5
25
Quick Check: MCQs
1. Which PL/SQL block section is mandatory?
a) DECLARE b) BEGIN c) EXCEPTION d) None are mandatory
2. Which exception fires when SELECT INTO returns no rows?
a) TOO_MANY_ROWS b) NO_DATA_FOUND c) ZERO_DIVIDE d) VALUE_ERROR
3. Which cursor type must be explicitly declared, opened, and closed?
a) Implicit b) Explicit c) Both d) Neither
4. A function differs from a procedure mainly because it:
a) Cannot take parameters b) Must return a value c) Cannot use loops d) Runs faster
5. Which trigger timing can modify the row before it's saved?
a) AFTER b) INSTEAD OF c) BEFORE d) None
BDM | RDBMS – Unit 5
26
Thank You
Bharti D. Mulchandani
Lecturer, Computer Engineering Department
R. C. Technical Institute, Ahmedabad