Oracle Basics of PL - SQL
Oracle Basics of PL - SQL
. Some important features of the program are: The executable portion of a PL/SQL code block starts with the keyword Begin and is terminated with the keyword End. PL/SQL code blocks are comprised of statements. Each statement ends with a semi-colon. PL/SQL code blocks are followed by a slash (/) in the first position of the following line. This causes the code block statements to be executed. The only PL/SQL code block keyword that is followed by a semi-colon is the End keyword.
SQL> START C:\BUSINESS\ORACLE~1\PLSQL1\L1.SQL HELLO PL/SQL PROCEDURE SUCCESSFULLY COMPLETED End listing
Practice
The code block is terminated by the End keyword. This is the only keyword within the construct that is followed by a semi-colon (;). The only required section is the executable section. This means the code block must have the Begin and End keywords. The code block is executed by the slash (/) symbol.
SQL> SET SERVEROUTPUT ON; SQL> DECLARE 2 LOCAL_VARIABLE VARCHAR2(30); 3 BEGIN 4 SELECT 'NUMBER OF EMPLOYEES'||TO_CHAR(COUNT(LAST_NAME), '999') 5 INTO LOCAL_VARIABLE 6 FROM EMPLOYEE; 7 DBMS_OUTPUT.PUT_LINE (LOCAL_VARIABLE); 8 EXCEPTION 9 WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('ERROR OCCURED'); 10 END; 11 / NUMBER OF EMPLOYEES 19 PL/SQL PROCEDURE SUCCESSFULLY COMPLETED.
End Listing
Some rules to remember are: Labels are defined by placing two less than (<<) symbols before the label name and two greater than (>>) symbols after the label name. The Goto keyword is used to redirect the focus of the code block. The name of the label is placed after the Goto keyword.
A Block label is similar to a label except that it can be used to qualify the contents of a block. The Block label is placed at the beginning of the block. The label is then placed following the End keyword. By placing the label definition and the end label, you can identify the code block and the variables within the labeled block. This can be a useful device when the program contains multiple code blocks.
SQL> BEGIN <<B_LABEL>> 2 GOTO MIDDLE; 3 <<TOP>> 4 DBMS_OUTPUT.PUT_LINE ('TOP STATEMENT'); 5 GOTO BOTTOM; 6 <<MIDDLE>> 7 DBMS_OUTPUT.PUT_LINE ('MIDDLE STATEMENT'); 8 GOTO TOP; 9 <<BOTTOM>> 10 DBMS_OUTPUT.PUT_LINE ('BOTTOM STATEMENT'); 11 END B_LABEL; 12 / MIDDLE STATEMENT TOP STATEMENT BOTTOM STATEMENT PL/SQL PROCEDURE SUCCESSFULLY COMPLETED. SQL>
End listing
Comments Comments can be entered into the code block. Two devices are available. These are: -Two dashes placed at the beginning of the line will comment out the entire line.
/* */ The slash-star (/*) symbol marks the beginning of a commented area. The star-slash (*/) symbol marks the ending. Multiple statements can be included in the commented section.
Practice
2. Create a PL/SQL procedure that has four sections. Each section should output a statement. Use labels and the Goto command to output the section messages in the following order: Section 3 Section 2 Section 1 Section 4
Defining Variables Variables are defined in the declaration section of the program. The syntax is:
Variable_name
datatype(precision);
Oracle treats a variable definition similar to other statements. The definition must end with a semi-colon. The definition statement begins with the variable name and contains the data type. These are the mandatory parts of the definition. A value may also be assigned to the variable during the definition statement. The variable may also be constrained.
Character Definitions
The following are examples of definitions:
first_name social_security_number
varchar2(15); char(11);
The PL/SQL maximum length of the char and varchar2 data types is larger than the length allowed in the Oracle database.
Numeric Definitions
Numeric data definitions can include two parameters. The first parameter is precision and the second is scale. Precision defines the overall length of the value. Scale determines the number of digits to the left or right of the decimal point. The range of scale is 84 to 127. If a scale is specified, rounding will occur at the end. The following rules apply: Positive scale definitions cause rounding to the right of the decimal point. Negative scale definitions cause rounding to the left of the decimal point. Zero scale definitions cause rounding to the nearest whole number.
Other Definitions Several other types of definitions are available. These are: Boolean This variable type is used to record a condition. The value can be true, false, or null. This variable type is used to record date values. This variable type is used to define a custom named exception or error handler.
Date Exception
Constrained Definitions Constraints can be placed on the variables defined in the code block. A constraint is a condition that is placed on the variable. Two common constraints are: Constant - This constraint will cause Oracle to ensure the value is not changed after a value is initially assigned to the variable. If a statement tries to change the variable value, an error will occur. Not Null - This constraint will cause Oracle to ensure the variable always contains a value. If a statement attempts to assign a null value to the variable, an error will occur.
pi birth_date
Aggregate and PL/SQL Record Definitions An aggregate variable definition is based upon a database or PL/SQL object. They consist of one or more variables and are extremely useful. They have two advantages: 1. The developer can automatically define a variable with the same data specifications as a table column or cursor variable without actually knowing the specifications. 2. The developer can set up an array of variables for a cursor or table record with one statement. The variables will have the same specifications as the table or cursor variables.
Variable_name
table_cursor_name.column_name%type;
lname
employee.last_name%type;
10
Array_name
table/cursor_name%rowtype;
Dept_var
department%rowtype;
Dept_var.department Dept_var.department_name
11
SQL> declare 2 retirement_date date; 3 emp_var employee%rowtype; Assigning 4 begin values to 5 select min(birth_date) variables 6 into emp_var.birth_date 7 from employee; 8 retirement_date := add_months(emp_var.birth_date, 12*65); 9 dbms_output.put_line (to_char(retirement_date)); 10 end; 11 / 29-DEC-73 PL/SQL procedure successfully completed. SQL> End Listing
SQL> declare 2 retirement_date date; 3 emp_var employee%rowtype; 4 begin 5 select * 6 into emp_var 7 from employee where last_name = 'ANTHONY'; 8 retirement_date := add_months(emp_var.birth_date, 12*65); 9 dbms_output.put_line (to_char(retirement_date)); 10 end; 11 / 15-FEB-85 PL/SQL procedure successfully completed. SQL> End listing
12
Practice
3. Create a PL/SQL procedure that computes the retirement age of the youngest employee. You should also list the employees name. 4. Modify the program in #3 to compute the number of days between today and the employees retirement date. 5. Identify the number of tool purchases for Harry Truman and George Bush. Output the name of the employee with the greater number of tool purchases.
To be effective, a code block or procedure needs to have commands that allow the developer to document the logic necessary to determine the behavior. Oracle uses conditional logic statements to form the procedures behavior. The logic statements come in two forms. These are:
13
End Listing
14
End Listing
End Listing
15
Practice
6. Use a nested-if statement to output whether the highest employee in #5 had two or more than the lower. 7. Output which decade of the twentieth century Bill Clinton was born in. 8. Create a PL/SQL procedure that computes and displays the average starting age of the set of employees in the Employee database.
CURSORS
A cursor is a device that is used to retrieve a set of records from a table/view into memory. Cursors allow each of the records to be read into the code block and processed one-at-a-time. A cursor can be compared to a book containing a page mark. Each of the pages is a record in the set of records retrieved when the cursor is executed. The bookmark indicates the current page. When using a cursor, Oracle always knows the current record. As one record is read into the code block, the current record is changed just as the bookmark is changed as a page is read. Cursors are important tools for the processing of records. They allow the developer to bring records into the code block and to process them using a complex set of statements
16
Declaring the Cursor Cursors are defined in the Declaration section of the code block. The definition consists of the keywords Cursor and Is, the name of the cursor, and the Select statement used to retrieve the record set. The following is an example of the cursor definition structure:
Cursor Commands There are three commands that are used in conjunction with cursors. These commands are contained in Table:
Cursor Commands
Command Open
Fetch/into
Close
Close cursor_name;
Description This command executes the cursors Select statement and places the records into memory. The first record in the set is the current set. This command assigns the values from the current cursor record to the listed local variables or PL/SQL record. It also makes the next record in the set the current record. Terminates the cursor and frees the memory used by the cursor for other uses.
17
Several items to remember about cursor commands are: The commands end with a semi-colon. Issuing the Open command when the cursor is currently open will cause an error and terminate the procedure. Issuing the Close command when the Cursor is not open will cause an error and terminate the procedure. Issuing the Fetch/into command when the cursor is not open will cause an error and terminate the procedure. Issuing the Fetch/Into command after the last record has been fetched will not cause an error. The values from the last record will be reassigned to the local variables.
SQL> declare 2 oldest_birth_date date; 3 lname employee.last_name%type; 4 fname employee.first_name%type; 5 cursor find_old_b_day is select min(birth_date) from employee; 6 cursor id_employee is select last_name, first_name 7 from employee 8 where birth_date = oldest_birth_date; 9 begin 10 open find_old_b_day; Value from the 11 fetch find_old_b_day into oldest_birth_date; old_b_day 12 close find_old_b_day; cursor is used 13 open id_employee; as an argument 14 fetch id_employee into lname, fname; 15 close id_employee; 16 dbms_output.put_line ('The Oldest Employee Is 17 ||lname||', '||fname); 18 end; 19 / Cursor The Oldest Employee Is JOHNSON, ANDREW commands PL/SQL procedure successfully completed. SQL> End Listing
18
Using Aggregate Variables With Cursors In the previous example local variables were defined for each of the columns retrieved by the cursors. The developer had to declare each of the variables used to assign cursor values and also had to include them in the fetch statements. There are two potential problems with this method. These are: 1. The developer must document the local variables size and type. If the size of the cursor variable is larger than the size of the local variable its value is assigned to, an error will occur and the procedure will terminate. The procedure will also terminate if the data types are different. 2. If the size of the column is changed, the procedure variables will also need to be changed. Failure to change the procedure may cause the procedure to terminate when run.
SQL> declare 2 cursor find_old_b_day is select min(birth_date) day 3 from employee; 4 old_date find_old_b_day%rowtype; 5 cursor id_employee is select last_name, first_name 6 from employee 7 where birth_date = old_date.day; 8 id id_employee%rowtype; 9 begin 10 open find_old_b_day; 11 fetch find_old_b_day into old_date; 12 close find_old_b_day; PL/SQL 13 open id_employee; records 14 fetch id_employee into id; 15 close id_employee; 16 dbms_output.put_line ('The Oldest Employee Is ' 17 ||id.last_name||', '||id.first_name); 18 end; 19 / PL/SQL The Oldest Employee Is JOHNSON, ANDREW record variable PL/SQL procedure successfully completed. SQL> End Listing
19
Several things to remember when using %rowtype are: The cursor must be defined before the PL/SQL record definition. All cursor columns must have a name. When expressions are included such as the case of group functions, you must include a column alias.
Practice
9. Create a PL/SQL procedure that computes the hiring age of the first employee hired by the WEL department.
20
Cursor Attributes
Cursor Attributes
Name %found
%notfound
%rowcount
%isopen
Description This attribute is true if the last fetch statement returned a record. It is false if it did not. This attribute is true if the last fetch statement did not return a record. It is false if it did. This attribute returns the number of fetch commands that have been issued for the cursor. This attribute is true if the indicated cursor is currently open. It is false if the cursor is currently closed.
These commands are used in a condition within the procedure. They are used to evaluate the condition of a cursor. Based upon this condition, an action will occur. The syntax of the expression is as follows:
Cursor_name%isopen
21
CHAPTER 1 SQL> DECLARE 2 CURSOR NAME IS SELECT MAX(FIRST_NAME) FNAME, %Isopen cursor CHAPTER 2 3 MAX(LAST_NAME)
variable
LNAME 4 5 NAMES FROM EMPLOYEE; NAME%ROWTYPE; 6 7 8 9 10 BEGIN IF NOT NAME%ISOPEN THEN OPEN NAME; END IF; FETCH NAME INTO NAMES;
CHAPTER 8 11 DBMS_OUTPUT.PUT_LINE (NAMES.FNAME||' '||NAMES.LNAME); CHAPTER 9 CHAPTER 10 CHAPTER 11 CHAPTER 12 CHAPTER 13 12 13 14 IF NAME%ISOPEN THEN CLOSE NAME; END IF;
15 END; 16 /
CHAPTER 14 WOODROW WILSON CHAPTER 15 CHAPTER 16 PL/SQL PROCEDURE SUCCESSFULLY COMPLETED. CHAPTER 17 CHAPTER 18 SQL> CHAPTER 19
End listing
22
Practice
10. Cause a cursor already open error to occur. 11. Fix the error produced in #10 using the %isopen cursor attribute.
LOOPS
There are three types of looping structures. These are the Loop structure, While structure, and For structure. The former two structures will be discussed in this section. The For looping structure will be discussed in the next section. Each of the loop structures has three things in common: 1. The structure contains the Loop keyword. 2. Each structure ends with the End loop keywords. 3. Each structure uses a conditional expression to determine whether to stop the looping.
23
Loop Statements; When break_out condition then exit; Statements; End loop;
loop
End listing
24
The Loop Structure Using the If-Then Structure to Terminate the Loop
SQL> declare 2 counter_variable number := 1; 3 cursor a is select last_name from employee; 4 cur_var a%rowtype; 5 begin 6 open a; 7 loop 8 if counter_variable = 7 then exit; end if; 9 fetch a into cur_var; 10 dbms_output.put_line (cur_var.last_name); 11 counter_variable := counter_variable +1; 12 end loop; 13 end; 14 / COOLIDGE JOHNSON REAGAN BUSH JOHNSON CLINTON PL/SQL procedure successfully completed. SQL>
End listing
Practice
12. Determine the hiring date for Ronald Reagan and how many tool and eyeglass purchases he made. 13. Use a simple loop to list the first 12 records of the Emp_tools table. Use the When keyword to construct the loop breakout. 14. Modify your procedure in #13. Use the If-then structure to construct the loop breakout.
25
26
Open cursor_name; Fetch cursor_attributes into local_variables; While (cursor_name%found) Loop Statements; Fetch cursor_attributes into local_variables; End loop; Close cursor_name;
A record is fetched before the loop Another fetch command is used at the end of
End listing
27
Nested Loops
A Nested While Loop Used to Compute the Highest Priced Tool
SQL> declare 2 cursor a is select payroll_number, last_name from employee 3 where fk_department = 'WEL'; 4 a_var a%rowtype; 5 cursor b is select tool_name, tool_cost from emp_tools 6 where fk_payroll_number = a_var.payroll_number; 7 b_var b%rowtype; 8 hi_tool_name emp_tools.tool_name%type; 9 hi_tool_cost emp_tools.tool_cost%type; 10 begin 11 open a; fetch a into a_var; Nested 12 while a%found loop 13 open b; fetch b into b_var; 14 while b%found loop 15 if b_var.tool_cost > hi_tool_cost or b_var.tool_cost is null then 16 hi_tool_name := b_var.tool_name; 17 hi_tool_cost := b_var.tool_cost; 18 end if; 19 fetch b into b_var; 20 end loop; 21 close b; 22 dbms_output.put_line (a_var.last_name||' '||b_var.tool_name); 23 hi_tool_name := null; 24 hi_tool_cost := null; 25 fetch a into a_var; 26 end loop; 27 close a; 28 end; 29 / REAGAN Tool Chest CARTER Tool Chest HOOVER TIN SNIPS TAFT FOUNTAIN PEN ANTHONY STAPLER ROOSEVELT PLIERS PL/SQL procedure successfully completed. SQL>
End listing
Practice
15. Create a procedure that displays the employees in the INT department. Use a While loop. 16. Create a procedure that determines the number of tool purchases and the number of eyeglass purchases per employee. Use the %rowcount cursor attribute to number the displayed rows. 17. Recreate #15 using the %notfound cursor attribute.
28
End Listing
End listing
29
30
End Listing
Practice
18. Create a procedure that updates the Absences column in the Employee table. The value should be set to 0. Use the Where Current Of option.
31
End listing
32
End listing
Practice
19. Create a procedure that displays the five oldest employees. Use a numeric For loop in your procedure and number each record. 20. Modify the procedure you built in #19 to number the records in reverse order.
33
PL/SQL
record SQL> declare 2 cursor a is select first_name, last_name from employee; 3 begin Cursor name 4 for cnt_var in a 5 loop 6 dbms_output.put_line(to_char(a%rowcount)||' '||cnt_var.last_name); 7 end loop; 8 end; 9 / 1 COOLIDGE . . 19 ROOSEVELT
PL/SQL procedure successfully completed.
End Listing
34
End Listing
Outer loop
variable used SQL> declare 2 hi_tool_name emp_tools.tool_name%type; in the inner 3 hi_tool_cost emp_tools.tool_cost%type; loop cursor 4 begin 5 for outer_loop in (select payroll_number, last_name from employee 6 where fk_department = 'WEL') 7 loop 8 for inner_loop in (select tool_name, tool_cost from emp_tools 9 where fk_payroll_number = outer_loop.payroll_number) 10 loop 11 if (inner_loop.tool_cost > hi_tool_cost 12 or hi_tool_cost is null) then 13 hi_tool_name := inner_loop.tool_name; 14 hi_tool_cost := inner_loop.tool_cost; 15 end if; 16 end loop; 17 dbms_output.put_line (outer_loop.last_name||' '||hi_tool_name); 18 hi_tool_name := null; 19 hi_tool_cost := null; 20 end loop; 21 end; 22 / REAGAN Tool Chest CARTER HOOVER TIN SNIPS TAFT FOUNTAIN PEN ANTHONY BRIEF CASE ROOSEVELT CALCULATOR
PL/SQL procedure successfully completed. SQL>
End listing
35
Practice
21. Create a procedure to list the employees in the INT and POL departments. Use a Cursor For loop in this procedure. The procedure should define a cursor. 22. Modify the procedure in #21. Define the select statement used in the Cursor For loop within the Cursor For structure. 23. Create a procedure that determines the date of the highest priced tool and the date of the highest priced eyeglass purchase for each employee. Use nested Cursor For loops
36