Day15 PLSQL-1
Day15 PLSQL-1
Utpal/SCA/PL-SQL-1 1
Overview of PL/SQL
Utpal/SCA/PL-SQL-1 2
PL / SQL
PL/SQL is the procedural extension to SQL with design feature
of programming languages.
Data Manipulation and Query statements of SQL are included
within procedural units of code.
Place reusable PL/SQL code in libraries to be shared between
application to all users.
Portability.
Sub-programs are named PL/SQL blocks, declared as either
procedures or functions
Utpal/SCA/PL-SQL-1 3
* Group logically related statements within block.
* You can declare variables.
* You can program with Control Structures, IF-THEN-ELSE, LOOP...
* Error handling functionality.
* Nest sub-block inside large block to build powerful program.
* Single line Comment --
* Multiple line Comments /* */
* A slash ( / ) runs the PL/SQL block.
DECLARE (Optional)
Variables, cursors, user-defined exception
BEGIN (Mandatory)
SQL & PL/SQL statements
EXCEPTION (Optional)
Actions to perform when error occur
END; (Mandatory)
/
Utpal/SCA/PL-SQL-1 4
Anonymous Procedure Function
[DECLARE] PROCEDURE Name FUNCTION Name
IS RETURN Datatype
IS
Utpal/SCA/PL-SQL-1 5
Oracle tools, like Developer, SQL*Plus have their own PL/SQL
engine, which is independent of the engine present in the Oracle Server.
The engine filters out SQL statement and sends them
individually to the SQL statement executor in the Oracle Server.
PL/SQL engine, processes remaining Procedural statements.
PL / SQL engine
PL/SQL PL/SQL Procedural statement
block block executor
Oracle Server
Utpal/SCA/PL-SQL-1 6
Summary
PL/SQL
Block Types
PL/SQL Environment
Utpal/SCA/PL-SQL-1 7
Declaring Variables
Utpal/SCA/PL-SQL-1 8
Use of Variables
Temporary storage of data
Manipulation of stored values
Reusability
Handling Variables
Declare and initialize variable in the declaration section.
Assign new values to variables in the executable section.
View results through output variables
Utpal/SCA/PL-SQL-1 9
Types of Variables
PL / SQL
Scalar (hold a single value) - number, date, binary_integer,
boolean (true, false, null),
timestamp…
Composite (group of value) - records, cursors…
Non - PL / SQL
Bind and host variables - global values
Utpal/SCA/PL-SQL-1 10
* Follow naming conventions.
* Declare one identifier per line.
* Initialize identifiers by using the assignment operator ( := )
identifier [CONSTANT] datatype [NOT NULL]
[ := | DEFAULT expr];
DECLARE
v_hiredate DATE;
v_deptno NUMBER(2) NOT NULL := 10;
v_location VARCHAR2(12) := ‘Atlanta’;
c_comm CONSTANT NUMBER := 1400;
v_count BINARY_INTEGER := 0;
v_total_sal NUMBER(9,2) := 0;
v_orderdate DATE := SYSDATE + 7;
v_valid BOOLEAN NOT NULL := TRUE;
Utpal/SCA/PL-SQL-1 11
* Declare variable according to :
-- A database column definition
-- Another previously declared variable
identifier table.column_name%TYPE ;
DECLARE
v_name employees.last_name%TYPE ;
v_balance NUMBER(7,2);
v_min_balance v_balance%TYPE := 10;
Utpal/SCA/PL-SQL-1 13
Summary
Variables / Identifiers - declared at declarative section
Declaring Variables
%TYPE
LOB
Utpal/SCA/PL-SQL-1 14
Writing Executable Statements
Utpal/SCA/PL-SQL-1 15
DECLARE
x NUMBER;
y NUMBER;
BEGIN
....... Scope of x , y
DECLARE
z NUMBER;
BEGIN
z := x ; Scope of z
END;
.......
y := z ;
END;
<<abc>>
DECLARE
birthdate DATE;
BEGIN
DECLARE
birthdate DATE;
..
abc.birthdate := TO_DATE(‘03-AUG-2004’,’DD-MON-YYYY’);
END;
..
END;
Utpal/SCA/PL-SQL-1 17
To reference a Bind Variable, prefix with colon ( : )
DECLARE
v_sal NUMBER(9,2) := &p_annual_sal;
BEGIN
:g_monthly_sal := v_sal / 12;
END;
/
PRINT g_monthly_sal
Utpal/SCA/PL-SQL-1 18
* Retrieve data from the database with a SELECT statement.
* Queries must return only one row.
SELECT select_list
INTO {variable_name[, variable_name]...
| record_name}
FROM table
[WHERE condition];
SET SERVEROUTPUT ON
DEFINE p_annual_sal = 6000
DECLARE
v_sal NUMBER(9,2) := p_annual_sal;
BEGIN
v_sal := v_sal/12;
DBMS_OUTPUT.PUT_LINE (‘The monthly salary is’ ||
TO_CHAR(v_sal));
END;
/
Utpal/SCA/PL-SQL-1 20
* Display the sum of the salaries for all employees in the specified department.
SET SERVEROUTPUT ON
DECLARE
v_sum_sal NUMBER(10,2);
BEGIN
SELECT sum(salary)
INTO v_sum_sal
FROM employees
WHERE department_id = 30;
DBMS_OUTPUT.PUT_LINE(‘The sum salary is ‘
|| TO_CHAR(v_sum_sal));
END;
/
.. ..
BEGIN
Analyze the result SELECT salary
INTO v_sum_sal
Why ? FROM employees
WHERE department_id = 30;
Utpal/SCA/PL-SQL-1 21
* The following DELETE statement removes all employees,
where last name is not just ‘King’, because Oracle assumes
that both last_name(s) in the WHERE clause refer to the
database column.
DECLARE
last_name VARCHAR2(25) := ‘King’;
BEGIN
DELETE FROM emp_copy
WHERE last_name = last_name ;
END;
Utpal/SCA/PL-SQL-1 22
SET SERVEROUTPUT ON
DECLARE
v_name VARCHAR2(10) := ‘Reynardo’;
v_address VARCHAR2(12) := ‘#9, MG Road’;
v_city VARCHAR2(10) := ‘Bangalore’;
v_zip VARCHAR2(7) := ‘560 006’;
BEGIN
DBMS_OUTPUT.PUT_LINE(v_name || CHR(10) ||
v_address || CHR(10) ||
v_city || CHR(10) ||
v_zip);
END;
v_ename := LOWER(v_ename);
v_date := TO_DATE(‘January 12, 2005’,
‘Month DD, YYYY’);
Utpal/SCA/PL-SQL-1 23
BEGIN
INSERT INTO employees
(employee_id, first_name, last_name, email,
hire_date, job_id, salary)
VALUES ( emp_seq.NEXTVAL , ‘Ruth’, ‘Cores’, ‘RCORES’,
sysdate, ‘AD_ASST’ 9000);
END;
DECLARE
v_sal_inc employees.salary%TYPE := 800;
BEGIN
UPDATE employees
SET salary = salary + v_sal_inc
WHERE job_id = ‘ST_CLERK’;
COMMIT;
END;
DECLARE
v_deptno employees.department_id%TYPE := 80;
BEGIN
DELETE FROM employees
WHERE department_id = v_deptno ;
END;
Utpal/SCA/PL-SQL-1 24
* Cursor is a private SQL work area for each user.
* Two Types :
Implicit Cursor - Automatically created if any SQL statement is executed.
Explicit Cursor - Can Create by programmer.
Utpal/SCA/PL-SQL-1 25
VARIABLE rows_deleted VARCHAR2(30)
DECLARE
v_eid employees.employee_id%TYPE := 176;
BEGIN
DELETE FROM employees
WHERE employee_id = v_eid;
:rows_deleted := (SQL%ROWCOUNT || ‘ rows deleted.’);
END;
/
PRINT rows_deleted
Utpal/SCA/PL-SQL-1 26
DECLARE
v_weight NUMBER(3) := 600;
v_message VARCHAR2(99) := ‘ Product 10012’;
BEGIN
DECLARE
v_weight NUMBER(3) := 1;
v_message VARCHAR2(90) := ‘Product 11001’;
v_new_locn VARCHAR2(50) := ‘Europe’;
BEGIN
v_weight := v_weight + 1;
v_new_locn := ‘Western ‘ || v_new_locn;
1
END;
v_weight := v_weight + 1;
v_message := v_message || ‘ is in stock’;
v_new_locn := ‘Western ‘ || v_new_locn;
2
END;
The value of V_WEIGHT at position 1 -> 2
The value of V_NEW_LOCN at position 1 -> Western Europe
The value of V_WEIGHT at position 2 -> 601
The value of V_MESSAGE at position 2 -> Product 10012 is in stock
The value of V_NEW_LOCN at position 2 -> Illegal because, not visible outside the sub-block
Utpal/SCA/PL-SQL-1 27
Class Exercise 1
<<abc>>
DECLARE
v_sal NUMBER(7,2) := 60000;
v_comm NUMBER(7,2) := v_sal * 0.20;
v_message VARCHAR2(90) := ‘ eligible for commission ’;
BEGIN
DECLARE
v_sal NUMBER(7,2) := 50000;
v_comm NUMBER(7,2) := 0;
v_total_comp NUMBER(7,2) := v_sal * v_comm;
BEGIN
v_message := ‘CLERK not ’|| v_message;
abc.v_comm := v_sal * 0.30;
1
END;
v_message := ‘SALESMAN’ || v_message;
2
END;
The value of V_MESSAGE at position 1 The value of V_TOTAL_COMP at position 2
The value of V_COMM at position 1 The value of V_COMM at position 2
The value of ABC.V_COMM at position 1 The value of V_MESSAGE at position 2
Utpal/SCA/PL-SQL-1 28
Summary
Nested Blocks and Scope Variables
Qualify and Identifier
SELECT statement in PL/SQL
Using Bind Variable
DBMS_OUTPUT.PUT_LINE
Retrieve Data
Naming Convention
Functions in PL/SQL
Insert / Update / Delete
Cursors
Utpal/SCA/PL-SQL-1 29
Control Structures
Utpal/SCA/PL-SQL-1 30
* You can change the logical execution of statements using IF
statements and LOOP control structures
IF condition THEN
statements;
[ELSIF condition THEN
statements;]
[ELSE
statements;]
END IF;
Utpal/SCA/PL-SQL-1 31
Eg., If the last name is Vargas and the salary is more than 6500,
Set the department number to 60.
IF v_ename = ‘Vargas’ AND salary > 6500 THEN
v_deptno := 60;
END IF;
..
Set a Boolean flag to TRUE if the hire date is greater than Five years; other wise, set
the Boolean flag to FALSE.
DECLARE
v_hire_date DATE := ’12-DEC-1990’;
v_five_years BOOLEAN;
BEGIN
IF MONTHS_BETWEEN(sysdate,v_hire_date)/12 > 5 THEN
v_five_years := TRUE;
ELSE
v_five_years := FALSE;
END IF;
END;
/
Utpal/SCA/PL-SQL-1 32
IF condition1 THEN
statements1;
ELSIF condition2 THEN
statements2;
ELSE
statements3;
END IF;
Utpal/SCA/PL-SQL-1 33
CASE expression selects a result and returns it.
SET SERVEROUTPUT ON
DECLARE
v_grade CHAR(1) := ‘A’;
v_appraisal VARCHAR2(20);
BEGIN
v_appraisal := CASE v_grade WHEN ‘A’ THEN ‘Excellent’
WHEN ‘B’ THEN ‘Very Good’
WHEN ‘C’ THEN ‘Good’
ELSE ‘No such grade’
END;
DBMS_OUTPUT.PUT_LINE (‘Grade: ’ || v_grade ||
‘ Appraisal’ || v_appraisal);
END;
/
Utpal/SCA/PL-SQL-1 34
What is the value of V_FLAG in each case ?
Utpal/SCA/PL-SQL-1 35
• LOOPs repeat a statement or sequence of statements multiple times.
• Types of LOOP
Basic LOOP - Perform repetitive actions without overall conditions.
FOR loop - Perform iterative control of actions based on count.
WHILE loop - perform iterative control based on a condition.
Utpal/SCA/PL-SQL-1 36
• A basic LOOP allows execution of its statements atleast once, even if the
condition already met upon entering the loop.
LOOP
statement1;
EXIT [WHEN condition];
END LOOP;
DECLARE
v_country_id locations.country_id%TYPE := ‘CA’;
v_location_id locations.location_id%TYPE;
v_counter NUMBER(2) := 1;
v_city locations.city%TYPE := ‘Montreal’;
BEGIN
SELECT MAX(location_id) INTO v_location_id
FROM locations WHERE country_id = v_country_id;
LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((v_location_id + v_counter),v_city,v_country_id);
v_counter := v_counter + 1;
EXIT WHEN v_counter > 3;
END LOOP;
END;
Utpal/SCA/PL-SQL-1 37
• A WHILE Loop repeats sequence of statements until the controlling
condition is no longer TRUE.
WHILE condition LOOP
statement1..;
END LOOP;
DECLARE
v_country_id locations.country_id%TYPE := ‘CA’;
v_location_id locations.location_id%TYPE;
v_counter NUMBER(2) := 1;
v_city locations.city%TYPE := ‘Washington’;
BEGIN
SELECT MAX(location_id) INTO v_location_id
FROM locations WHERE country_id = v_country_id;
WHILE v_counter <= 3 LOOP
INSERT INTO locations(location_id, country_id)
VALUES((v_location_id + v_counter),v_city,v_country_id);
v_counter := v_counter + 1;
END LOOP;
END;
Utpal/SCA/PL-SQL-1 38
• A FOR Loop is used to test for the number of iterations.
FOR counter IN [REVERSE] lower_bound..upper_bound LOOP
statement1..;
statement2..; Implicitly j IN -5..5
declared k IN REVERSE first..last
END LOOP;
step IN 0..TRUNC(high/low) * 2
DECLARE
v_country_id locations.country_id%TYPE := ‘CA’;
v_location_id locations.location_id%TYPE;
v_city locations.city%TYPE := ‘Paris’;
BEGIN
SELECT MAX(location_id) INTO v_location_id
FROM locations WHERE country_id = v_country_id;
FOR i IN 1..3 LOOP
INSERT INTO locations(location_id, country_id)
VALUES((v_location_id + i), v_city, v_country_id);
v_counter := v_counter + 1;
END LOOP;
END;
Utpal/SCA/PL-SQL-1 39
Specify a different increment (5 instead of 1 for example). Inside the FOR loop, simply
multiply each reference to the loop counter by the new increment. In the following
example, you assign today's date to elements 5, 10, and 15 of an index-by table:
DECLARE
TYPE DateList IS TABLE OF DATE INDEX BY BINARY_INTEGER;
dates DateList;
k CONSTANT INTEGER := 5; -- set new increment
BEGIN
FOR j IN 1..3 LOOP
dates(j*k) := SYSDATE; -- multiply loop counter by increment
END LOOP;
...
END;
FOR ctr IN 1..10 LOOP
IF NOT finished THEN
INSERT INTO ... VALUES (ctr, ...); -- OK
factor := ctr * 2; -- OK
ELSE
ctr := 10; -- not allowed
END IF;
END LOOP;
Utpal/SCA/PL-SQL-1 40
• Nest loops to multiple levels.
• Use labels to distinguish between blocks and loops.
• Exit the outer loop with the EXIT statement that references the label.
.. .. ..
BEGIN
<<Outer_loop>>
LOOP
v_counter := v_counter + 1;
EXIT WHEN v_counter > 10; -- leaves both loops
<<Inner_loop>>
LOOP
...
EXIT Outer_loop WHEN total_done = ‘YES’;
-- leaves both loops
EXIT WHEN inner_done = ‘YES’;
-- leaves inner loop only
.. ..
END LOOP Inner_loop;
.. ..
END LOOP Outer_loop;
END;
Utpal/SCA/PL-SQL-1 41
Utpal/SCA/PL-SQL-1 42
• Create the MESSAGES table with column results varchar2(60)
• Insert the numbers 1 to 10 excluding 6 and 8
• Commit before the end of the block
BEGIN
FOR i IN 1..10 LOOP
IF i = 6 or i = 8 THEN
null;
ELSE
INSERT INTO messages(results)
VALUES (i);
END IF;
COMMIT;
END LOOP;
END;
/
Utpal/SCA/PL-SQL-1 43
Summary
LOOP IF condition1 THEN
statement1; statements1;
EXIT [WHEN condition]; ELSIF condition2 THEN
END LOOP; statements2;
ELSE
statements3;
END IF;
CASE
WHILE condition LOOP
statement1..;
BOOLEAN
END LOOP;