Sie sind auf Seite 1von 68

What Is PL/SQL?

PL/SQL stands for Procedural Language operating on or using SQL Combines the flexibility of SQL (4GL) with the power and configurability of the procedural constructs of a 3GL Extends SQL by adding 3GL constructs such as: Variables and types (predefined and user defined) Control Structures (IF-THEN-ELSE, Loops) Procedures and functions Object types and methods

Client-Server Model
SQL results in many network trips, one for each SQL statement PL/SQL permits several SQL statements to be bundled into a single block Results in fewer calls to database

Less network traffic faster response time

Benefits of PL/SQL

Improved Performance
SQL

Application

SQL SQL SQL

Other DBMSs

Application

SQL IF...THEN SQL ELSE SQL END IF; SQL

Oracle with PL/SQL

Benefits of PL/SQL
Modularize program development DECLARE

BEGIN

EXCEPTION

END;

Features of PL / SQL
Block Structure Error Handling Variables and Types Looping Constructs Cursors

PL/SQL Block Structure


DECLARE Optional Variables, cursors, userdefined exceptions BEGIN Mandatory SQL statements PL/SQL statements DECLARE EXCEPTION Optional BEGIN Actions to perform when EXCEPTION errors occur END; END; Mandatory

PL/SQL Block Structure


DECLARE v_variable VARCHAR2(5); BEGIN SELECT column_name INTO v_variable FROM table_name; EXCEPTION WHEN exception_name THEN ... END;

DECLARE BEGIN EXCEPTION END;

Block Types
Anonymous
[DECLARE]

Procedure
PROCEDURE name IS
BEGIN --statements [EXCEPTION] END;

Function
FUNCTION name RETURN datatype IS BEGIN --statements RETURN value; [EXCEPTION]
END;

BEGIN --statements [EXCEPTION] END;

Program Constructs
Anonymous block

DECLARE
Application trigger

Stored procedure/ function Application procedure/ function

BEGIN
EXCEPTION

Database trigger

END;

Packaged procedure/ function

Declaring PL/SQL Variables


Syntax:
identifier [CONSTANT] datatype [NOT NULL] [:= | DEFAULT expr];

Declare Examples: v_hiredate v_deptno v_location c_ comm v_count v_valid

DATE; NUMBER(2) NOT NULL := 10; VARCHAR2(13) := 'Atlanta'; CONSTANT NUMBER := 1400; BINARY_INTEGER := 0; BOOLEAN NOT NULL := TRUE;

Variables and Data Types

Variables
Used to store numbers, character strings, dates, and other data values Avoid using keywords, table names and column names as variable names Must be declared with data type before use: variable_name data_type_declaration;

Naming Rules
Two variables can have the same name, provided they are in different blocks. The variable name (identifier) should not be the same as the name of table columns used in the block.
DECLARE empno BEGIN SELECT INTO FROM WHERE END; NUMBER(4); empno empno emp ename = 'SMITH';

Scalar Data Types

Represent a single value

Scalar Data Types

Composite and Reference Variables

Composite variables
RECORD: contains multiple scalar values, similar to a table record TABLE: tabular structure with multiple columns and rows

Reference variables
Directly reference a specific database field or record and assume the data type of the associated field or record %TYPE: same data type as a database field %ROWTYPE: same data type as a database record

Control Structures
IF-THEN-ELSE
Syntax: IF boolean_expression1 THEN sequence_of_statements1; [ELSIF boolean_expression2 THEN sequence_of_statements2;] [ELSE sequence_of_statements3;] END IF;

PL/SQL Decision Control Structures

Use IF/THEN structure to execute code if condition is true IF condition THEN commands that execute if condition is TRUE; END IF; If condition evaluates to NULL it is considered false Use IF/THEN/ELSE to execute code if condition is true or false IF condition THEN commands that execute if condition is TRUE; ELSE commands that execute if condition is FALSE; END IF; Can be nested be sure to end nested statements

IF, THEN, and ELSIF Statements


For a given value entered, return a calculated value. Example:

. . . IF v_start > 100 v_start := 2 * ELSIF v_start >= v_start := 0.5 ELSE v_start := 0.1 END IF; . . . THEN v_start; 50 THEN * v_start; * v_start;

The LOOP...EXIT Loop


LOOP [program statements] IF condition THEN EXIT; END IF; [additional program statements] END LOOP

The LOOP...EXIT WHEN Loop


LOOP program statements EXIT WHEN condition; END LOOP;

Basic Loop

Example:

DECLARE v_ordid order_items.order_id%TYPE := 101; v_counter NUMBER(2) := 1; BEGIN LOOP INSERT INTO order_items(order_id,line_item_id) VALUES(v_ordid, v_counter); v_counter := v_counter + 1; EXIT WHEN v_counter > 10; END LOOP; END;

The WHILE...LOOP
WHILE condition LOOP program statements END LOOP;

Insert the first 10 new line items for order number 101. Example:

DECLARE v_ordid order_items.order_id%TYPE := 101; I number(2) := 1; BEGIN WHILE i < 10 LOOP INSERT INTO order_items(order_id,line_item_id) VALUES(v_ordid, i); i := i + 1; END LOOP; END;

The Numeric FOR Loop


FOR counter_variable IN start_value .. end_value LOOP program statements END LOOP;

Insert the first 10 new line items for order number 101. Example:

DECLARE v_ordid order_items.order_id%TYPE := 101; BEGIN FOR i IN 1..10 LOOP INSERT INTO order_items(order_id,line_item_id) VALUES(v_ordid, i); END LOOP; END;

PL/SQL Records
Syntax:
TYPE record_type IS RECORD( field1 type1 [NOT NULL] field2 type2 [NOT NULL] field3 type3 [NOT NULL] fieldn typen [NOT NULL]

[:=expr1], [:=expr2], [:=expr3], [:=exprn]);

Example
DECLARE TYPE t_StudentRecord IS RECORD( StudentID NUMBER(5), FirstName VARCHAR2(25), LastName VARCHAR2(25)); V_StudentInfo t_StudentRecord; V_StudentInfo.StudentID := 1001; V_StudentInfo.FirstName := Scott;

Example
DECLARE TYPE t_StudentRecord IS RECORD( StudentID students.studentId%TYPE, FirstName students.FirstName%TYPE, LastName students.LastName%TYPE); V_StudentInfo t_StudentRecord; BEGIN SELECT StudentID, FirstName, LastName INTO V_StudentInfo FROM Students WHERE StudentID = 1001;

END;

PL/SQL Tables
Syntax:
TYPE table_type IS TABLE OF type Index By BINARY_INTEGER;

Example
DECLARE TYPE t_StudentName IS TABLE OF Students.FirstName%TYPE INDEX BY BINARY_INTEGER; TYPE t_TableDate IS TABLE OF DATE INDEX BY BINARY_INTEGER; V_StudentName t_StudentName; V_Date t_TableDate;

BEGIN
V_StudentName(1) := Bhavesh; V_Date(1) := SYSDATE; END

Table Attributes
Count Delete Exists First Last Next Prior

Cursors

Pointer to a memory location that the DBMS uses to process a SQL query
Use to retrieve and manipulate database data

Using an Implicit Cursor


Executing a SELECT query creates an implicit cursor To retrieve it into a variable use INTO: INTO variable1, variable2, ... FROM table1, table2, ... WHERE join_ conditions AND search_condition_to_retrieve_1_record; Can only be used with queries that return exactly one record
SELECT field1, field2, ...

Explicit Cursor

Use for queries that return multiple records or no records


Must be explicitly declared and used

Using an Explicit Cursor


Declare the cursor CURSOR cursor_name IS select_query; Open the cursor OPEN cursor_name; Fetch the data rows LOOP FETCH cursor_name INTO variable_name(s); EXIT WHEN cursor_name%NOTFOUND; Close the cursor CLOSE cursor_name;

Controlling Explicit Cursors


No DECLARE OPEN FETCH EMPTY? Yes CLOSE

Create a
named SQL area

Identify
the active set

Load the
current row into variables

Test for

Release
the active set

existing rows Return to FETCH if rows found

Declaring the Cursor


DECLARE CURSOR c1 IS SELECT employee_id, last_name FROM employees;

Example:

CURSOR c2 IS SELECT * FROM departments WHERE department_id = 10; BEGIN ...

Opening the Cursor

Syntax: OPEN cursor_name; Open the cursor to execute the query and identify the active set. If the query returns no rows, no exception is raised. Use cursor attributes to test the outcome after a fetch.

Fetching Data from the Cursor

Examples:

FETCH c1 INTO v_empid, v_ename; ... OPEN defined_cursor; LOOP FETCH defined_cursor INTO defined_variables EXIT WHEN ...; ... -- Process the retrieved data ... END;

Closing the Cursor

Syntax:
cursor_name;

CLOSE

Close the cursor after completing the processing of the rows. Reopen the cursor, if required. Do not attempt to fetch data from a cursor after it has been closed.

Explicit Cursor Attributes


Obtain status information about a cursor.
Attribute %ISOPEN Type BOOLEAN Description Evaluates to TRUE if the cursor is open

%NOTFOUND
%FOUND

BOOLEAN
BOOLEAN

Evaluates to TRUE if the most recent fetch does not return a row
Evaluates to TRUE if the most recent fetch returns a row; complement of %NOTFOUND Evaluates to the total number of rows returned so far

%ROWCOUNT

NUMBER

Cursor FOR Loops

Retrieve employees one by one until there are no more left. Example:
DECLARE CURSOR c1 IS SELECT employee_id, last_name FROM employees; BEGIN FOR emp_record IN c1 LOOP -- implicit open and implicit fetch occur IF emp_record.employee_id = 134 THEN ... END LOOP; -- implicit close occurs END;

FOR UPDATE Clause

Retrieve the orders for amounts over $1,000 that were processed today. Example:

DECLARE CURSOR c1 IS SELECT customer_id, order_id FROM orders WHERE order_date = SYSDATE AND order_total > 1000.00 ORDER BY customer_id FOR UPDATE NOWAIT;

WHERE CURRENT OF Clause


Example: DECLARE CURSOR c1 IS SELECT salary FROM employees FOR UPDATE OF salary NOWAIT; BEGIN ... FOR emp_record IN c1 LOOP UPDATE ... WHERE CURRENT OF c1; ... END LOOP; COMMIT; END;

Procedures
It is a program unit that can receive multiple input parameters and return multiple output values or return no output values
Syntax:
CREATE [OR REPLACE] PROCEDURE proc_name [list of parameters] IS Declaration section BEGIN Execution section EXCEPTION Exception section END;

Parameter Declarations List

Defines the parameters and declares their associated data types Enclosed in parentheses Separated by commas

Parameter Declarations List


Parameter mode describes how the program unit can change the parameter value:
IN - specifies a parameter that is passed to the program unit as a read-only value that the program unit cannot change. OUT - specifies a parameter that is a write-only value that can appear only on the left side of an assignment statement in the program unit IN OUT - specifies a parameter that is passed to the program unit, and whose value can also be changed within the program unit

Exception Handling
Runtime errors cause exceptions Exceptions cause program control to fall to exception section where exception is handled Exception handling section permits the user to trap and respond to runtime errors

Advantages
you can handle errors conveniently without the need to code multiple checks Exceptions improve readability by letting you isolate error-handling routines

Syntax
EXCEPTION WHEN <named_exception> THEN -- handle identified exception WHEN <named_exception> THEN -- handle identified exception WHEN OTHERS THEN -- handle any exceptions not previously handled END;

TOO_MANY_ROWS
CREATE OR REPLACE PROCEDURE procTooManyRows IS ecode number(5); ename varchar2(100); empName varchar2(50); BEGIN SELECT emp_name into empName from employee; EXCEPTION WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE('TOO many rows exception occur'); END; /

Divide By Zero
CREATE OR REPLACE PROCEDURE procDBZ (para1 NUMBER) IS z NUMBER := 0; x NUMBER; BEGIN x := para1/ z; EXCEPTION WHEN ZERO_DIVIDE THEN dbms_output.put_line('Division By Zero'); WHEN OTHERS THEN dbms_output.put_line('Some Other Problem'); END procDBZ; /

Duplicate value on Index


CREATE OR REPLACE PROCEDURE add_new_supplier (supplier_id_in IN NUMBER, supplier_name_in IN VARCHAR2) IS BEGIN INSERT INTO suppliers (supplier_id, supplier_name ) VALUES ( supplier_id_in, supplier_name_in ); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN DBMS_OUTPUT.PUT_LINE('You have tried to insert a duplicate supplier_id.'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ('An error has occurred inserting a supplier.'); END;

NO_DATA_FOUND
CREATE OR REPLACE PROCEDURE getEmployeeDetails (employee_id IN NUMBER, employee_name OUT VARCHAR2, email OUT VARCHAR2) IS BEGIN SELECT EmpName, Email into employee_name, email FROM Employee WHERE EmpID = emp_ID EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE(No record found for the given employee id.'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ('An error has occurred getting employee details.'); END;

Trapping an error
CREATE OR REPLACE PROCEDURE trap_errcode IS ecode NUMBER(38); thisproc CONSTANT VARCHAR2(50) := 'trap_errmesg'; BEGIN NULL; RAISE too_many_rows; EXCEPTION WHEN OTHERS THEN ecode := SQLCODE; dbms_output.put_line(thisproc || ' - ' || ecode); END trap_errcode; /

NonPredefined Error

Less common errors Do not have predefined names Must declare your own name for the exception code in the declaration section DECLARE e_exception_name EXCEPTION; PRAGMA EXCEPTION_INIT (e_exception_name, -Oracle_error_code);

User defined exception

Not a real Oracle error Use to enforce business rules

Trigger

Syntax
CREATE [OR REPLACE] TRIGGER trigger_name BEFORE (or AFTER) INSERT OR UPDATE [OF COLUMNS] OR DELETE ON tablename [FOR EACH ROW [WHEN (condition)]] BEGIN ... END;

Example Before Insert


Create or Replace trigger emp_bi_trigger before insert on emp for each row declare v_empid emp.empid%type; begin select seqemp.nextval into v_empid from dual; :new.empid := v_empid; :new.hiredate := sysdate; end;

Example After Insert


Create of Replace trigger emp_bi_trigger after insert on emp for each row declare v_empid emp.empid%type; begin dbms_output.put_line(Emp Id: ||:new.empId); dbms_output.put_line(Salary: || :new.salary); end;

Example Before Update


CREATE OR REPLACE TRIGGER emp_bu_trigger BEFORE UPDATE OF fname ON emp FOR EACH ROW BEGIN DBMS_OUTPUT.PUT_LINE('First Name '||:OLD.fname||' has change to '||:NEW.fname); END;

Example After Update


CREATE OR REPLACE TRIGGER emp_au_trigger AFTER UPDATE ON emp FOR EACH ROW BEGIN DBMS_OUTPUT.PUT_LINE('First Name '||:OLD.fname||' has change to '||:NEW.fname); DBMS_OUTPUT.PUT_LINE('Last Name '||:OLD.lname||' has change to '||:NEW.lname); END;

Example Statement level


create or replace trigger emp_biud_trigger before insert or update or delete on emp begin dbms_output.put_line('before statement (emp)'); end;

Managing Trigger

Disable or reenable a database trigger: ALTER TRIGGER trigger_name DISABLE | ENABLE Disable or reenable all triggers for a table: ALTER TABLE table_name DISABLE | ENABLE ALL TRIGGERS Recompile a trigger for a table: ALTER TRIGGER trigger_name COMPILE To remove a trigger from the database, use the DROP TRIGGER syntax: DROP TRIGGER trigger_name;

Das könnte Ihnen auch gefallen