Sunteți pe pagina 1din 49

PL/SQL

PL/SQL Block Structure


DECLARE (optional) BEGIN (required) EXCEPTION (optional) END; (required)

Comments in PL/SQL Block


Single Line(-- Comment) Multi Line(/* Comment */)

PL/SQL Block Types


Anonymous
DECLARE BEGIN -statements EXCEPTION END;

Procedure
PROCEDURE <name>(param1,2..) IS BEGIN -statements EXCEPTION END;

Function
FUNCTION <name>>(param1,2 ..) RETURN <datatype> IS BEGIN -statements EXCEPTION END;

PL/SQL placeholders
All SQL types are supported by PL/SQL
Numerical types
NUMBER, PLS_INTEGER Many derived types, e.g. POSITIVE

Character types
CHAR, VARCHAR2, NCHAR,

Other scalar types


BOOLEAN, DATE

PL/SQL placeholders
Scalar type
variable constant

Composite/vector type
record - used for reading rows from table

PL/SQL placeholders
Scalar type
variable Constant
DECLARE l_x NUMBER := 20000; l_message VARCHAR2(40); C_PI CONSTANT NUMBER(3,2):=3.14; BEGIN l_x := 1000 * C_PI; l_message := 'Hello world'; END;

Attributes %TYPE and %ROWTYPE


%TYPE references type of a variable or a database column %ROWTYPE references type of a record structure, table row or a cursor Advantage:
an actual type does not need to be known

%TYPE and %ROWTYPE examples


balance minimum_balance my_dname dept_rec NUMBER(7,2); balance%TYPE := 10.00; dept.dname%TYPE; dept%ROWTYPE;

SELECT deptno, dname, loc INTO dept_rec FROM dept WHERE deptno = 30;

User-Defined Records
Defining a Record TYPE type_name IS RECORD ( field_name1 datatype1 , field_name2 datatype2 ); record-name type_name; DECLARE TYPE books IS RECORD ( title varchar(50), author varchar(50), subject varchar(100), book_id number); book1 books; book2 books;

PL/SQL Control Structures


Conditional Control
Using IF and CASE statements

Example
DECLARE l_grade CHAR(1) := 'B'; BEGIN CASE l_grade WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent'); WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good'); WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Good'); WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair'); WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor'); ELSE DBMS_OUTPUT.PUT_LINE('No such grade'); END CASE; END; DECLARE l_sales NUMBER(8,2) := 20000; l_bonus NUMBER(6,2); BEGIN IF l_sales > 50000 THEN l_bonus := 1500; ELSIF l_sales > 35000 THEN l_bonus := 500; ELSE l_bonus := 100; END IF; UPDATE employees SET salary = salary + l_bonus; END;

PL/SQL Control Structures


Iterative loops
Simple loop (infinite) WHILE loop FOR loop
Numeric range
Reversed
DECLARE l_i NUMBER := 0;

BEGIN
LOOP END LOOP; WHILE l_i < 10 LOOP DBMS_OUTPUT.PUT_LINE (TO_CHAR(l_i)); l_i:=l_i+1;

Cursor based

DBMS_OUTPUT.PUT_LINE (TO_CHAR(l_i));
l_i := l_i + 1; END LOOP; FOR l_i IN 1..500 LOOP DBMS_OUTPUT.PUT_LINE (TO_CHAR(l_i)); END LOOP; FOR l_i IN REVERSE 1..3 LOOP DBMS_OUTPUT.PUT_LINE (TO_CHAR(l_i)); END LOOP; END;

Parameters in Procedure and Functions


In PL/SQL, we can pass parameters to procedures and functions in three ways. 1) IN type parameter: These types of parameters are used to send values to stored procedures. 2) OUT type parameter: These types of parameters are used to get values from stored procedures. This is similar to a return type in functions. 3) IN OUT parameter: These types of parameters are used to send values and get values from stored procedures. NOTE: If a parameter is not explicitly defined a parameter type, then by default it is an IN type parameter.

Example
DECLARE a number; b number; c number; PROCEDURE findSum(x IN number, y IN number, z IN OUT number) IS BEGIN z:=x+y; END IF; END; BEGIN a:= 23; b:= 45; findSum (a, b, c); dbms_output.put_line(' Sum of (23, 45) : ' || c); END;

Cursors

What are Cursors?


A cursor is a temporary work area created in the system memory when a SQL statement is executed. A cursor contains information on a select statement and the rows of data accessed by it. There are two types of cursors in PL/SQL: Implicit cursors Explicit cursors

Implicit Cursors
Automatically created and destroyed by Oracle. Outcome of the statement can be determined by using SQL%ATTRIBUTE_NAME Some attributes are explained on the next slide.

Example
DECLARE var_rows number(5); BEGIN UPDATE employee SET salary = salary + 1000; IF SQL%NOTFOUND THEN dbms_output.put_line('None of the salaries where updated'); ELSIF SQL%FOUND THEN var_rows := SQL%ROWCOUNT; dbms_output.put_line('Salaries for ' || var_rows || 'employees are updated'); END IF; END;

Explicit Cursors
An explicit cursor is defined in the declaration section of the PL/SQL Block. General Syntax for creating a cursor is as given below:

CURSOR cursor_name IS select_statement;


cursor_name A suitable name for the cursor. select_statement A select query which returns multiple rows.

How to use Explicit Cursor?


There are four steps in using an Explicit Cursor. DECLARE the cursor in the declaration section. OPEN the cursor in the Execution Section. FETCH the data from cursor into PL/SQL variables or records in the Execution Section. CLOSE the cursor in the Execution Section before you end the PL/SQL Block.

Declaration
DECLARE CURSOR emp_cur IS SELECT * FROM emp_tbl WHERE salary > 5000;

How to access an Explicit Cursor?


These are the three steps in accessing the cursor. 1) Open the cursor. OPEN cursor_name; 2) Fetch the records in the cursor one at a time. FETCH cursor_name INTO record_name; OR FETCH cursor_name INTO variable_list; 3) Close the cursor. CLOSE cursor_name;

Cursor with a Simple Loop


DECLARE CURSOR emp_cur IS SELECT first_name, last_name, salary FROM emp_tbl; emp_rec emp_cur %rowtype; BEGIN IF NOT sales_cur%ISOPEN THEN OPEN sales_cur; END IF; LOOP FETCH emp_cur INTO emp_rec; EXIT WHEN emp_cur%NOTFOUND; dbms_output.put_line(emp_cur.first_name || ' ' ||emp_cur.last_name || ' ' ||emp_cur.salary); END LOOP; END;

Cursor with a While Loop


DECLARE CURSOR emp_cur IS SELECT first_name, last_name, salary FROM emp_tbl; emp_rec emp_cur%rowtype; BEGIN IF NOT sales_cur%ISOPEN THEN OPEN sales_cur; END IF; FETCH sales_cur INTO sales_rec; WHILE sales_cur%FOUND THEN LOOP dbms_output.put_line(emp_cur.first_name || ' ' ||emp_cur.last_name || ' ' ||emp_cur.salary); FETCH sales_cur INTO sales_rec; END LOOP; END;

Cursor with a FOR Loop


DECLARE CURSOR emp_cur IS SELECT first_name, last_name, salary FROM emp_tbl; BEGIN FOR emp_rec in c1 LOOP dbms_output.put_line(emp_cur.first_name || ' ' ||emp_cur.last_name || ' ' ||emp_cur.salary); END LOOP; END;

Parameterized Cursor
DECLARE cursor c(no number) is select * from emp_information where emp_no = no; tmp emp_information%rowtype; BEGIN FOR tmp IN c(4) LOOP dbms_output.put_line('EMP_No: '||tmp.emp_no); dbms_output.put_line('EMP_Name: '||tmp.emp_name); dbms_output.put_line('EMP_Dept: '||tmp.emp_dept); dbms_output.put_line('EMP_Salary:'||tmp.emp_salary); END LOOP; END;

Exception Handling

Exception Handling
PL/SQL Exception message consists of three parts. 1) Type of Exception 2) An Error Code 3) A message

Structure of Exception Handling


DECLARE Declaration section BEGIN Exception section EXCEPTION WHEN ex_name1 THEN -Error handling statements WHEN ex_name2 THEN -Error handling statements WHEN Others THEN -Error handling statements END;

Types of Exception
There are 3 types of Exceptions. a) Named System Exceptions b) Unnamed System Exceptions c) User-defined Exceptions

a) Named System Exceptions


System exceptions are automatically raised by Oracle. There are some system exceptions which are raised frequently, so they are pre-defined and given a name in Oracle which are known as Named System Exception. E.g.: BEGIN Execution section EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line ('A SELECT...INTO did not return any row.'); END;

Example

Unnamed System Exceptions


The system exception for which oracle does not provide a name is known as unnamed system exception. These exception do not occur frequently. These Exceptions have a code and an associated message.

Syntax
DECLARE exception_name EXCEPTION; PRAGMA EXCEPTION_INIT (exception_name, Err_code); BEGIN Execution section EXCEPTION WHEN exception_name THEN handle the exception END;

Example
Example: Lets consider the product table and order_items table. Here product_id is a primary key in product table and a foreign key in order_items table. If we try to delete a product_id from the product table when it has child records in order_id table an exception will be thrown with oracle code number -2292. We can provide a name to this exception and handle it in the exception section as given below.

DECLARE Child_rec_exception EXCEPTION; PRAGMA EXCEPTION_INIT (Child_rec_exception, -2292); BEGIN Delete FROM product where product_id= 104; EXCEPTION WHEN Child_rec_exception THEN Dbms_output.put_line('Child records are present for this product_id.'); END;

User-defined Exceptions
Apart from system exceptions we can explicitly define exceptions based on business rules. Steps to be followed to use user-defined exceptions: They should be explicitly declared in the declaration section. They should be explicitly raised in the Execution Section. They should be handled by referencing the userdefined exception name in the exception section.

Example
DECLARE c_id customers.id%type := &cc_id; c_name customers.name%type; c_addr customers.address%type; ex_invalid_id EXCEPTION; BEGIN IF c_id <= 0 THEN RAISE ex_invalid_id; ELSE SELECT name, address INTO c_name, c_addr FROM customers WHERE id = c_id; DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name); DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr); END IF; EXCEPTION WHEN ex_invalid_id THEN dbms_output.put_line('ID must be greater than zero!'); WHEN no_data_found THEN dbms_output.put_line('No such customer!'); WHEN others THEN dbms_output.put_line('Error!'); END;

RAISE_APPLICATION_ERROR ( )
RAISE_APPLICATION_ERROR is a built-in procedure in oracle which is used to display the user-defined error messages along with the error number whose range is in between -20000 and -20999. RAISE_APPLICATION_ERROR raises an exception but does not handle it. RAISE_APPLICATION_ERROR is used for the following reasons, a) to create a unique id for an user-defined exception. b) to make the user-defined exception look like an Oracle error.

Syntax
RAISE_APPLICATION_ERROR (error_number, error_message); The Error number must be between -20000 and -20999 The Error_message is the message you want to display when the error occurs. Steps to be folowed to use RAISE_APPLICATION_ERROR procedure: 1. Declare a user-defined exception in the declaration section. 2. Raise the user-defined exception based on a specific business rule in the execution section. 3. Finally, catch the exception and link the exception to a user-defined error number in RAISE_APPLICATION_ERROR.

Example
CREATE OR REPLACE PROCEDURE Register is BEGIN RAISE_APPLICATION_ERROR(-20000, 'Can''t add more Employee'); EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(20001, ' doesn''t exist!'); END Register;

SQLCODE and SQLERRM


SQLCODE: It returns the error number for the error. SQLERRM: It returns the actual error message of the error. When a SQL statement raises an exception, Oracle captures the error codes by using the SQLCODE and SQLERRM globally-defined variables. SQLCODE and SQLERRM can track exceptions that are handled by the OTHERS clause of the exception handler.

Example
Declare v_sal1 emp.empno%Type := &sal1; v_ename1 emp.ename%Type; Begin Select ename into v_ename1 From emp Where sal=v_sal1; dbms_output.put_line('Name: '||v_ename1); Exception When no_data_found then dbms_output.put_line('Employee not found with '||v_sal1); When others then dbms_output.put_line('The program received an error. Error message returned was: ' || SQLCODE || ',' || SQLERRM); End;

Triggers
A trigger is a pl/sql block structure which is fired when a DML statements like Insert, Delete, Update is executed on a database table. A trigger is triggered automatically when an associated DML statement is executed.

Syntax
CREATE [OR REPLACE ] TRIGGER trigger_name {BEFORE | AFTER } {INSERT [OR] | UPDATE [OR] | DELETE} [OF col_name] ON table_name [REFERENCING OLD AS o NEW AS n] [FOR EACH ROW] WHEN (condition) BEGIN --- sql statements END;

Example
CREATE OR REPLACE TRIGGER audit_sal BEFORE UPDATE OF salary ON employees FOR EACH ROW BEGIN INSERT INTO emp_audit VALUES( :old.employee_id, SYSDATE, :new.salary, :old.salary ); COMMIT; END;

Q&A

Thank You

S-ar putea să vă placă și