3 2 1
INTRODUCTION TO PL/SQL
About PL/SQL
PL/SQL:
Stands for Procedural Language extension to SQL Is Oracle Corporations standard data access language for relational databases Seamlessly integrates procedural constructs with SQL
About PL/SQL
PL/SQL
Provides a block structure for executable units of code. Maintenance of code is made easier with such a welldefined structure. Provides procedural constructs such as:
Variables, constants, and data types Control structures such as conditional statements and loops Reusable program units that are written once and executed many times
PL/SQL Run-Time Architecture
PL/SQL block procedural
Procedural statement executor PL/SQL SQL
PL/SQL Engine
Oracle Server
SQL statement executor
Benefits of PL/SQL
Integration of procedural constructs with SQL Improved performance
SQL 1 SQL 2
SQL IF...THEN SQL ELSE SQL END IF; SQL
Benefits
Modularization
Portability
BENEFITS of PL/SQL
Exception Handling
Integration
With
Oracle tools
PL/SQL Block Structure
DECLARE (optional)
Variables, cursors, user-defined exceptions
BEGIN (mandatory)
SQL statements PL/SQL statements
EXCEPTION (optional)
Actions to perform when exceptions occur
END; (mandatory)
Block Types
Procedure
PROCEDURE name IS BEGIN --statements [EXCEPTION] END;
Function
FUNCTION name RETURN datatype IS BEGIN --statements RETURN value; [EXCEPTION] END;
Anonymous
[DECLARE]
BEGIN --statements [EXCEPTION] END;
Program Constructs
Tools Constructs Anonymous blocks Application procedures or functions Application packages Application triggers Object types
Database Server Constructs Anonymous blocks Stored procedures or functions Stored packages Database triggers Object types
Examining an Anonymous Block
An anonymous block in the SQL Developer workspace:
Executing an Anonymous Block
Click the Run Script button to execute the anonymous block: Run Script (or F5)
Enabling Output of a PL/SQL Block
1. To enable output in SQL Developer, execute the following command before running the PL/SQL block:
SET SERVEROUTPUT ON
2. Use a predefined Oracle package and its procedure in the anonymous block:
DBMS_OUTPUT.PUT_LINE DBMS_OUTPUT.PUT_LINE (' The First Name of the Employee is ' || v_fname) ;
Identifiers
Declaring PL/SQL Variables
Use of Variables
Variables can be used for:
Temporary storage of data Manipulation of stored values Reusability
SELECT order_id, order_status INTO v_id, v_status FROM
2854
v_id
v_status
Requirements for Variable Names
A Variable name:
Must start with a letter Can include letters or numbers Can include special characters (such as $, _, and #) Must contain no more than 30 characters Must not include reserved words
Handling Variables in PL/SQL
Variables are:
Declared and (optionally) initialized in the declarative section Used and assigned new values in the executable section Passed as parameters to PL/SQL subprograms Used to hold the output of a PL/SQL subprogram
Declaring and Initializing PL/SQL Variable
identifier [ CONSTANT ] datatype [NOT NULL ] Syntax: [ := | DEFAULT expr ] ;
Examples:
DECLARE v_hiredate v_deptno v_location c_comm
DATE ; NUMBER(2) NOT NULL := 10 ; VARCHAR2(13) := Atlanta ; CONSTANT NUMBER := 1400 ;
Declaring and Initializing PL/SQL Variables
DECLARE v_myName VARCHAR2(20) ; BEGIN DBMS_OUTPUT.PUT_LINE ('My name is: ' || v_myName) ; v_myName := ' John ' ; DBMS_OUTPUT.PUT_LINE( ' My name is: ' || v_myName) ; END ; / DECLARE v_myName VARCHAR2(20) := ' John ' ; BEGIN v_myName := ' Steven ' ; DBMS_OUTPUT.PUT_LINE ( ' My name is: ' || v_myName) ; END ; /
Guidelines for Declaring and Initializing PL/SQL Variables
Follow consistent naming conventions. Use meaningful identifiers for variables. Initialize variables that are designated as NOT NULL and CONSTANT. Initialize variables with the assignment operator (:=) or the DEFAULT keyword:
v_myName VARCHAR2 (20) := 'John' ; v_myName VARCHAR2( 20) DEFAULT 'John' ;
Declare one identifier per line for better readability and code maintenance.
Base Scalar Data Types
CHAR [(maximum_length)] VARCHAR2 (maximum_length) NUMBER [(precision, scale)] BINARY_INTEGER PLS_INTEGER BOOLEAN BINARY_FLOAT BINARY_DOUBLE
10
Base Scalar Data Types
DATE TIMESTAMP TIMESTAMP WITH TIME ZONE TIMESTAMP WITH LOCAL TIME ZONE INTERVAL YEAR TO MONTH INTERVAL DAY TO SECOND
Declaring Scalar Variables
Examples:
DECLARE v_orderid v_count_loop v_ordr_total v_orderdate v_orderMode v_valid ... NUMBERR2 (9) ; BINARY_INTEGER := 0 ; NUMBER (9,2) := 0 ; DATE := SYSDATE + 7 ; VARCHAR2 (10) ; BOOLEAN NOT NULL := TRUE ;
11
%TYPE Attribute
Is used to declare a variable according to:
A database column definition Another declared variable
Is prefixed with:
The database table and column name The name of the declared variable
Declaring Variables with the %TYPE Attribute
Syntax
identifier
table.column_name%TYPE ;
Examples
... v_order_id ... ... v_status v_customerid ... orders.order_id%TYPE ;
NUMBER(2) ; v_status%TYPE := 00 ;
12
Declaring Boolean Variables
Only the TRUE, FALSE, and NULL values can be assigned to a Boolean variable. Conditional expressions use the logical operators AND and OR, and the unary operator NOT to check the variable values. The variables always yield TRUE, FALSE, or NULL. Arithmetic, character, and date expressions can be used to return a Boolean value.
Identifiers
Writing Executable Statements
13
Commenting Code
Prefix single-line comments with two hyphens (--). Place a block comment between the symbols /* and */.
Example:
DECLARE ... v_annual_sal NUMBER (9,2) ; BEGIN /* Compute the annual salary based on the monthly salary input from the user */ v_annual_sal := monthly_sal * 12 ; --The --The following line displays the annual salary DBMS_OUTPUT.PUT_LINE (v_annual_sal) ; END ; /
SQL Functions in PL/SQL
Available in procedural statements:
Single-row functions
Not available in procedural statements:
DECODE Group functions
14
SQL Functions in PL/SQL: Examples
Get the length of a string:
v_desc_size INTEGER (5) ; v_prod_description VARCHAR2 (70) := 'You can use this product with your radios for higher frequency' ; -- get the length of the string in prod_description v_desc_size := LENGTH (v_prod_description) ;
Get the number of months an employee has worked:
v_tenure := MONTHS_BETWEEN (CURRENT_DATE, v_hiredate) ;
Data Type Conversion
Converts data to comparable data types Is of two types:
Implicit conversion Explicit conversion
Functions:
TO_CHAR TO_DATE TO_NUMBER TO_TIMESTAMP
15
Data Type Conversion
-- implicit data type conversion v_date_of_joining DATE := '02'02-FebFeb-2000' ; -- error in data type conversion v_date_of_joining DATE := 'February 02,2000 ;
-- explicit data type conversion v_date_of_joining DATE := TO_DATE( 'February 02,2000' Month DD, YYYY') ;
Nested Blocks
PL/SQL blocks can be nested.
An executable section (BEGIN END) can contain nested blocks. An exception section can contain nested blocks.
16
Nested Blocks: Example
DECLARE v_outer_variable VARCHAR2(20):='GLOBAL VARIABLE'; BEGIN DECLARE v_inner_variable VARCHAR2(20):='LOCAL VARIABLE'; BEGIN DBMS_OUTPUT.PUT_LINE(v_inner_variable); DBMS_OUTPUT.PUT_LINE(v_outer_variable); END; DBMS_OUTPUT.PUT_LINE(v_outer_variable); END;
Operators in PL/SQL
Logical Same as in SQL Arithmetic Concatenation Parentheses to control order of operations Exponential operator (**)
17
Operators in PL/SQL: Examples
Increment the counter for a loop.
loop_count := loop_count + 1 ;
Set the value of a Boolean flag.
good_sal := sal BETWEEN 50000 AND 150000 ;
Validate whether an employee number contains a value.
Valid := (empno IS NOT NULL) ;
Control Structures
Conditional Control: IF Statements Iterative Control: LOOP and EXIT Statements Sequential Control: GOTO and NULL Statements
18
Control Structures
Conditional Control: IF Statements
To take alternative actions depending on circumstances Three forms of IF statements IF-THEN IF-THEN-ELSE IF-THEN-ELSIF IF-THEN
IF condition THEN sequence_of_statements END IF;
Example:
IF sales > quota THEN compute_bonus(empid); UPDATE payroll SET pay = pay + bonus WHERE emp_id = emp_id; END IF; IF x > y THEN high := x; END IF;
Control Structures
IF-THEN-ELSE IF condition THEN sequence_of_statements1 ELSE sequence_of_statements2 END IF; Example: IF trans_type = 'CR' THEN UPDATE accounts SET balance = balance + credit WHERE ... ELSE UPDATE accounts SET balance = balance - debit WHERE ... END IF;
19
Control Structures
IF-THEN-ELSE IF statements can be nested Example: IF trans_type = 'CR' THEN UPDATE accounts SET balance = balance + credit WHERE ... ELSE IF new_balance >= minimum_balance THEN UPDATE accounts SET balance = balance - debit WHERE ... ELSE RAISE insufficient_funds; END IF; END IF;
Control Structures
IF-THEN-ELSIF
IF condition1 THEN sequence_of_statements1 ELSIF condition2 THEN sequence_of_statements2 ELSE sequence_of_statements3 END IF;
Example:
BEGIN IF sales > 50000 THEN bonus := 1500; ELSIF sales > 35000 THEN bonus := 500; ELSE bonus := 100; END IF; INSERT INTO payroll VALUES (emp_id, bonus, ...); END;
20
Control Structures
Iterative Control: LOOP and EXIT Statements
Loop: The simplest form of LOOP
LOOP sequence_of_statements END LOOP;
Exit: The EXIT statement forces a loop to complete unconditionally
LOOP ... IF credit_rating < 3 THEN ... EXIT; -- exit loop immediately END IF; END LOOP; -- control resumes here
Control Structures
EXIT-WHEN EXIT-WHEN statement allows a loop to complete conditionally
LOOP FETCH c1 INTO ... EXIT WHEN c1%NOTFOUND; ... END LOOP; CLOSE c1;
-- exit loop if condition is true
EXIT-WHEN statement replaces a simple IF statement
IF count > 100 THEN EXIT; END IF; | | | EXIT WHEN count > 100;
21
Control Structures
Loop Labels
An undeclared identifier enclosed by double angle brackets must appear at the beginning of the LOOP statement
<<outer>> LOOP ... LOOP ... EXIT outer WHEN ... END LOOP; ... END LOOP outer;
-- exit both loops
Control Structures
WHILE-LOOP
WHILE-LOOP statement associates a condition with a sequence of statements enclosed by the keywords LOOP and END LOOP
WHILE condition LOOP sequence_of_statements END LOOP; WHILE total <= 25000 LOOP ... SELECT basicsal INTO salary FROM emp WHERE ... total := total + salary; END LOOP;
22
Control Structures
FOR-Loop
FOR loops iterate over a specified range of integers
FOR counter IN [REVERSE] lower_bound..higher_bound LOOP sequence_of_statements END LOOP;
Example:
DECLARE x NUMBER := 100; BEGIN FOR i IN 1..10 LOOP IF MOD(i,2) = 0 THEN -- i is even INSERT INTO temp VALUES (i, x,first, 'i is even'); ELSE INSERT INTO temp VALUES (i, x, second,'i is odd'); END IF; x := x + 100; END LOOP; COMMIT; END;
Interaction with Oracle Using PL/SQL Variables
DECLARE countryid country.country_id%TYPE; countryname country.country_name%TYPE; ID country.country_id%TYPE; BEGIN SELECT * INTO countryid, countryname FROM COUNTRY WHERE COUNTRY_ID = &ID; DBMS_OUTPUT.PUT_LINE ('Country ID: ' || COUNTRYID); DBMS_OUTPUT.PUT_LINE ('Name: ' || COUNTRYNAME); END;
23
Interaction with Oracle Using PL/SQL ROWTYPE Variables
DECLARE country_rec COUNTRY%ROWTYPE; ID COUNTRY706.COUNTRY_ID%TYPE :=&1; BEGIN SELECT * INTO country_rec FROM COUNTRY706 WHERE COUNTRY_ID = ID; DBMS_OUTPUT.PUT_LINE (country_rec.COUNTRY_ID); DBMS_OUTPUT.PUT_LINE(country_rec.COUNTRY_NAME); END;
Example - 1
Retrieve all the columns of particular employee
Declare V_eno number(4); V_name varchar2(15); V_job varchar2(10); V_mgr number(4); V_hiredate date; V_sal number(7,2); V_comm number(7,2); V_dno number(2); Begin Select * Into v_eno,v_ename,v_job,v_mgr,v_hiredate,v_sal, v_comm,v_dno
48
24
%ROWTYPE
Declare myemp emp%rowtype; Begin select * into myemp . if (myemp.comm is not null) then Structure of emp table is referred and copied to variable myemp. To access the variables use rowtype variable and name of the column. i.e.,myemp.comm
49
Record Type
User defined, customized data type Like structures in C Collection of various members Create the Data type and declare record variable which refers the user defined record type
50
25
Record Type - Example
DECLARE TYPE my_data is RECORD (ename emp.ename%TYPE, dname dept.dname%TYPE); my_emp my_data; BEGIN SELECT ename,dname INTO my_emp FROM emp,dept WHERE emp.deptno=dept.deptno AND empno=&ENO; dbms_output.put_line(my_emp.ename ||my_emp.dname); END;
51
Record Type - Example
TYPE WBP IS RECORD (LTA NUMBER(7,2), HRA NUMBER(7,2), fon NUMBER(7,2)); my_allowance WBP; -- declare variable of record type WBP BEGIN my_allowance.LTA:=3000; my_allowance.fon:=2000;
52
26
Interaction with Oracle Using Cursor
DECLARE countryid COUNTRY.COUNTRY_ID%TYPE; countryname COUNTRY.COUNTRY_NAME%TYPE; CURSOR c1 IS SELECT country_id, country_name FROM COUNTRY; BEGIN OPEN c1; LOOP FETCH C1 into countryid, countryname; EXIT WHEN c1%NOTFOUND; DBMS_OUTPUT.PUT_LINE ('ID: '|| countryid); DBMS_OUTPUT.PUT_LINE ('Name: '|| countryname); END LOOP; DBMS_OUTPUT.PUT_LINE (c1%ROWCOUNT); CLOSE c1; END;
Code Analysis Using PL/SQL Cursor
An anonymous PL/SQL block This is an explicit cursor Declaration CURSOR c1 Tells oracle to declare a cursor, and have the output of the query in this cursor OPEN c1 Opens the cursor for traversal FETCH c1 Selects the record one by one into PL/SQL variables CLOSE c1 Closes the cursor c1%ROWCOUNT Returns count of rows c1%NOTFOUND Returns false, when there are no records to be traversed, else returns true
OPEN, FETCH, CLOSE this is too muchisnt there a simpler way to do it ???
27
Interaction with Oracle Using Cursor For Loop
DECLARE CURSOR c1 IS SELECT country_id, country_name FROM COUNTRY; BEGIN FOR COUNTRY_REC IN C1 LOOP DBMS_OUTPUT.PUT_LINE(COUNTRY_REC.country_id); DBMS_OUTPUT.PUT_LINE(COUNTRY_REC.country_name); END LOOP; END;
Code Analysis Using Cursor For Loop
This is an explicit cursor Cursor For Loop Declaration FOR COUNTRY_REC IN c1
Declares loop index as %ROWTYPE record Opens a cursor Repeatedly fetches record in the index variable Closes the cursor when there are no further records to be processed
28
Interaction with Oracle Using Parametrized Cursor
DECLARE CURSOR c1 (ID country.country_id%TYPE) IS SELECT * FROM COUNTRY WHERE COUNTRY_ID = ID; BEGIN FOR COUNTRY_REC IN C1 (&ID) LOOP DBMS_OUTPUT.PUT_LINE(COUNTRY_REC.country_id); DBMS_OUTPUT.PUT_LINE(COUNTRY_REC.country_name); END LOOP; END;
Interaction with Oracle Using Implicit Cursor
DECLARE countryid country.country_id%TYPE; countryname country.country_name%TYPE; ID country.country_id%TYPE; BEGIN SELECT * INTO countryid, countryname FROM COUNTRY WHERE COUNTRY_ID = &ID; DBMS_OUTPUT.PUT_LINE ('Country ID: ' || COUNTRYID); DBMS_OUTPUT.PUT_LINE ('Name: ' || COUNTRYNAME); IF SQL%FOUND THEN DBMS_OUTPUT.PUT_LINE ('Data found'); END IF; END;
29
Interaction with Oracle Using Cursor Variables
Cursor Variables
A cursor variable points to the current row in the result set of a multi-row query A cursor is static, a cursor variable is dynamic Declaring a cursor variable creates a pointer A cursor variable has data type REF CURSOR Cursor variables are used to pass query result sets between PL/SQL stored subprograms and various clients
Declaring Cursor Variables
DECLARE --define record variable dept_rec dept%ROWTYPE; --define a REF CURSOR type TYPE cur_dept IS REF CURSOR RETURN dept_rec%type; -- declare cursor variable dept_cv cur_dept;
Interaction with Oracle Using Cursor Variables
Opening a Cursor Variable
BEGIN OPEN dept_cv FOR SELECT * FROM dept; END
Fetching from a Cursor Variable
LOOP
/* Fetch from cursor variable. */ FETCH dept_cv INTO dept_rec; DBMS_OUTPUT.PUT_LINE(dept_rec.deptno); EXIT WHEN dept_cv%NOTFOUND; -- exit when last row is fetched -- process data record END LOOP;
Closing a Cursor Variable
CLOSE dept_cv;
30
Cursor Attributes
%FOUND %NOTFOUND %ISOPEN %ROWCOUNT %ROWTYPE
Example
Declare Cursor my_cur IS Select * from emp where deptno=10 FOR UPDATE; current_rec my_cur%rowtype; Begin . FETCH my_cur INTO current_rec; update emp set comm=1000 WHERE CURRENT OF my_cur;
62
31
Exceptions
Calling procedure Called procedure
PROCEDURE PROC1 ... IS ... BEGIN ... PROC2(arg1); ... EXCEPTION ... END PROC1;
PROCEDURE PROC2 ... IS ... BEGIN ... EXCEPTION ... END PROC2;
Control returns to calling procedure
Exception raised Exception handled
10-63
Exception Block
Syntax . EXCEPTION WHEN name_of_exception1 THEN handler PL/SQL statements WHEN name_of_exception2 THEN handler END;
64
32
Exception
Any PL/SQL block can have its own exception block Exception block contains Name of the exception thrown HANDLER explains the actions to be performed when error occur Exception is not going to solve the current error condition.
65
Need for Exception
When Error occurs Abruptly stop executing the current block ROLLBACK If Exception is Handled Stops the current process Saves the process done so far Transfer the control to exception handler Smooth Transition from error condition to end of program
66
33
Types of Exception
Exception
Pre-defined Exception
Userdefined
NonPredefined Exception
67
Pre-defined Exceptions
PL/SQL defined exceptions Sensed and mapped to the corresponding exception handler automatically User has to DEFINE it - handler No need to DECLARE and INVOKE
No_data_found Invalid_number Zero_divide Cursor_already_open Dup_val_on_index Too_many_rows
68
34
Example
DECLARE v_empno EMP.EMPNO%TYPE; BEGIN
Will this get inserted in database?
INSERT INTO DEPT VALUES(55,Operations,NY); SELECT empno INTO v_empno FROM emp WHERE ename=ABC; DBMS_OUTPUT.PUT_LINE (v_empno); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE (no employee found); END;
Will this get printed?
69
WHEN OTHERS
Unhandled exception can be trapped in the OTHERS category
Example .. EXCEPTION .. WHEN OTHERS THEN DBMS_OUTPUT,PUT_LINE (SQLCODE); DBMS_OUTPUT,PUT_LINE (SQLERRM); END;
When PL/SQL senses exception, handler is searched. If specific handler is not found OTHERS handler is executed Use SQLCODE & SQLERRM to print the error code and message
70
35
User defined Exception
Designed by user as error Kind of Logical error Manager getting commission > 500 is invalid User has to DECLARE DEFINE & INVOKE
71
User defined Exception
In Declaration Block - DECLARE Exception_name EXCEPTION; In Exception Block DEFINE WHEN Exception_name THEN Handler In Execution Block INVOKE RAISE Exception_name
72
36
Example
DECLARE v_comm EMP.comm%TYPE; v_job EMP.job%TYPE; invalid_commisn EXCEPTION; BEGIN IF (v_job=MANAGER AND v_comm>500) THEN RAISE invalid_commisn; END IF; .. EXCEPTION WHEN invalid_commisn THEN . END;
73
RAISE APPLICATION ERROR
Used to print user defined error message
. RAISE_APPLICATION_ERROR(-20010,'Check Constraint Violation'); ERROR at line 1: ORA-20010: Check Constraint Violation
74
37
Creating Procedures
10-75
Creating a Modularized Subprogram Design
1
xx xxx xxx xx xxx xxx ----- --- ------- --- --xx xxx xxx xx xxx xxx ----- --- ---
3 2
xx xxx xxx xx xxx xxx P P ----- --- ------- --- --P ----- --- ---
Modularize code into subprograms.
Locate code sequences repeated more that once. Create subprogram P containing the repeated code Modify original code to invoke the new subprogram.
10-76
38
Creating a Layered Subprogram Design
Create subprogram layers for your application.
Data access subprogram layer with SQL logic Business logic subprogram layer, which may or may not use the data access layer
10-77
Modularizing Development with PL/SQL Blocks
PL/SQL is a block-structured language. The PL/SQL code block helps modularize code by using:
Anonymous blocks Procedures and functions Packages Database triggers Easy maintenance Improved data security and integrity Improved performance Improved code clarity
The benefits of using modular program constructs are:
10-78
39
What Are PL/SQL Subprograms?
A PL/SQL subprogram is a named PL/SQL block that can be called with a set of parameters. You can declare and define a subprogram within either a PL/SQL block or another subprogram. A subprogram consists of a specification and a body. A subprogram can be a procedure or a function. Typically, you use a procedure to perform an action and a function to compute and return a value. Subprograms can be grouped into PL/SQL packages.
10-79
The Benefits of Using PL/SQL Subprograms
Easy maintenance
Improved data security and integrity
Subprograms: Stored procedures and functions
Improved code clarity
Improved performance
10-80
40
Differences Between Anonymous Blocks and Subprograms
Anonymous Blocks
Unnamed PL/SQL blocks Compiled every time Not stored in the database Cannot be invoked by other applications Do not return values Cannot take parameters
Subprograms
Named PL/SQL blocks Compiled only once Stored in the database Named and, therefore, can be invoked by other applications Subprograms called functions must return values. Can take parameters
10-81
What Are Procedures?
Are a type of subprogram that perform an action Can be stored in the database as a schema object Promote reusability and maintainability
Procedures
10-82
41
Creating Procedures: Overview
View errors/warnings in SQL Developer
YES
Use SHOW ERRORS command in SQL*Plus Create/edit procedure Compiler warnings/errors? View compiler warnings/errors
NO
Use USER/ALL/DBA_ ERRORS views
Execute procedure
10-83
Creating Procedures with the SQL CREATE OR REPLACE Statement
Use the CREATE clause to create a stand-alone procedure that is stored in the Oracle database. Use the OR REPLACE option to overwrite an existing procedure. CREATE [OR REPLACE] PROCEDURE procedure_name [(parameter1 [mode] datatype1, parameter2 [mode] datatype2, ...)] IS|AS [local_variable_declarations; ...] BEGIN PL/SQL block -- actions; END [procedure_name];
10-84
42
What Are Parameters and Parameter Modes?
Are declared after the subprogram name in the PL/SQL header Pass or communicate data between the calling environment and the subprogram Are used like local variables but are dependent on their parameterpassing mode:
An IN parameter mode (the default) provides values for a subprogram to process An OUT parameter mode returns a value to the caller An IN OUT parameter mode supplies an input value, which may be returned (output) as a modified value
10-85
Formal and Actual Parameters
Formal parameters: Local variables declared in the parameter list of a subprogram specification Actual parameters (or arguments): Literal values, variables, and expressions used in the parameter list of the calling subprogram
-- Procedure definition, Formal_parameters CREATE PROCEDURE raise_sal(p_id NUMBER, p_sal NUMBER) IS BEGIN . . . END raise_sal; -- Procedure calling, Actual parameters (arguments) v_emp_id := 100; raise_sal(v_emp_id, 2000)
10-86
43
Procedural Parameter Modes
Parameter modes are specified in the formal parameter declaration, after the parameter name and before its data type. The IN mode is the default if no mode is specified.
CREATE PROCEDURE proc_name(param_name [mode] datatype) ...
Modes
IN (default)
Calling environment
OUT IN OUT
Procedure
10-87
Comparing the Parameter Modes
IN
Default mode Value is passed into subprogram Formal parameter acts as a constant Actual parameter can be a literal, expression, constant, or initialized variable Can be assigned a default value
OUT
Must be specified Value is returned to the calling environment Uninitialized variable
IN OUT
Must be specified Value passed into subprogram; value returned to calling environment Initialized variable
Must be a variable
Must be a variable
Cannot be assigned a default value
Cannot be assigned a default value
10-88
44
Using the IN Parameter Mode: Example
CREATE OR REPLACE PROCEDURE raise_salary (p_id IN employees.employee_id%TYPE, p_percent IN NUMBER) IS BEGIN UPDATE employees SET salary = salary * (1 + p_percent/100) WHERE employee_id = p_id; END raise_salary; /
EXECUTE raise_salary(176, 10)
10-89
Using the OUT Parameter Mode: Example
CREATE OR REPLACE PROCEDURE query_emp IN employees.employee_id%TYPE, (p_id p_name OUT employees.last_name%TYPE, p_salary OUT employees.salary%TYPE) IS BEGIN SELECT last_name, salary INTO p_name, p_salary FROM employees WHERE employee_id = p_id; END query_emp; / SET SERVEROUTPUT ON DECLARE v_emp_name employees.last_name%TYPE; v_emp_sal employees.salary%TYPE; BEGIN query_emp(171, v_emp_name, v_emp_sal); DBMS_OUTPUT.PUT_LINE(v_emp_name||' earns '|| to_char(v_emp_sal, '$999,999.00')); END; /
10-90
45
Using the IN OUT Parameter Mode: Example
Calling environment p_phone_no (before the call) '8006330575' p_phone_no (after the call) '(800) 633-0575'
CREATE OR REPLACE PROCEDURE format_phone (p_phone_no IN OUT VARCHAR2) IS BEGIN p_phone_no := '(' || SUBSTR(p_phone_no,1,3) || ') ' || SUBSTR(p_phone_no,4,3) || '-' || SUBSTR(p_phone_no,7); END format_phone; /
10-91
Viewing the OUT Parameters: Using the DBMS_OUTPUT.PUT_LINE Subroutine
Use PL/SQL variables that are printed with calls to the DBMS_OUTPUT.PUT_LINE procedure. SET SERVEROUTPUT ON DECLARE v_emp_name employees.last_name%TYPE; v_emp_sal employees.salary%TYPE; BEGIN query_emp(171, v_emp_name, v_emp_sal); DBMS_OUTPUT.PUT_LINE('Name: ' || v_emp_name); DBMS_OUTPUT.PUT_LINE('Salary: ' || v_emp_sal); END;
10-92
46
Viewing OUT Parameters: Using SQL*Plus Host Variables
1. 2. 3.
Use SQL*Plus host variables. Execute QUERY_EMP using host variables. Print the host variables.
VARIABLE b_name VARCHAR2(25) VARIABLE b_sal NUMBER EXECUTE query_emp(171, :b_name, :b_sal) PRINT b_name b_sal
10-93
Available Notations for Passing Actual Parameters
When calling a subprogram, you can write the actual parameters using the following notations: Positional: Lists the actual parameters in the same order as the formal parameters Named: Lists the actual parameters in arbitrary order and uses the association operator (=>) to associate a named formal parameter with its actual parameter Mixed: Lists some of the actual parameters as positional and some as named Prior to Oracle Database 11g, only the positional notation is supported in calls from SQL Starting in Oracle Database 11g, named and mixed notation can be used for specifying arguments in calls to PL/SQL subroutines from SQL statements
10-94
47
Passing Actual Parameters: Creating the add_dept Procedure
CREATE OR REPLACE PROCEDURE add_dept( p_name IN departments.department_name%TYPE, p_loc IN departments.location_id%TYPE) IS BEGIN INSERT INTO departments(department_id, department_name, location_id) VALUES (departments_seq.NEXTVAL, p_name , p_loc ); END add_dept; /
10-95
Passing Actual Parameters: Examples
-- Passing parameters using the positional notation. EXECUTE add_dept ('TRAINING', 2500)
-- Passing parameters using the named notation. EXECUTE add_dept (p_loc=>2400, p_name=>'EDUCATION')
10-96
48
Using the DEFAULT Option for the Parameters
Defines default values for parameters Provides flexibility by combining the positional and named parameter-passing syntax
CREATE OR REPLACE PROCEDURE add_dept( p_name departments.department_name%TYPE:='Unknown', p_loc departments.location_id%TYPE DEFAULT 1700) IS BEGIN INSERT INTO departments (department_id, department_name, location_id) VALUES (departments_seq.NEXTVAL, p_name, p_loc); END add_dept; EXECUTE add_dept EXECUTE add_dept ('ADVERTISING', p_loc => 1200) EXECUTE add_dept (p_loc => 1200)
10-97
Calling Procedures
You can call procedures using anonymous blocks, another procedure, or packages. You must own the procedure or have the EXECUTE privilege.
CREATE OR REPLACE PROCEDURE process_employees IS CURSOR cur_emp_cursor IS SELECT employee_id FROM employees; BEGIN FOR emp_rec IN cur_emp_cursor LOOP raise_salary(emp_rec.employee_id, 10); END LOOP; COMMIT; END process_employees; /
10-98
49
Removing Procedures: Using the DROP
Using the DROP statement:
DROP PROCEDURE raise_salary;
-Using SQL Developer
2 1 3
10-99
Viewing Procedure Information Using the Data Dictionary Views
DESCRIBE user_source
SELECT text FROM user_source WHERE name = 'ADD_DEPT' AND type = 'PROCEDURE' ORDER BY line;
10-100
50
Creating Functions
11-101
Overview of Stored Functions
A function:
Is a named PL/SQL block that returns a value Can be stored in the database as a schema object for repeated execution Is called as part of an expression or is used to provide a parameter value for another subprogram Can be grouped into PL/SQL packages
11-102
51
Creating Functions
The PL/SQL block must have at least one RETURN statement.
CREATE [OR REPLACE] FUNCTION function_name [(parameter1 [mode1] datatype1, . . .)] RETURN datatype IS|AS [local_variable_declarations; . . .] BEGIN PL/SQL Block -- actions; RETURN expression; END [function_name];
11-103
Creating and Running Functions
View errors/warnings in SQL Developer
YES
Use SHOW ERRORS command in SQL*Plus Create/edit function Compiler warnings/errors? View compiler warnings/errors
NO
Use USER/ALL/DBA_ ERRORS views
Invoke function
11-104
52
Creating and Invoking a Stored Function Using the CREATE FUNCTION Statement: Example
CREATE OR REPLACE FUNCTION get_sal (p_id employees.employee_id%TYPE) RETURN NUMBER IS v_sal employees.salary%TYPE := 0; BEGIN SELECT salary INTO v_sal FROM employees WHERE employee_id = p_id; RETURN v_sal; END get_sal; / -- Invoke the function as an expression or as -- a parameter value. EXECUTE dbms_output.put_line(get_sal(100))
11-105
Using Different Methods for Executing Functions
-- As a PL/SQL expression, get the results using host variables VARIABLE b_salary NUMBER EXECUTE :b_salary := get_sal(100)
-- As a PL/SQL expression, get the results using a local -- variable SET SERVEROUTPUT ON DECLARE sal employees.salary%type; BEGIN sal := get_sal(100); DBMS_OUTPUT.PUT_LINE('The salary is: '|| sal); END; /
11-106
53
Using Different Methods for Executing Functions
-- Use as a parameter to another subprogram EXECUTE dbms_output.put_line(get_sal(100))
-- Use in a SQL statement (subject to restrictions) SELECT job_id, get_sal(employee_id) FROM employees;
...
11-107
Advantages of User-Defined Functions in SQL Statements
Can extend SQL where activities are too complex, too awkward, or unavailable with SQL Can increase efficiency when used in the WHERE clause to filter data, as opposed to filtering the data in the application Can manipulate data values
11-108
54
Using a Function in a SQL Expression
CREATE OR REPLACE FUNCTION tax(p_value IN NUMBER) RETURN NUMBER IS BEGIN RETURN (p_value * 0.08); END tax; / SELECT employee_id, last_name, salary, tax(salary) FROM employees WHERE department_id = 100;
11-109
Calling User-Defined Functions in SQL Statements
User-defined functions act like built-in single-row functions and can be used in:
The SELECT list or clause of a query Conditional expressions of the WHERE and HAVING clauses The CONNECT BY, START WITH, ORDER BY, and GROUP BY clauses of a query The VALUES clause of the INSERT statement The SET clause of the UPDATE statement
11-110
55