Beruflich Dokumente
Kultur Dokumente
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
Benefits of PL/SQL
Improved Performance
SQL
Application
Other DBMSs
Application
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
Block Types
Anonymous
[DECLARE]
Procedure
PROCEDURE name IS
BEGIN --statements [EXCEPTION] END;
Function
FUNCTION name RETURN datatype IS BEGIN --statements RETURN value; [EXCEPTION]
END;
Program Constructs
Anonymous block
DECLARE
Application trigger
BEGIN
EXCEPTION
Database trigger
END;
DATE; NUMBER(2) NOT NULL := 10; VARCHAR2(13) := 'Atlanta'; CONSTANT NUMBER := 1400; BINARY_INTEGER := 0; BOOLEAN NOT NULL := TRUE;
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';
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;
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 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;
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;
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]
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
Explicit Cursor
Create a
named SQL area
Identify
the active set
Load the
current row into variables
Test for
Release
the active set
Example:
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.
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;
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.
%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
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;
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;
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;
Defines the parameters and declares their associated data types Enclosed in parentheses Separated by commas
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; /
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);
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;
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;