Click here to load reader
Upload
coleen-perry
View
251
Download
1
Embed Size (px)
Citation preview
Chapter SixteenCursors
Objective:– Introduction to cursors
– Use of cursors in a database record
– Implicit & explicit cursors
– Cursors & loops
– Cursors with parameters
COSC 641 Chapter 16: PL/SQL Cursors
2
Cursors
DEF:A cursor is a pointer to the context area.
Context area: Memory location containing info needed to complete the PL/SQL processing
COSC 641 Chapter 16: PL/SQL Cursors
3
Cursors (Example 1)
DECLAREV_ID Student.id%TYPE;V_Name Student.name%TYPE;V_Major Student.major%TYPE=‘COSC’;
CURSOR C_Student ISSELECT id, nameFROM StudentWHERE major=V_Major;
BEGINOPEN C_Student;LOOP FETCH C_Student INTO V_ID, V_Name;
EXIT WHEN C_Student%NOTFOUND;END LOOP;CLOSE C_Student;
END;
COSC 641 Chapter 16: PL/SQL Cursors
4
Cursors (Example 2)
CURSOR My_cursor IS
SELECT a.Name, b.Name, c.Name
FROM faculty a, student b, staff c
WHERE a.ID = b.ID AND
b.ID = c.ID;
COSC 641 Chapter 16: PL/SQL Cursors
5
Cursors
• Every SQL statement executed by the Oracle Server has an individual cursor associated with it.
– Explicit cursors– Implicit cursors
COSC 641 Chapter 16: PL/SQL Cursors
6
Explicit Cursors (from example 1)
• Keep track of the current row that is processing• Process row by row• Programmer can manually control the cursor• All in an active set
Active Set
1111 Mark
Cursor 1231 Cathy Current row
1421 Jack
1789 Sandy
COSC 641 Chapter 16: PL/SQL Cursors
7
Controlling Explicit Cursors:
1. Create a named SQL area; (DECLARE)
2. Identify the active set (OPEN)
3. Load the current row into variables (FETCH)
4. Test for existing rowsa. If found goto step 3
b. If not found goto step 5
5. Release the active set (CLOSE)
COSC 641 Chapter 16: PL/SQL Cursors
8
Explicit Cursor
OPEN
FETCH
How Many Rows
CLOSE
COSC 641 Chapter 16: PL/SQL Cursors
9
Cursors (Example 1)
DECLAREV_ID Student.id%TYPE;V_Name Student.name%TYPE;V_Major Student.major%TYPE=‘COSC’;
CURSOR C_Student ISSELECT id, nameFROM StudentWHERE major=V_Major;
BEGINOPEN C_Student;LOOP FETCH C_Student INTO V_ID, V_Name;
EXIT WHEN C_Student%NOTFOUND;END LOOP;CLOSE C_Student;
END;
COSC 641 Chapter 16: PL/SQL Cursors
10
Example
CREATE OR REPLACE FUNCTION myFac(Name_In IN student.Name%TYPE) RETURN NUMBER ASCURSOR a IS
SELECT MajorFROM studentWHERE Name = UPPER(Name_In);
a_rec a%ROWTYPE;Ret_val NUMBER;BEGIN
OPEN a;FETCH a INTO a_rec;If a%FOUND THEN
IF a_rec.Major = ‘COSC’ THENRet_val = 10;
ELSIF a_Rec.major = ‘MATH’ THENRet_val = 5;
END IF;END IF;CLOSE a;RETURN Ret_Val;
END;/
COSC 641 Chapter 16: PL/SQL Cursors
11
Declaring a Cursor
Syntax:
CURSOR C_Name [([Parameter [, parameter])]
IS
Select_Statement [RETURN ret]
[For UPDATE [of [COLUMN List]];
COSC 641 Chapter 16: PL/SQL Cursors
12
Example
CURSOR C_Faculty IS
SELECT *FROM FacultyWHERE Major=UPPER(‘COSC’);-----------------------------
CURSOR C_Dept IS
SELECT ID, NoFROM DeptWHERE Name=UPPER(‘COSC’);
-----------------------------
COSC 641 Chapter 16: PL/SQL Cursors
13
Opening the Cursor
Syntax:OPEN C_Name;
OPEN is an executable statement that:
1. Dynamically allocates memory for a context area2. Parses the SELECT statement3. Binds the input variables: (by obtaining their memory address)4. Identifies the active set
5. Positions the pointer just before the 1st row in the active set
COSC 641 Chapter 16: PL/SQL Cursors
14
Example
DECLARECURSOR C_Faculty IS
SELECT *FROM FacultyWHERE Major=‘COSC’;
CURSOR C_Dept ISSELECT ID, NoFROM DeptWHERE Name=‘COSC’;
V_F_Name Faculty.Name%TYPE;V_F_Salary Faculty.Salary%TYPE;V_D_Rec Dept%ROWTYPE;
BEGINOPEN C_Faculty;OPEN C_Dept;….
COSC 641 Chapter 16: PL/SQL Cursors
15
Fetching the Data
Syntax:FETCH C_Name INTO [record_name| V1, V2, …];
1. Retrieve the current row values into output variables2. Match each variable to the columns3. Test to see if the cursor points to a row
FETCH statement performs:1. Advance the pointer to the next row in the active set2. Reads the data from the current row into the output variables3. Exits the loop, if the pointer points to the end of the active set
COSC 641 Chapter 16: PL/SQL Cursors
16
Example
DECLARECURSOR C_Faculty IS
SELECT *FROM FacultyWHERE Major=UPPER(‘COSC’);
CURSOR C_Dept ISSELECT ID, NoFROM DeptWHERE
Name=‘COSC’;V_F_Name Faculty.Name%TYPE;V_F_Salary Faculty.Salary%TYPE;V_D_Rec Dept%ROWTYPE;
BEGINOPEN C_Faculty;OPEN C_Dept;
FOR I IN 1..5 LOOP FETCH C_Faculty INTO V_F_Name, V_F_Salary
………END LOOP;
LOOP FETCH C_Dept INTO V_D_Rec EXIT WHEN C_Dept%NOTFOUNDEND LOOP;END;/
COSC 641 Chapter 16: PL/SQL Cursors
17
Closing the Cursor
Syntax:CLOSE C_Name;
1. Close the cursor after the process is completed
2. Reopen the cursor, if it is needed
• OPEN_CURSORS = 50;
COSC 641 Chapter 16: PL/SQL Cursors
18
Illegal Cursor
DECLARECURSOR C_Student IS
SELECT id, name
FROM Student
WHERE major=V_Major;V_Major Student.major%TYPE=‘COSC’;
COSC 641 Chapter 16: PL/SQL Cursors
19
ROWNUM• Return a number indicating the order in which a row was selected from a table
DECLARECURSOR C1 IS
SELECT ID, NameFROM FacultyWHERE salary > 40000 AND ROWNUM <=100; --100 rows
CURSOR C2 ISSELECT *FROM (SELECT ID, Name
FROM faculty_temp WHERE salary> 40000 ORDER BY salary DESC)
WHERE ROWNUM <10; --first 9 sorted rowsBEGIN
………UPDATE faculty_tempSET ID = ROWNUM; --each row gets a different number
END;/
COSC 641 Chapter 16: PL/SQL Cursors
20
Explicit Cursor Attributes
• %FOUND Boolean TypeC_Dept%FOUND;
• %NOTFOUND Boolean TypeC_Dept%NOTFOUND;
• %ISOPEN Boolean Type C_Dept%ISOPEN;
• %ROWCOUNT Number TypeC_Dept%ROWCOUNT;
• %BULK_ROWCOUNTC_Dept% BULK_ROWCOUNT;
COSC 641 Chapter 16: PL/SQL Cursors
21
%ISOPEN
• You can fetch rows only when it is open• Use %ISOPEN to check
IF NOT C_faculty%ISOPEN THEN OPEN C_faculty;
END IF;LOOP
FETCH C_faculty into V_ID, V_Name;…
COSC 641 Chapter 16: PL/SQL Cursors
22
Explicit Cursor Attributes
• Use %ROWCOUNT cursor attribute to retrieve an exact number of rows• Use %NOTFOUND cursor attribute to determine when to exit the loop
SET SERVEROUTPUT ON;BEGIN
….OPEN C_faculty;LOOP
FETCH C_faculty INTO V_ID, V_Name;DBMS_OUTPUT.PUT_LINE (‘faculty’ || V_Name || ’has ID = ‘ || V_ID);EXIT WHEN
C_faculty %ROWCOUNT >5 ORC_faculty %NOTFOUND;
END LOOP;CLOSE C_faculty;
END;/
COSC 641 Chapter 16: PL/SQL Cursors
23
Cursor Exception
• INVALID_CURSOR
• TOO_MANY_ROWS
• %BULK_EXCEPTION
COSC 641 Chapter 16: PL/SQL Cursors
24
Example
DECLARECURSOR C_Faculty IS
SELECT *FROM Faculty;
V_F_Rec C_Faculty%ROWTYPE;BEGIN
AOPEN C_Faculty;
BFETCH C_Faculty INTO V_F_Rec;
CFETCH C_Faculty INTO V_F_Rec;
DCLOSE C_Faculty;
E F
END;
NameSalaryMary 40,000Mark 38,000
COSC 641 Chapter 16: PL/SQL Cursors
25
%FOUND & %NOTFOUND
C_Faculty%FOUND C_Faculty%NOTFOUND
A: ORA_1001 ORA_1001
B: NULL NULL
C: TRUE FALSE
D: TRUE FALSE
E: FALSE TRUE
F: ORA_1001 ORA_1001
COSC 641 Chapter 16: PL/SQL Cursors
26
%ISOPEN & %ROWCOUNT
C_Faculty%ISOPEN C_Faculty%ROWCOUNT
A: FALSE ORA_1001
B: TRUE 0
C: TRUE 1
D: TRUE 2
E: FALSE ORA_1001
COSC 641 Chapter 16: PL/SQL Cursors
27
• NO_DATA_FOUND– SELECT INTO….
• %NOTFOUND SQL%NOTFOUND– Cursor
COSC 641 Chapter 16: PL/SQL Cursors
28
Practice:
Create a PL/SQL block to find the top n salaries– Use a substitution parameter so user can input n.– Use loop to get names and salaries of the top n
faculty from faculty table.– Store the names and salaries in a temporary table.– Test for n=0 , and n > number of faculty– Assume no two faculty members have the same
salary.– Empty the table after each test.
COSC 641 Chapter 16: PL/SQL Cursors
29
Practice 2:
– Assume faculty members may have the same salaries. In this case list all of them;
– Mary 10000– Mark 5000– Sandy5000– John 2000– If n=2; list Mary, Mark, and Sandy– If n=3; list Mary, Mark, Sandy, and John
COSC 641 Chapter 16: PL/SQL Cursors
30
Cursors with Parameters
Syntax:CURSOR C_Name [ (P1, P2, …) ] IS
Select_Statement;
Where P1,P2: P [IN] datatype [[:= | DEFAULT ] exp]
1. Pass parameter values to a cursor when the cursor is opened & the query is executed
2. Open an explicit cursor several times with a different active set each time.
COSC 641 Chapter 16: PL/SQL Cursors
31
Example of Cursors with Parameters
DECLARE CURSOR C_Student (V_ID NUMBER, V_Major VARCHAR2) IS
SELECT ID, MajorFROM StudentWHERE Major = V_Major AND ID = V_ID;
BEGINOPEN C_Student (1111, ‘COSC’);….CLOSE C_Student;OPEN C_Student(2222, ‘MATH’);….CLOSE C_Student;
END;/
COSC 641 Chapter 16: PL/SQL Cursors
32
Cursors with Parameters
DECLAREV_VAR_ID Student.ID%TYPE;V_VAR_Major Student.Major%TYPE:=‘COSC’;
CURSOR C_Student (V_ID NUMBER, V_Major VARCHAR2) IS
SELECT ….
OPEN C_Student (1111, V_VAR_Major);CLOSE C_Student;OPEN C_Student (2222, ‘VART’);
COSC 641 Chapter 16: PL/SQL Cursors
33
Cursors with Parameters
CURSOR a (Name_IN VARCHAR2) ISSELECT MajorFROM StudentWHERE Name = UPPER(Name_IN);a_Rec a%ROWTYPE;ret_val NUMBER;
BEGINOPEN a (‘Sandy’);FETCH a INTO a_Rec;IF a%FOUND THEN
IF a_Rec.Major = ‘COSC’ THENRet_val = 10;
ELSIF a_Rec.Major = ‘MATH’ THENRet_val = 5;
END IF;END IF;CLOSE a;
END;
COSC 641 Chapter 16: PL/SQL Cursors
34
Open Cursor with Parameters
OPEN a (:My_pack.Name);
OPEN a (‘John’);
OPEN a (‘Mark’);
COSC 641 Chapter 16: PL/SQL Cursors
35
Cursor With Parameter:
CURSOR C_staff RETURN staff%ROWTYPE
IS
SELECT *
FROM staff
WHERE dept=UPPER(‘Cosc’);
COSC 641 Chapter 16: PL/SQL Cursors
36
Cursor with Default Value
DECLARE
CURSOR C1(low NUMBER DEFAULT 0,
high NUMBER DEFAULT 99) IS
SELECT …
COSC 641 Chapter 16: PL/SQL Cursors
37
FOR UPDATE Clause
Syntax:
SELECT …..
FROM …..
FOR UPDATE [OF Col_Ref] [NOWAIT]
- Lock the record before update or delete
COSC 641 Chapter 16: PL/SQL Cursors
38
Example
DECLARE
CURSOR C_Student ISSELECT Name, ID, GPA
FROM Student
WHERE Dept=‘COSC’
FOR UPDATE OF id, name;
COSC 641 Chapter 16: PL/SQL Cursors
39
WHERE CURRENT OF clause
Syntax:
WHERE CURRENT OF cursor• Use Cursors to update or delete the current row
• Include the FOR UPDATE clause in the cursor query to Lock the rows first
• Use WHERE CURRENT OF clause to reference the current row from an explicit cursor.
COSC 641 Chapter 16: PL/SQL Cursors
40
ExampleDECLARE
CURSOR C_Student ISSELECT Major, idFROM StudentWHERE Major = ‘COSC’FOR UPDATE NOWAIT;
BEGINFOR I IN C_StudentLOOP
UPDATE studentSET ID=student.Id * 100WHERE CURRENT OF C_Student;
END LOOP;COMMIT;
END;/
COSC 641 Chapter 16: PL/SQL Cursors
41
Cursor with subqueries
DECLARECURSOR C1 is
SELECT id, NameFROM facultyWHERE salary >
( SELECT AVG(Salary) FROM
Faculty );CURSOR C2 is
SELECT *FROM (SELECT Name,Salary
FROM Faculty ORDER BY Salary DESC,Name)
WHERE ROWNUM<21;Continued…
COSC 641 Chapter 16: PL/SQL Cursors
42
Cursor FOR loops:
Syntax:
FOR record_name IN cursor_name LOOP
statement1;
statement2;
….
END LOOP;
COSC 641 Chapter 16: PL/SQL Cursors
43
Cursor FOR loop:
BEGINFOR I IN C1LOOP
DBMS_OUTPUT.PUT_LINE(‘Above average Salary’ || I.Name);
END LOOP;FOR I IN C2LOOP
DBMS_OUTPUT.PUT_LINE(‘Twenty Top paid Faculty’ || I.NAME || I.SALARY);
END LOOP;END;/
COSC 641 Chapter 16: PL/SQL Cursors
44
NO_DATA_FOUND VS. %NOTFOUND
SELECT ….
INTO …..
FROM …..
WHERE …..
• NO_DATA_FOUND :Exception• %NOTFOUND :Flag
COSC 641 Chapter 16: PL/SQL Cursors
45
Implicit Cursor
INSERT
DELETE
UPDATE
SELECT INTO
COSC 641 Chapter 16: PL/SQL Cursors
46
Implicit Cursor
DECLARE
a faculty%ROWTYPE;
BEGIN
SELECT *
INTO a
FROM faculty
WHERE ID = 1111;
END;
COSC 641 Chapter 16: PL/SQL Cursors
47
Error Handling with Implicit Cursor
• NO_DATA_FOUND
• TOO_MANY_ROWS
COSC 641 Chapter 16: PL/SQL Cursors
48
Implicit Cursor Attributes
• SQL%FOUND
• SQL%NOTFOUND
• SQL%ROWCOUNT
• SQL%ISOPEN --Always Return False
COSC 641 Chapter 16: PL/SQL Cursors
49
Implicit Cursor
BEGIN
UPDATE classroom
SET NoOfSeats= 250
WHERE roomId=111;
IF SQL%NOTFOUND THEN
INSERT INTO classroom (roomId, NoOfSeats)
VALUES ( 111, 250);
END IF;
COSC 641 Chapter 16: PL/SQL Cursors
50
UPDATE, DELETE, INSERT
SET SERVEROUTPUT ON;BEGIN
UPDATE FacultySET Salary = Salary * 0.05WHERE Dept = ‘COSC’;DBMS_OUTPUT.PUT_LINE(‘Update’
|| SQL%ROWCOUNT);
END;/
COSC 641 Chapter 16: PL/SQL Cursors
51
Cursor Variable
• CURSOR
• CURSOR Variable
COSC 641 Chapter 16: PL/SQL Cursors
52
Cursor Variable
TYPE ref_Type IS REF CURSOR [RETURN TYPE];
Example:
DECLARE
TYPE stud_type REF CURSOR RETURN student%ROWTYPE;
stud_cv stud_type; -- Declar Cursor Variable
TYPE fac_type REF CURSOR RETURN faculty%ROWTYPE;
fac_cv fac_type;
COSC 641 Chapter 16: PL/SQL Cursors
53
Cursor Variable
Example:DECLARE
TYPE FacCur_Type IS REF CURSOR RETURN faculty%ROWTYPE;Fac FacCur_Type;-- Declar Cursor Variable--Process all rowsPROCEDURE p1(fac_cv IN FacCur_Type) IS
person faculty%ROWTYPE;BEGIN LOOP
FETCH fac_cv INTO person;EXIT WHEN fac_cv%NOTFOUND;DBMS_OUTPUT.PUT_LINE( person.name);
END LOOP;END;
COSC 641 Chapter 16: PL/SQL Cursors
54
Cursor Variable
BEGINOPEN Fac FOR
SELECT * FROM FacultyWHERE ROWNUM<=10;p1(fac);CLOSE Fac;
OPEN Fac FOR SELECT * FROM FacultyWHERE name LIKE ‘X%’;p1(Fac);CLOSE Fac;
END;/
COSC 641 Chapter 16: PL/SQL Cursors
55
Controlling Cursor VariablesCursor variables are controlled by OPEN-FOR, FETCH, CLOSE
DECLARETYPE FacCur_type IS REF CURSOR RETURN
faculty%ROWTYPE;Fac FacCur_type; -- Declar Cursor VariableFacRec faculty%ROWTYPE;
BEGINOPEN Fac FOR
SELECT * FROM FacultyWHERE salary>40000;
LOOPFETCH Fac INTO FacRec;EXIT WHEN Fac%NOTFOUND;DBMS_OUTPUT.PUT_LINE( FacRec.name);
END LOOP;CLOSE Fac;
END;/
COSC 641 Chapter 16: PL/SQL Cursors
56
EXAMPLE
DECLARETYPE Company_Type IS REF CURSOR
RETURN Company%ROWTYPE;company_cv Company_Type;company_Rec Company%ROWTYPE;
BEINGOPEN company_cv FOR
SELECT *FROM Company;
FETCH company_cv INTO company_Rec;CLOSE company_cv;
END;
COSC 641 Chapter 16: PL/SQL Cursors
57
Example:
DECLARECURSOR O_CUR IS
SELECT Customer_ID, Room_NoFROM OccupancyWHERE R_Date = TRUNC(SYSDATE);
O_Rec O_CUR%ROWTYPE;
BEGINOPEN O_CUR
LOOP FETCH O_CUR INTO O_Rec;EXIT WHEN O_CUR%NOTFOUND;F1 (O_Rec.customer_ID, O_Rec.Room_No);
END LOOP;CLOSE O_CUR;
END;/