Advanced Databases PL/SQL Anonymous Blocks 1 What is PL/SQL? Procedural programming language Uses detailed instructions Processes statements sequentially Combines SQL commands with procedural instructions Used to perform sequential processing using an Oracle database 2 PL/SQL Variables Variable names must follow the Oracle naming standard Can use reserved words (BEGIN, NUMBER) and table names for variable names, but is not a good practice Make variable names descriptive Use lower-case letters, and separate words with underscores Example: current_s_id 3 Declaring PL/SQL Variables PL/SQL is a strongly-typed language All variables must be declared prior to use Syntax for declaring a variable: variable_name data_type_declaration; Example: current_s_id NUMBER(6); 4 PL/SQL Data Types Scalar Composite References a data structure Reference (Not Required) References a single value References a specific database item LOB (Not Required) References a large binary object 5 Scalar Data Types Database scalar data types: VARCHAR2 CHAR DATE LONG NUMBER Non-database scalar data types: Integers: BINARY_INTEGER, INTEGER, INT, SMALLINT Decimal numbers: DEC, DECIMAL, DOUBLE, PRECISION, NUMERIC, REAL BOOLEAN 6 Composite Data Types Reference multiple data elements, such as a record Types: RECORD TABLE VARRAY Tabular structure that can expand or contract as needed 7 Reference Data Types (Not Required) Reference a database item Assume data type of item %TYPE: assumes data type of field %ROWTYPE: assumes data type of entire row 8 PL/SQL Program Structure DECLARE Variable declarations Variable Declarations BEGIN Program statements Body EXCEPTION Error-handling statements END; Exception Section 9 PL/SQL Program Lines May span multiple text editor lines Each line ends with a semicolon Text is not case sensitive 10 Comment Statements Block of comments are delimited with /* */ /* <comment that spans more than one line of code> */ Single comment line starts with 2 hyphens -- comment on a single line 11 Arithmetic Operators Example Result ** Exponentiation 2 ** 3 8 * Multiplication 2*3 6 / Division 9/2 4.5 + Addition 3+2 5 - Subtraction 3–2 1 - Negation -5 Negative 5 12 Assignment Statements Assignment operator: := Variable being assigned to a new value is on left side of assignment operator New value is on right side of operator student_name := ‘John Miller’; student_name := current_student; 13 Displaying PL/SQL Output in SQL*Plus Normally PL/SQL is used with other Oracle utilities such as forms or reports You will learn to use PL/SQL in SQL*Plus Command to activate memory buffer in SQL*Plus to enable output from PL/SQL programs: SQL> SET SERVEROUTPUT ON SIZE buffer_size; SQL> SET SERVEROUTPUT ON SIZE 4000; 14 Displaying PL/SQL Program Output in SQL*Plus Command to output data from a PL/SQL program in SQL*Plus: DBMS_OUTPUT.PUT_LINE(‘output string’); DBMS_OUTPUT.PUT_LINE(‘Current Output:’); 15 Executing a PL/SQL Program in SQL*Plus Copy program code from Notepad to SQL*Plus Type / to execute 16 PL/SQL Data Type Conversion Functions TO_DATE: character string to DATE TO_DATE(‘07/14/01’, ‘MM/DD/YY’); TO_NUMBER: character string to NUMBER TO_NUMBER(‘2’); TO_CHAR: NUMBER or DATE to character string TO_CHAR(2); TO_CHAR(SYSDATE, ‘MM/DD/YYYY HH:MI’); 17 Character String Functions Concatenating strings: joining 2 or more character strings into a single string Concatenation operator: || s_first_name := ‘Sarah’ s_last_name := ‘Miller’ s_full_name := s_first_name || ‘ ’ || s_last_name 18 PL/SQL Character String Functions RTRIM: removes blank trailing spaces cust_address := RTRIM(cust_address); LENGTH: returns string length (number of characters) address_length := LENGTH(cust_address); UPPER, LOWER: changes characters to all upper or lower case s_name := UPPER(s_name); s_name := LOWER(s_name); 19 PL/SQL Character String Functions INSTR: searches a string and looks for a matching substring and returns its starting position starting_position := INSTR(string_being_searched, search_string>); blank_position := INSTR(‘Sarah Miller’, ‘ ’); 20 PL/SQL Character String Functions SUBSTR: extracts a specific number of characters from a string, starting at a given point extracted_string := SUBSTR(string_being_searched, starting_point, number_of_characters_to_extract); s_first_name := SUBSTR(‘Sarah Miller’, 1,5); 21 Debugging PL/SQL Programs Syntax error Does not follow language guidelines Causes a PLS- compile error Examples: misspelling a reserved word, using a function incorrectly Logic error Program compiles correctly, but does not give correct output 22 Locating and Correcting Syntax Errors Isolate the line that is causing the error This may be before or after the line that is flagged by the compiler Comment out lines as necessary until program runs One error may cause several cascading errors, so re-run program after fixing each error 23 Locating and Fixing Logic Errors 1. Identify the output variable(s) that have the error. 2. Identify the inputs and calculations that contribute to the error. 3. Display the values of the inputs using DBMS_OUTPUT commands. 4. Take a break and look at it again later. 5. Ask a fellow student for help. 6. Ask your instructor for help. 24 NULL Values in Assignment Statements Until a value is assigned to a variable, the variable’s value is NULL Performing an arithmetic value on a NULL value always results in a NULL value Advice: Always initialize variable values 25 PL/SQL Selection Structures IF/THEN IF/END IF: IF condition THEN program statements END IF; IF/ELSE/END IF: IF condition THEN program statements ELSE alternate program statements END IF; 26 PL/SQL Selection Structures IF/ELSIF: IF condition1 THEN program statements; ELSIF condition2 THEN alternate program statements; ELSIF condition3 THEN alternate program statements; . . . ELSE alternate program statements; END IF; 27 PL/SQL Comparison Operators Operator Description Example = Equal Count = 5 <>, != Not Equal Count <> 5 > Greater Than Count > 5 < Less Than Count < 5 >= Greater Than or Equal To Count >= 5 <= Less Than or Equal To Count <= 5 28 Evaluating NULL Conditions in IF/THEN Structures If a condition evaluates as NULL, then it is FALSE How can a condition evaluate as NULL? It uses a BOOLEAN variable that has not been initialized It uses any other variable that has not been initialized 29 Using SQL Commands in PL/SQL Programs SQL Command Purpose Category Data Definition Change Language (DDL) database structure Examples CREATE, ALTER, GRANT, REVOKE Data View or change SELECT, Manipulation data INSERT, Language (DML) UPDATE, DELETE Transaction Create logical COMMIT, Control transactions ROLLBACK Can be used in PL/SQL No Yes Yes 30 PL/SQL Loops Loop: repeats one or more program statements multiple times until an exit condition is reached Pretest loop: exit condition is tested before program statements are executed Posttest loop: exit condition is tested after program statements are executed 31 LOOP … EXIT Loop LOOP … EXIT LOOP program statements IF condition THEN Pretest EXIT; OR Posttest END IF; more program statements END LOOP; 32 LOOP … EXIT WHEN Loop LOOP program statements EXIT WHEN condition; END LOOP; Posttest 33 WHILE Loop WHILE condition LOOP program statements END LOOP; Pretest WHILE … LOOP 34 Numeric FOR Loop FOR counter_variable IN start_value .. end_value LOOP Preset program statements number of END LOOP; iterations 35 Cursors Pointer to a server memory location Contains information about a SQL command in a PL/SQL program Called the command’s context area 36 Cursors Database Server Memory Cursor context area active set Number of rows processed CID 1 2 3 4 5 CALLID MIS 101 MIS 301 MIS 441 CS 155 MIS 451 Parsed command statement CNAME Intro. to Info. Systems Systems Analysis Database Management Programming in C++ Client/Server Systems CCREDIT 3 3 3 3 3 37 Types of Cursors Implicit Explicit 38 Implicit Cursors Created automatically every time you use an INSERT, UPDATE, DELETE, or SELECT command Doesn’t need to be declared Can be used to assign the output of a SELECT command to one or more PL/SQL variables Can only be used if query returns one and only one record 39 Implicit Cursor Syntax SELECT field1, field2, … INTO variable1, variable2, … FROM tablename WHERE search_condition_that_will_ return_a_single_record; 40 Explicit Cursors Must be declared in program DECLARE section Can be used to assign the output of a SELECT command to one or more PL/SQL variables Can be used if query returns multiple records or no records 41 Using an Explicit Cursor Declare the cursor Open the cursor Fetch the cursor result into PL/SQL program variables Close the cursor 42 Declaring an Explicit Cursor DECLARE CURSOR cursor_name IS SELECT_statement; 43 Opening an Explicit Cursor OPEN cursor_name; 44 Fetching Explicit Cursor Records FETCH cursor_name INTO variable_name(s); 45 Closing an Explicit Cursor CLOSE cursor_name; 46 Processing an Explicit Cursor LOOP ..EXIT WHEN approach: OPEN cursor_name; LOOP FETCH cursor_name INTO variable_name(s); EXIT WHEN cursor_name%NOTFOUND: END LOOP; CLOSE cursor_name; 47 Processing an Explicit Cursor Cursor FOR Loop approach: FOR variable_name(s) in cursor_name LOOP additional processing statements; END LOOP; 48 Explicit Cursor Attributes Attribute Return Value %NOTFOUND TRUE when no rows left to fetch; FALSE when rows left to fetch TRUE when rows left to fetch; FALSE when no rows left to fetch Number of rows a cursor has fetched so far TRUE if cursor is open and FALSE is cursor is closed %FOUND %ROWCOUNT %ISOPEN 49 Using Reference Data Types in Explicit Cursor Processing Declaring a ROWTYPE reference variable: DECLARE reference_variable_name cursor_name%ROWTYPE; Referencing a ROWTYPE reference variable: reference_variable_name.database_field_name 50 PL/SQL Example1 DECLARE Emp_name VARCHAR2(10); Cursor c1 IS SELECT Ename FROM Emp_tab WHERE Deptno = 20;BEGIN OPEN c1; LOOP FETCH c1 INTO Emp_name; EXIT WHEN c1%NOTFOUND; DBMS_OUTPUT.PUT_LINE(Emp_name); END LOOP; END; 51 PL/SQL Example2 DECLARE Emp_number INTEGER := 9999; Emp_name emp.empname%type; BEGIN SELECT Ename INTO Emp_name FROM Emp_tab WHERE Empno = Emp_number; -- no such number DBMS_OUTPUT.PUT_LINE('Employee name is ' || Emp_name); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('No such employee: ' || Emp_number); END; 52 PL/SQL Tables Composed into two components: Primary Key Column of Scalar or record type Increased dynamically Similar to Arrays in programming languages Known as Objects of type tables Syntax TYPE typename is TABLE OF [column_type | variable%type] [INDEX BY BINARY_IINTEGER]; Indentifier type_name; 53 PL/SQL Tables Declaration There are two steps in the declaration of a PL/SQL table. First, you must define the table structure using the TYPE statement. Second, once a table type is created, you then declare the actual table. 54 PL/SQL Table Declaration Example: DECLARE -- Table structure definition TYPE EmpNameType IS TABLE OF Emp.empname%TYPE INDEX BY BINARY_INTEGER; -- Create the actual table EmpTab EmpNameType; SupTab EmpNameType; BEGIN NULL; -- ... END; 55 Referencing and Modifying PL/SQL table rows In order to specify a particular row in a PL/SQL table, you must name the table and the index. Syntax: <table_name>(<index_value>) The datatype of the index value must be compatible with the BINARY_INTEGER datatype. You assign values to a row using the standard assignment operator. Referencing a nonexistent row raises the NO_DATA_FOUND exception. 56 Referencing and Modifying PL/SQL table rows Example: DECLARE CURSOR c_Ename IS SELECT empname, empno FROM emp ORDER BY empname; TYPE type_Ename_tab IS TABLE OF emp.empname%TYPE INDEX BY BINARY_INTEGER; tab_Ename type_Ename_tab; v_Ename_counter NUMBER := 0; BEGIN FOR r_Ename IN c_Ename LOOP v_Ename_counter := v_Ename_counter + 1; tab_Ename(v_Ename_counter):= r_Ename.empname; END LOOP; END; FOR i_Ename IN 1 .. v_Ename_counter LOOP DBMS_OUTPUT.PUT_LINE('Here is a name: '|| Tab_Ename(i_Ename)); END LOOP; 57 PL/SQL TABLE ATTRIBUTES Here are seven PL/SQL table attributes you can use to gain information about a PL/SQL table or to modify a row in a PL/SQL table: • DELETE—Deletes rows in a table. • EXISTS—Return TRUE if the specified entry exists in the table. • COUNT—Returns the number of rows in the table. • FIRST—Returns the index of the first row in the table. • LAST—Returns the index of the last row in the table. • NEXT—Returns the index of the next row in the table after the specified row. • PRIOR—Returns the index of the previous row in the table be-for the specified row. 58 PL/SQL Table Attributes – How to use them? PL/SQL table attributes are used with the following syntax: <table_name>.<attribute> If you declare a PL/SQL table named t_emp then you get a rowcount for the table as follows: v_count := t_emp.count; The DELETE, EXISTS, NEXT and PRIOR attributes function differently than the other attributes. These two generally operate on one row at a time, so you must add the following syntax: <TableName>.<attribute>(<IndexNumber>[,<IndexNumber>]) Examples: t.emp.delete deletes all rows from the t_emp table, whereas t_emp.delete(15) deletes the fifteenth row of the t_emp table. Likewise, t_emp.exists(10) returns a value of true if there is a tenth row and a value of false if there is not. The EXISTS attribute can be used to determine if a particular index value exists in the PL/SQL table or not. NEXT and PRIOR is used in the same manner 59 PL/SQL Exception Handling All error handling statements are placed in the EXCEPTION program block Exception handler: program command that provides information about an error, and suggest correction actions 60 Predefined Exceptions Common errors that have been given predefined names that appear instead of error numbers Error Code ORA-00001 ORA-01001 ORA-01403 ORA-01422 Exception Name DUP_VAL_ON_INDEX INVALID_CURSOR NO_DATA_FOUND TOO_MANY_ROWS ORA-01476 ZERO_DIVIDE ORA-01722 INVALID_NUMBER ORA-06502 VALUE_ERROR Description Unique constraint violated Illegal cursor operation Query returns no records Query returns more rows than expected Division by zero Invalid numeric conversion Error in arithmetic or numeric function operation 61 Exception Handler Syntax For Predefined Exceptions WHEN exception1_name exception handling WHEN exception2_name exception handling … WHEN OTHERS THEN exception handling THEN statements; THEN statements; statements; 62 Undefined Exceptions Less-common errors that have not been given predefined names ORA- error code appears Exception handler tests for ORA- error code and provides alternate error message 63 User-Defined Exceptions Errors that will not cause a run-time error, but will violate business rules (i.e. they are created for logical errors) Programmer creates a custom error message 64 Nested PL/SQL Program Blocks An inner program block can be nested within an outer program block DECLARE variable declarations BEGIN program statements DECLARE variable declarations BEGIN program statements EXCEPTION error handling statements END; Outer block Inner block EXCEPTION error handling statements END; 65 Exception Handling in Nest Program Blocks If an exception is raised and handled in an inner block, program execution resumes in the outer block 66 Exception Handling in Nested Program Blocks DECLARE variable declarations BEGIN program statements DECLARE exception_A BEGIN RAISE exception_A EXCEPTION exception_A error handler END; additional program statements EXCEPTION error handling statements END; Exception is raised and handled in inner block Program execution resumes here 67 Exception Handling in Nested Program Blocks Exceptions raised in inner blocks can be handled by exception handlers in outer blocks 68 Example of a USER-DEFINED Exception Declare huge_quantity exception; V_qty number(10); v_msg varchar2(100); Begin v_qty := &V_qty; if v_qty > 1000 then v_msg := ‘very huge quantity’; raise huge_quantity; else v_msg := ‘Good’; end if; dbms_output.put_line (v_msg); Exception when huge_quantity then dbms_output.put_line (v_msg); End; 69 Example of a USER-DEFINED Exception (Giving an error number between -20000 to -20999) Declare huge_quantity exception; V_qty number(10); v_msg varchar2(100); Begin v_qty := &V_qty; if v_qty > 1000 then v_msg := ‘very huge quantity’; raise huge_quantity; else v_msg := ‘Good’; end if; dbms_output.put_line (v_msg); Exception when huge_quantity then raise_application_error (-20100, v_msg); End; 70