Download presentation
Presentation is loading. Please wait.
Published byAleesha Turner Modified over 8 years ago
1
Examples dealing with cursors and tables Please use speaker notes for additional information!
2
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 ----------- --------------- --------------- ---------- --------- 7369 SMITH JOHN 7902 800 7499 ALLEN KEVIN 7698 1600 7505 DOYLE JEAN 7839 2850 7506 DENNIS LYNN 7839 2750 7507 BAKER LESLIE 7839 2200 7521 WARD CYNTHIA 7698 1250 7555 PETERS DANIEL 7505 1250 7557 SHAW KAREN 7505 1250 7560 DUNCAN SARAH 7506 1250 7564 LANGE GREGORY 7506 1250 7566 JONES TERRY 7839 2975 7569 ALBERTS CHRIS 7839 3000 7600 PORTER RAYMOND 7505 1250 7609 LEWIS RICHARD 7507 1800 7654 MARTIN KENNETH 7698 1250 7676 SOMMERS DENISE 7507 1850 7698 BLAKE MARION 7839 2850 7782 CLARK CAROL 7839 2450 7788 SCOTT DONALD 7566 3000 7789 WEST LIVIA 7506 1500 7799 FISHER MATTHEW 7569 3000 7820 ROSS PAUL 7505 1300 7839 KING FRANCIS 5000 7844 TURNER MARY 7698 1500 7876 ADAMS DIANE 7788 1100 7900 JAMES FRED 7698 950 7902 FORD JENNIFER 7566 3000 7916 ROBERTS GRACE 7569 2875 7919 DOUGLAS MICHAEL 7799 800 7934 MILLER BARBARA 7782 1300 7950 JENSEN ALICE 7505 750 7954 MURRAY JAMES 7506 750 32 rows selected.
3
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.
4
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.
5
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 ---------- 7902 7698 7839 7698... 7902 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
6
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 ---------- 7902 7698 7839 7698... 7902 7698 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 7902. Therefore the flag stayed FALSE.
7
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 ---------- 7902 7698 7839 7698... 7902 7698 7839 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 7698. Logic - third fetch The IF statement was never equal because we were checking 7839 with the two things in the table: 7902 and 7698. Therefore the flag stayed FALSE. COUNT before WHILE 2 COUNT in WHILE before IF 2
8
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 ---------- 7902 7698 7839 7698... 7902 7698 7839 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, & 7839. 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 & 7839. 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
9
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 ---------- 7902 7698 7839 7698... 7902 7698 7839 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, & 7839. 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 & 7839. 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
10
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 ---------- 7902 7698 7839 7698... 7902 7698 7839 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 & 7839. 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
11
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. SQL> @ pay_raise_1a 7902 7698 7839 7505 7506 7507 7566 7569 7788 7799 7782 PL/SQL procedure successfully completed.
12
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.
13
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.
14
SQL> SELECT * FROM employeez; EMPLOYEE_ID LAST_NAME FIRST_NAME MANAGER_ID SALARY ----------- --------------- --------------- ---------- --------- 7369 SMITH JOHN 7902 816 7499 ALLEN KEVIN 7698 1632 7505 DOYLE JEAN 7839 3135 7506 DENNIS LYNN 7839 3025 7507 BAKER LESLIE 7839 2420 7521 WARD CYNTHIA 7698 1275 7555 PETERS DANIEL 7505 1275 7557 SHAW KAREN 7505 1275 7560 DUNCAN SARAH 7506 1275 7564 LANGE GREGORY 7506 1275 7566 JONES TERRY 7839 3272.5 7569 ALBERTS CHRIS 7839 3300 7600 PORTER RAYMOND 7505 1275 7609 LEWIS RICHARD 7507 1836 7654 MARTIN KENNETH 7698 1275 7676 SOMMERS DENISE 7507 1887 7698 BLAKE MARION 7839 3135 7782 CLARK CAROL 7839 2695 7788 SCOTT DONALD 7566 3300 7789 WEST LIVIA 7506 1530 7799 FISHER MATTHEW 7569 3300 7820 ROSS PAUL 7505 1326 7839 KING FRANCIS 5500 7844 TURNER MARY 7698 1530 7876 ADAMS DIANE 7788 1122 7900 JAMES FRED 7698 969 7902 FORD JENNIFER 7566 3300 7916 ROBERTS GRACE 7569 2932.5 7919 DOUGLAS MICHAEL 7799 816 7934 MILLER BARBARA 7782 1326 7950 JENSEN ALICE 7505 765 7954 MURRAY JAMES 7506 765 32 rows selected. SQL> @ pay_raise_3 PL/SQL procedure successfully completed. Pay_raise_3 Managers 7902 7698 7839 7505 7506 7507 7566 7569 7788 7799 7782 7369 is not in the manager list so Smith gets a 2% raise going from 800 to 816. 7507 was on the manager list so Baker got a 10% raise from 2200 to 2420.
15
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.
16
-- 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).
17
Output SQL> SELECT * FROM employeez; EMPLOYEE_ID LAST_NAME FIRST_NAME MANAGER_ID SALARY ----------- --------------- --------------- ---------- --------- 7369 SMITH JOHN 7902 832.32 7499 ALLEN KEVIN 7698 1664.64 7505 DOYLE JEAN 7839 3448.5 7506 DENNIS LYNN 7839 3327.5 7507 BAKER LESLIE 7839 2662 7521 WARD CYNTHIA 7698 1300.5 7555 PETERS DANIEL 7505 1300.5 7557 SHAW KAREN 7505 1300.5 7560 DUNCAN SARAH 7506 1300.5 7564 LANGE GREGORY 7506 1300.5 7566 JONES TERRY 7839 3599.75 7569 ALBERTS CHRIS 7839 3630 7600 PORTER RAYMOND 7505 1300.5 7609 LEWIS RICHARD 7507 1872.72 7654 MARTIN KENNETH 7698 1300.5 7676 SOMMERS DENISE 7507 1924.74 7698 BLAKE MARION 7839 3448.5 7782 CLARK CAROL 7839 2964.5 7788 SCOTT DONALD 7566 3630 7789 WEST LIVIA 7506 1560.6 7799 FISHER MATTHEW 7569 3630 7820 ROSS PAUL 7505 1352.52 7839 KING FRANCIS 6050 7844 TURNER MARY 7698 1560.6 7876 ADAMS DIANE 7788 1144.44 7900 JAMES FRED 7698 988.38 7902 FORD JENNIFER 7566 3630 7916 ROBERTS GRACE 7569 2991.15 7919 DOUGLAS MICHAEL 7799 832.32 7934 MILLER BARBARA 7782 1352.52 7950 JENSEN ALICE 7505 780.3 7954 MURRAY JAMES 7506 780.3 32 rows selected. SQL> @ pay_raise_4 PL/SQL procedure successfully completed.
18
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.
19
IF from part1 EMPLOYEE_ID MANAGER_ID ----------- ---------- 7555 7505 7557 7505 7600 7505 7820 7505 7950 7505 7560 7506 7564 7506 7789 7506 7954 7506 7609 7507 7676 7507 7788 7566 7902 7566 7799 7569 7916 7569 7499 7698 7521 7698 7900 7698 7844 7698 7654 7698 7934 7782 7876 7788 7919 7799 7505 7839 7506 7839 7507 7839 7782 7839 7698 7839 7569 7839 7566 7839 7369 7902 7839 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 7505 7506
20
-- 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.
21
SQL> SELECT * FROM employeez; EMPLOYEE_ID LAST_NAME FIRST_NAME MANAGER_ID SALARY ----------- --------------- --------------- ---------- --------- 7369 SMITH JOHN 7902 848.97 7499 ALLEN KEVIN 7698 1697.93 7505 DOYLE JEAN 7839 3793.35 7506 DENNIS LYNN 7839 3660.25 7507 BAKER LESLIE 7839 2928.2 7521 WARD CYNTHIA 7698 1326.51 7555 PETERS DANIEL 7505 1326.51 7557 SHAW KAREN 7505 1326.51 7560 DUNCAN SARAH 7506 1326.51 7564 LANGE GREGORY 7506 1326.51 7566 JONES TERRY 7839 3959.73 7569 ALBERTS CHRIS 7839 3993 7600 PORTER RAYMOND 7505 1326.51 7609 LEWIS RICHARD 7507 1910.17 7654 MARTIN KENNETH 7698 1326.51 7676 SOMMERS DENISE 7507 1963.23 7698 BLAKE MARION 7839 3793.35 7782 CLARK CAROL 7839 3260.95 7788 SCOTT DONALD 7566 3993 7789 WEST LIVIA 7506 1591.81 7799 FISHER MATTHEW 7569 3993 7820 ROSS PAUL 7505 1379.57 7839 KING FRANCIS 6655 7844 TURNER MARY 7698 1591.81 7876 ADAMS DIANE 7788 1167.33 7900 JAMES FRED 7698 1008.15 7902 FORD JENNIFER 7566 3993 7916 ROBERTS GRACE 7569 3050.97 7919 DOUGLAS MICHAEL 7799 848.97 7934 MILLER BARBARA 7782 1379.57 7950 JENSEN ALICE 7505 795.91 7954 MURRAY JAMES 7506 795.91 SQL> @ pay_raise_5 PL/SQL procedure successfully completed. output
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.