Examples dealing with cursors and tables Please use speaker notes for additional information!

Slides:



Advertisements
Similar presentations
PL/SQL.
Advertisements

PL/SQL User Defined Types Record and Table Please use speaker notes for additional information!
AN INTRODUCTION TO PL/SQL Mehdi Azarmi 1. Introduction PL/SQL is Oracle's procedural language extension to SQL, the non-procedural relational database.
PL/SQL. Introduction to PL/SQL PL/SQL is the procedure extension to Oracle SQL. It is used to access an Oracle database from various environments (e.g.
Loops (Part 1) Computer Science Erwin High School Fall 2014.
Programming with Alice Computing Institute for K-12 Teachers Summer 2011 Workshop.
PL/SQL - Using IF statements Please use speaker notes for additional information!
Murali Mani Persistent Stored Modules (Stored Procedures) : PSM.
Library example CREATE TABLE books ( isbn VARCHAR2(13) PRIMARY KEY, title VARCHAR2(200), summary VARCHAR2(2000), author VARCHAR2(200), date_published DATE,
Programming in Oracle with PL/SQL
1 PL/SQL programming Procedures and Cursors Lecture 1 Akhtar Ali.
Table maintenance revisited (again) Please use speaker notes for additional information!
Cursors in Pl/SQL Database 1. Practice. Sample Database The schema of the sample database is the following: Drinkers (name, occupation, birthday, salary)
Logical Operators Operator AND OR NOT Meaning Returns TRUE if both component conditions are TRUE Returns TRUE if either component condition is TRUE Returns.
PL/SQL Bulk Collections in Oracle 9i and 10g Kent Crotty Burleson Consulting October 13, 2006.
Cursors in PL/SQL Includes cursor example and continuation of first cursor example Please use speaker notes for additional information!
Bordoloi and Bock EXCEPTIONS. Bordoloi and Bock Errors Two types of errors can be found in a program: compilation errors and runtime errors. There is.
6 Copyright © 2009, Oracle. All rights reserved. Working with Composite Data Types.
15/10/20151 PHP & MySQL 'Slide materials are based on W3Schools PHP tutorial, 'PHP website 'MySQL website.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Introduction to Relational Databases &
Program with PL/SQL. Interacting with the Oracle Server.
Overview · What is PL/SQL · Advantages of PL/SQL · Basic Structure of a PL/SQL Block · Procedure · Function · Anonymous Block · Types of Block · Declaring.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Cursors These slides are licensed under.
PL/SQL Cursors Session - II. Attributes Attributes %TYPE %ROWTYPE % Found % NotFound % RowCount % IsOPen %TYPE %ROWTYPE % Found % NotFound % RowCount.
PL SQL Block Structures. What is PL SQL A good way to get acquainted with PL/SQL is to look at a sample program. PL/SQL combines the data manipulating.
SQL- DQL (Oracle Version). 2 SELECT Statement Syntax SELECT [DISTINCT] column_list FROM table_list [WHERE conditional expression] [GROUP BY column_list]
More on views Please refer to speaker notes for additional information!
SQL and Conditions Speaker notes will provide additional information!
1 CursorsCursors. 2 SQL Cursor A cursor is a private SQL work area. A cursor is a private SQL work area. There are two types of cursors: There are two.
Session 2: SQL (A): Parts 1 and 2 Original materials supplied by the Oracle Academic Initiative (OAI). Edited for classroom use by Professor Laku Chidambaram.
Manipulating data within PL/SQL Please use speaker notes for additional information!
PL/SQL Procedural Language / Structured Query Language.
Variety of JavaScript Examples Please use speaker notes for additional information!
Exceptions in PL/SQL Please use speaker notes for additional information!
Indexes in Oracle An Introduction Please check speaker notes for additional information!
Using SQL in PL/SQL ITEC 224 Database Programming.
Using SQL Connecting, Retrieving Data, Executing SQL Commands, … Svetlin Nakov Technical Trainer Software University
ITEC 224 Database Programming PL/SQL Lab Cursors.
Copyright  Oracle Corporation, All rights reserved. 12 Creating Views.
Introduction to Explicit Cursors. 2 home back first prev next last What Will I Learn? Distinguish between an implicit and an explicit cursor Describe.
implicit and an explicit cursor
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Using Data Structures in Embedded Programs.
PL/SQL programming Procedures and Cursors Lecture 1 [Part 2]
Introduction to PL/SQL As usual, use speaker notes for additional information!
In this session, you will learn to: Query data by using joins Query data by using subqueries Objectives.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Extended Prelude to Programming Concepts & Design, 3/e by Stewart Venit and.
Program with PL/SQL Lesson 3. Interacting with the Oracle Server.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Extended Prelude to Programming Concepts & Design, 3/e by Stewart Venit and.
6 Copyright © 2004, Oracle. All rights reserved. Working with Composite Data Types.
Visual Basic - Break Processing
ITEC 224 Database Programming
COMP 430 Intro. to Database Systems
Chapter 3: Decisions and Loops
Subqueries.
Error Handling Summary of the next few pages: Error Handling Cursors.
Introduction to Procedures
Introduction to the Array
Writing Correlated Subqueries
MySQL - Creating donorof database offline
Working with Composite Datatypes
What Is a View? EMPNO ENAME JOB EMP Table EMPVU10 View
Please use speaker notes for additional information!
Chapter 2 Handling Data in PL/SQL Blocks Oracle9i Developer:
Cursors.
Chapter 03 DBMS.
Searching an Array or Table
More and Still More on Procedures and Functions
Restricting and Sorting Data
Please use speaker notes for additional information!
Presentation transcript:

Examples dealing with cursors and tables Please use speaker notes for additional information!

Data - employeez SQL> DESC employeez; Name Null? Type EMPLOYEE_ID NOT NULL NUMBER(4) LAST_NAME VARCHAR2(15) FIRST_NAME VARCHAR2(15) MANAGER_ID NUMBER(4) SALARY NUMBER(7,2) SQL> select * from employeez; EMPLOYEE_ID LAST_NAME FIRST_NAME MANAGER_ID SALARY SMITH JOHN ALLEN KEVIN DOYLE JEAN DENNIS LYNN BAKER LESLIE WARD CYNTHIA PETERS DANIEL SHAW KAREN DUNCAN SARAH LANGE GREGORY JONES TERRY ALBERTS CHRIS PORTER RAYMOND LEWIS RICHARD MARTIN KENNETH SOMMERS DENISE BLAKE MARION CLARK CAROL SCOTT DONALD WEST LIVIA FISHER MATTHEW ROSS PAUL KING FRANCIS TURNER MARY ADAMS DIANE JAMES FRED FORD JENNIFER ROBERTS GRACE DOUGLAS MICHAEL MILLER BARBARA JENSEN ALICE MURRAY JAMES rows selected.

SET SERVEROUTPUT ON DECLARE TYPE t_ManagerTable IS TABLE OF employeez.manager_id%TYPE INDEX BY BINARY_INTEGER; v_ManagerIdTable t_ManagerTable; CURSOR c_Employee1 IS SELECT manager_id FROM employeez; v_ManagerId employeez.manager_id%TYPE; v_FoundFlag BOOLEAN; v_LoopCnt BINARY_INTEGER BEGIN OPEN c_Employee1; LOOP FETCH c_Employee1 INTO v_ManagerId; EXIT WHEN c_Employee1%NOTFOUND; v_FoundFlag := FALSE; v_LoopCnt := 1; WHILE v_LoopCnt <= v_ManagerIdTable.COUNT LOOP IF v_ManagerId = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; EXIT; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = FALSE THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_ManagerId; END IF; END LOOP; CLOSE c_Employee1; FOR i IN 1..v_ManagerIdTable.COUNT LOOP dbms_output.put_line(v_ManagerIdTable(i)); END LOOP; END; / SET SERVEROUTPUT OFF SQL> edit pay_raise_1a pay_raise_1a This table will hold unique manager ids. The processing determines uniqueness and updates the table. The cursor will hold all manager_id. The open fills the c_Employee1 cursor. While loop to check for unique manager ids. If a unique is found, the flag is set. Note the EXIT which takes you out of the loop ahead of schedule if the flag is set. If after exiting the unique loop, the flag is FALSE it means that a match was not found ad so the manager id is moved to the table. The outer LOOP…END LOOP is executed until the cursor is empty.

pay_raise_1a Logic analysis: The table, the cursor and the variables needed for processing were set up in the DECLARE. The OPEN statement fills the cursor according to the specifications in the SELECT statement within the cursor. The outer LOOP is entered and a record is FETCHed from the cursor and the manager_id is placed in the variable v_ManagerId. If the fetch was unsuccessful the outer loop is excited and cursor is closed prior to executing the FOR loop. If the FETCH was successful, the v_FoundFlag is set to FALSE and the v_LoopCnt is initialized at 1. Now the inner WHILE LOOP is entered as long as the v_LoopCt is less than or equal to the table count. The first time the WHILE loop is not entered because v_LoopCt is 1 and the COUNT of the elements in the table is 0. It will drop through the LOOP and reach the IF v_FoundFlag = FALSE statement. The flag is false so the element is added to the table COUNT + 1 which means it goes in as element 1. To follow this logic a little more, please look at the next slide.

COUNT before WHILE 0 COUNT before WHILE 1 COUNT in WHILE before IF 1 LOOP FETCH c_Employee1 INTO v_ManagerId; EXIT WHEN c_Employee1%NOTFOUND v_FoundFlag := FALSE; v_LoopCnt := 1; dbms_output.put_line('COUNT before WHILE ' || v_ManagerIdTable.COUNT); WHILE v_LoopCnt <= v_ManagerIdTable.COUNT LOOP dbms_output.put_line('COUNT in WHILE before IF ' || v_ManagerIdTable.COUNT); IF v_ManagerId = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; EXIT; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = FALSE THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_ManagerId; END IF; END LOOP; SQL> SELECT manager_id 2 FROM employeez; MANAGER_ID is written to the table Note that the logic does not enter the while loop. Because v_LoopCnt is not <= v_ManagerIdTable.COUNT. I am testing to see if 1 <= 0 and it isn’t. Logic - first fetch

COUNT before WHILE 1 COUNT in WHILE before IF 1 LOOP FETCH c_Employee1 INTO v_ManagerId; EXIT WHEN c_Employee1%NOTFOUND v_FoundFlag := FALSE; v_LoopCnt := 1; dbms_output.put_line('COUNT before WHILE ' || v_ManagerIdTable.COUNT); WHILE v_LoopCnt <= v_ManagerIdTable.COUNT LOOP dbms_output.put_line('COUNT in WHILE before IF ' || v_ManagerIdTable.COUNT); IF v_ManagerId = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; EXIT; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = FALSE THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_ManagerId; END IF; END LOOP; SQL> SELECT manager_id 2 FROM employeez; MANAGER_ID is written to the table since the flag is FALSE. Note that the logic does enter the while loop. Because v_LoopCnt is <= v_ManagerIdTable.COUNT. I am testing to see if 1 <= 1 and it is. Logic - second fetch The IF statement was never equal because we were checking 7698 with the only thing in the table which was Therefore the flag stayed FALSE.

LOOP FETCH c_Employee1 INTO v_ManagerId; EXIT WHEN c_Employee1%NOTFOUND v_FoundFlag := FALSE; v_LoopCnt := 1; dbms_output.put_line('COUNT before WHILE ' || v_ManagerIdTable.COUNT); WHILE v_LoopCnt <= v_ManagerIdTable.COUNT LOOP dbms_output.put_line('COUNT in WHILE before IF ' || v_ManagerIdTable.COUNT); IF v_ManagerId = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; EXIT; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = FALSE THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_ManagerId; END IF; END LOOP; SQL> SELECT manager_id 2 FROM employeez; MANAGER_ID is written to the table since the flag is FALSE. Note that the logic does enter the while loop. Because v_LoopCnt is <= v_ManagerIdTable.COUNT. It goes through the loop twice comparing 7839 (the new number) to the numbers already in the table: 7903 and Logic - third fetch The IF statement was never equal because we were checking 7839 with the two things in the table: 7902 and Therefore the flag stayed FALSE. COUNT before WHILE 2 COUNT in WHILE before IF 2

LOOP FETCH c_Employee1 INTO v_ManagerId; EXIT WHEN c_Employee1%NOTFOUND v_FoundFlag := FALSE; v_LoopCnt := 1; dbms_output.put_line('COUNT before WHILE ' || v_ManagerIdTable.COUNT); WHILE v_LoopCnt <= v_ManagerIdTable.COUNT LOOP dbms_output.put_line('COUNT in WHILE before IF ' || v_ManagerIdTable.COUNT); IF v_ManagerId = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; EXIT; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = FALSE THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_ManagerId; END IF; END LOOP; SQL> SELECT manager_id 2 FROM employeez; MANAGER_ID Nothing is written to the table since the flag is TRUE. Note that the logic does enter the while loop. Because v_LoopCnt is <= v_ManagerIdTable.COUNT. It goes through the loop 3 times comparing 7839 (the new number) to the numbers already in the table: 7903, 7698, & It finds a match on the third check and sets the flag to TRUE. Logic - fourth fetch The IF statement was equal on the third check because we were checking 7839 with the three things in the table: 7902,7698 & On the last check there is a match so the flag is set to TRUE and the loop is exited.. COUNT before WHILE 3 COUNT in WHILE before IF 3

LOOP FETCH c_Employee1 INTO v_ManagerId; EXIT WHEN c_Employee1%NOTFOUND v_FoundFlag := FALSE; v_LoopCnt := 1; dbms_output.put_line('COUNT before WHILE ' || v_ManagerIdTable.COUNT); WHILE v_LoopCnt <= v_ManagerIdTable.COUNT LOOP dbms_output.put_line('COUNT in WHILE before IF ' || v_ManagerIdTable.COUNT); IF v_ManagerId = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; EXIT; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = FALSE THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_ManagerId; END IF; END LOOP; SQL> SELECT manager_id 2 FROM employeez; MANAGER_ID Nothing is written to the table since the flag is TRUE. Note that the logic does enter the while loop. Because v_LoopCnt is <= v_ManagerIdTable.COUNT. It goes through the loop 3 times comparing 7839 (the new number) to the numbers already in the table: 7903, 7698, & It finds a match on the third check and sets the flag to TRUE. Logic - fifth fetch The IF statement was equal on the third check because we were checking 7839 with the three things in the table: 7902,7698 & On the last check there is a match so the flag is set to TRUE and the loop is exited.. COUNT before WHILE 3 COUNT in WHILE before IF 3

LOOP FETCH c_Employee1 INTO v_ManagerId; EXIT WHEN c_Employee1%NOTFOUND v_FoundFlag := FALSE; v_LoopCnt := 1; dbms_output.put_line('COUNT before WHILE ' || v_ManagerIdTable.COUNT); WHILE v_LoopCnt <= v_ManagerIdTable.COUNT LOOP dbms_output.put_line('COUNT in WHILE before IF ' || v_ManagerIdTable.COUNT); IF v_ManagerId = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; EXIT; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = FALSE THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_ManagerId; END IF; END LOOP; SQL> SELECT manager_id 2 FROM employeez; MANAGER_ID Nothing is written to the table since the flag is TRUE. Note that the logic does enter the while loop. Because v_LoopCnt is <= v_ManagerIdTable.COUNT. It goes through the loop 2 times comparing 7839 (the new number) to the numbers already in the table: 7903, 7698 (never checks 7839). It finds a match on the second check and sets the flag to TRUE. Logic - sixth fetch The IF statement was equal on the second check because we were checking 7698 with the three things in the table: 7902,7698 & On the second check there is a match so the flag is set to TRUE and the loop is exited.. COUNT before WHILE 3 COUNT in WHILE before IF 3

Logic after close When there are no more records in the cursor - the FETCH does not fetch a record the EXIT based on %NOTFOUND is taken. At that point the logic drops to the END LOOP. The next statement executed is the CLOSE which closes the cursor. Finally, there is a FOR loop which is used for demonstration purposes. It goes through the processing and displays the content of the table. As can be seen from the output there are no duplicate numbers in the table. pay_raise_1a PL/SQL procedure successfully completed.

pay_raise_3 - part 1 DECLARE TYPE t_ManagerTable IS TABLE OF employeez.manager_id%TYPE INDEX BY BINARY_INTEGER; v_ManagerIdTable t_ManagerTable; CURSOR c_Employee1 IS SELECT manager_id FROM employeez; CURSOR c_Employee2 IS SELECT employee_id, salary FROM employeez FOR UPDATE OF salary; v_ManagerId employeez.manager_id%TYPE; v_EmployeeId employeez.employee_id%TYPE; v_Salary employeez.salary%TYPE; v_FoundFlag BOOLEAN; v_LoopCnt BINARY_INTEGER; v_TableIndx BINARY_INTEGER; BEGIN OPEN c_Employee1; LOOP FETCH c_Employee1 INTO v_ManagerId; EXIT WHEN c_Employee1%NOTFOUND; v_FoundFlag := FALSE; v_LoopCnt := 1; WHILE v_LoopCnt <= v_ManagerIdTable.COUNT LOOP IF v_ManagerId = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; EXIT; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = FALSE THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_ManagerId; END IF; END LOOP; CLOSE c_Employee1; SQL> edit pay_raise_3 I have added a second cursor to hold the records I am updating, a hold area for the employee id #, a work area for salary and an index. This is the logic that we looked at on previous slides to develop a table of unique manager id #s.

pay_raise_3 - part 2 OPEN c_Employee2; LOOP FETCH c_Employee2 INTO v_EmployeeId, v_Salary; EXIT WHEN c_Employee2%NOTFOUND; v_FoundFlag := FALSE; v_LoopCnt := 1; WHILE v_LoopCnt <= v_ManagerIdTable.COUNT LOOP IF v_EmployeeId = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; EXIT; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = TRUE THEN v_Salary := 1.1 * v_Salary; ELSE v_Salary := 1.02 * v_Salary; END IF; UPDATE employeez SET salary = v_Salary WHERE CURRENT OF c_Employee2; END LOOP; CLOSE c_Employee2; COMMIT; END; / The inner WHILE loop is checking the employee id against the numbers in the manager to table to see if the employee is a manager. If they are the flag is set to true and the loop is exited. The open fills the cursor according to the select on the previous slide. The FETCH moves the data into the specified variables. If the flag is true it means the person is a manager and they are given a 10% raise. Non managers are given a 2% raise. Flag initialized at false and count at 1. The record is updated. Note the WHERE CURRENT OF pointing to the cursor. This assures that the record being processed is updated.

SQL> SELECT * FROM employeez; EMPLOYEE_ID LAST_NAME FIRST_NAME MANAGER_ID SALARY SMITH JOHN ALLEN KEVIN DOYLE JEAN DENNIS LYNN BAKER LESLIE WARD CYNTHIA PETERS DANIEL SHAW KAREN DUNCAN SARAH LANGE GREGORY JONES TERRY ALBERTS CHRIS PORTER RAYMOND LEWIS RICHARD MARTIN KENNETH SOMMERS DENISE BLAKE MARION CLARK CAROL SCOTT DONALD WEST LIVIA FISHER MATTHEW ROSS PAUL KING FRANCIS TURNER MARY ADAMS DIANE JAMES FRED FORD JENNIFER ROBERTS GRACE DOUGLAS MICHAEL MILLER BARBARA JENSEN ALICE MURRAY JAMES rows selected. pay_raise_3 PL/SQL procedure successfully completed. Pay_raise_3 Managers is not in the manager list so Smith gets a 2% raise going from 800 to was on the manager list so Baker got a 10% raise from 2200 to 2420.

Third version pay_raise_4 - part 1 DECLARE TYPE t_ManagerTable IS TABLE OF employeez.manager_id%TYPE INDEX BY BINARY_INTEGER; v_ManagerIdTable t_ManagerTable; CURSOR c_Employee1 IS SELECT manager_id FROM employeez; CURSOR c_Employee2 IS SELECT employee_id, salary FROM employeez FOR UPDATE OF salary; v_Salary employeez.salary%TYPE; v_FoundFlag BOOLEAN; v_LoopCnt BINARY_INTEGER; BEGIN -- Build a table of manager ID's FOR v_EmployeeData1 IN c_Employee1 LOOP v_FoundFlag := FALSE; v_LoopCnt := 1; WHILE (v_LoopCnt <= v_ManagerIdTable.COUNT) AND (v_FoundFlag = FALSE) LOOP IF v_EmployeeData1.manager_id = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = FALSE THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_EmployeeData1.manager_id; END IF; END LOOP; The cursor FOR loop defines the record implicitly in the FOR and links it to the cursor. The FOR automates the processing of the cursor. Note that the WHILE loop does not have an exit. The AND condition that checks to see if the loop should be executed because the count is not less than the number of elements and the flag is FALSE indicating no match yet. Note the use of the implicitly define record from the FOR.

-- Look in manager ID table to determine if employee is a manager -- If employee is a manager increase pay by 10% else increase pay by 2% FOR v_EmployeeData2 IN c_Employee2 LOOP v_FoundFlag := FALSE; v_LoopCnt := 1; WHILE (v_LoopCnt <= v_ManagerIdTable.COUNT) AND (v_FoundFlag = FALSE) LOOP IF v_EmployeeData2.employee_id = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = TRUE THEN v_Salary := 1.1 * v_EmployeeData2.salary; ELSE v_Salary := 1.02 * v_EmployeeData2.salary; END IF; UPDATE employeez SET salary = v_Salary WHERE CURRENT OF c_Employee2; END LOOP; COMMIT; END; / Third version pay_raise_4 - part 2 CURSOR c_Employee2 IS SELECT employee_id, salary FROM employeez FOR UPDATE OF salary; This cursor was declared on the previous page - I am showing it here for reference. Note the use of the implicitly defined record in the IF statement. This name was implicitly defined in the FOR loop as the record name associated with the cursor. Therefore v_employeeData2.employee_id refers to the record in the cursor and specifically the employee_id field. (See the select above).

Output SQL> SELECT * FROM employeez; EMPLOYEE_ID LAST_NAME FIRST_NAME MANAGER_ID SALARY SMITH JOHN ALLEN KEVIN DOYLE JEAN DENNIS LYNN BAKER LESLIE WARD CYNTHIA PETERS DANIEL SHAW KAREN DUNCAN SARAH LANGE GREGORY JONES TERRY ALBERTS CHRIS PORTER RAYMOND LEWIS RICHARD MARTIN KENNETH SOMMERS DENISE BLAKE MARION CLARK CAROL SCOTT DONALD WEST LIVIA FISHER MATTHEW ROSS PAUL KING FRANCIS TURNER MARY ADAMS DIANE JAMES FRED FORD JENNIFER ROBERTS GRACE DOUGLAS MICHAEL MILLER BARBARA JENSEN ALICE MURRAY JAMES rows selected. pay_raise_4 PL/SQL procedure successfully completed.

SET SERVEROUTPUT ON DECLARE TYPE t_ManagerTable IS TABLE OF employeez.manager_id%TYPE INDEX BY BINARY_INTEGER; v_ManagerIdTable t_ManagerTable; CURSOR c_Employee1 IS SELECT employee_id, salary, manager_id FROM employeez ORDER BY manager_id FOR UPDATE OF salary; v_Salary employeez.salary%TYPE; v_FoundFlag BOOLEAN; v_LoopCnt BINARY_INTEGER; BEGIN -- Build a table of manager ID's FOR v_EmployeeData1 IN c_Employee1 LOOP IF v_ManagerIdTable.COUNT = 0 OR v_EmployeeData1.manager_id != v_ManagerIdTable(v_ManagerIdTable.COUNT) THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_EmployeeData1.manager_id; END IF; END LOOP; Pay_raise_5 - part 1 If there is nothing in the manager table (count = 0) or if the manager of the current employee is not = to the element in the table then the element is added to the table. See the next slide for details on this IF.

IF from part1 EMPLOYEE_ID MANAGER_ID SQL> SELECT employee_id, manager_id 2 FROM employeez 3 ORDER BY manager_id; FOR v_EmployeeData1 IN c_Employee1 LOOP IF v_ManagerIdTable.COUNT = 0 OR v_EmployeeData1.manager_id != v_ManagerIdTable(v_ManagerIdTable.COUNT) THEN v_ManagerIdTable(v_ManagerIdTable.COUNT + 1) := v_EmployeeData1.manager_id; END IF; END LOOP; First record: v_ManagerIdTable.Count = 0 so 7505 is put in table. (Note that COUNT is incremented by 1.) Second record: count is not 0 and v_Employee Data1.manager_id is equal to v_ManagerIdTable(v_ManagerIdTable.COUNT) so no addition is made to table. Third record through Fifth record same as Second record Sixth record count is not 0 BUT v_EmployeeData1.manager_id is NOT equal to v_ManagerIdTable(v_ManagerIdTable.COUNT so 7506 is added to the table. Table

-- Look in manager ID table to determine if employee is a manager -- If employee is a manager increase pay by 10% else increase pay by 2% FOR v_EmployeeData2 IN c_Employee1 LOOP v_FoundFlag := FALSE; v_LoopCnt := 1; WHILE (v_LoopCnt <= v_ManagerIdTable.COUNT) AND (v_FoundFlag = FALSE) LOOP IF v_EmployeeData2.employee_id = v_ManagerIdTable(v_LoopCnt) THEN v_FoundFlag := TRUE; END IF; v_LoopCnt := v_LoopCnt + 1; END LOOP; IF v_FoundFlag = TRUE THEN v_Salary := 1.1 * v_EmployeeData2.salary; ELSE v_Salary := 1.02 * v_EmployeeData2.salary; END IF; UPDATE employeez SET salary = v_Salary WHERE CURRENT OF c_Employee1; END LOOP; COMMIT; END; / SET SERVEROUTPUT OFF Pay_raise_5 - part 2 Note that on the previous slide we had FOR v_EmployeeData1. This is done to differentiate the uses.

SQL> SELECT * FROM employeez; EMPLOYEE_ID LAST_NAME FIRST_NAME MANAGER_ID SALARY SMITH JOHN ALLEN KEVIN DOYLE JEAN DENNIS LYNN BAKER LESLIE WARD CYNTHIA PETERS DANIEL SHAW KAREN DUNCAN SARAH LANGE GREGORY JONES TERRY ALBERTS CHRIS PORTER RAYMOND LEWIS RICHARD MARTIN KENNETH SOMMERS DENISE BLAKE MARION CLARK CAROL SCOTT DONALD WEST LIVIA FISHER MATTHEW ROSS PAUL KING FRANCIS TURNER MARY ADAMS DIANE JAMES FRED FORD JENNIFER ROBERTS GRACE DOUGLAS MICHAEL MILLER BARBARA JENSEN ALICE MURRAY JAMES pay_raise_5 PL/SQL procedure successfully completed. output