1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen 2002-2008 Cursors These slides are licensed under.

Slides:



Advertisements
Similar presentations
BACS 485—Database Management Advanced SQL Overview Advanced DDL, DML, and DCL Commands.
Advertisements

12-1 Copyright  Oracle Corporation, All rights reserved. What Is a View? EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
Restricting and sorting data 16 May May May Created By Pantharee Sawasdimongkol.
1Eyad Alshareef Enhanced Guide to Oracle 10g Chapter 3: Using SQL Queries to Insert, Update, Delete, and View Data.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Extended SQL & The Relational Calculus.
Copyright  Oracle Corporation, All rights reserved. 2 Restricting and Sorting Data.
SQL: Part 4 Original materials supplied by the Oracle Academic Initiative (OAI). Edited for classroom use by Professor Laku Chidambaram. Not for commercial.
Copyright  Oracle Corporation, All rights reserved. 6 Writing Correlated Subqueries.
Advanced SQL (part 2) and SQL in practice CS263 Lecture 8.
Session 3: SQL (B): Parts 3 & 4 Original materials supplied by the Oracle Academic Initiative (OAI). Edited for classroom use by Professor Laku Chidambaram.
Logical Operators Operator AND OR NOT Meaning Returns TRUE if both component conditions are TRUE Returns TRUE if either component condition is TRUE Returns.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Introduction to Objects & Databases These.
o At the end of this lesson, you will be able to:  Describe the life-cycle development phases  Discuss the theoretical and physical aspects of a relational.
Copyright  Oracle Corporation, All rights reserved. I Introduction.
Lecture 4 PL/SQL language. PL/SQL – procedural SQL Allows combining procedural and SQL code PL/SQL code is compiled, including SQL commands PL/SQL code.
4-1 Copyright  Oracle Corporation, All rights reserved. Displaying Data from Multiple Tables.
Dr. Philip Cannata 1 Programming Languages Prolog Part 3 SQL & Prolog.
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.
PL/SQL A BRIEF OVERVIEW DAVID WILSON. PL/SQL User’s Guide and Reference PL/SQL User’s Guide and Reference.
Subqueries.
Copyright س Oracle Corporation, All rights reserved. I Introduction.
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.
Copyright  Oracle Corporation, All rights reserved. 4 Accessing a Database Using JBCL.
Copyright  Oracle Corporation, All rights reserved. 2 Restricting and Sorting Data.
SQL- DQL (Oracle Version). 2 SELECT Statement Syntax SELECT [DISTINCT] column_list FROM table_list [WHERE conditional expression] [GROUP BY column_list]
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Basic SQL These slides are licensed under.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Maintaining Session State in the Data.
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.
8 Producing Readable Output with SQL*Plus. 8-2 Objectives At the end of this lesson, you should be able to: Produce queries that require an input variable.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Maintaining Session State in the Data.
I-1 Copyright س Oracle Corporation, All rights reserved. Data Retrieval.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Implementing The Middle Tier These slides.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Advanced Relational Algebra These slides.
Copyright  Oracle Corporation, All rights reserved. 12 Creating Views.
Copyright  Oracle Corporation, All rights reserved. 8 Producing Readable Output with SQL*Plus.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Subqueries These slides are licensed under.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Object-Relational Database Programming.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Using Data Structures in Embedded Programs.
CS345 Project Presentation Language: H-- Mikhail Iakhiaev.
Copyright س Oracle Corporation, All rights reserved. I Introduction.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Relational State Assertions These slides.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Collection Operators These slides are.
Oracle CONNECT BY function JAVA WEB Programming. Emp 테이블의 내용 ( 상 / 하급자 계층구조 ) SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
2-1 Limiting Rows Using a Selection “…retrieve all employees in department 10” EMP EMPNO ENAME JOB... DEPTNO 7839KINGPRESIDENT BLAKEMANAGER CLARKMANAGER.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Grouping These slides are licensed under.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Collection Operators These slides are.
Copyright س Oracle Corporation, All rights reserved. 12 Creating Views.
1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Inner Joins These slides are licensed.
1-1 Copyright  Oracle Corporation, All rights reserved. Logging In to SQL*Plus From Windows environment:From Windows environment: From command line:From.
Copyright  Oracle Corporation, All rights reserved. 2 Restricting and Sorting Data.
Copyright  Oracle Corporation, All rights reserved. Introduction.
Communicating with a RDBMS Using SQL Database SQL> SELECT loc 2 FROM dept; SQL> SELECT loc 2 FROM dept; SQL statement is entered Statement is sent to database.
Relational Normalization Theory
Subqueries.
Subqueries Schedule: Timing Topic 25 minutes Lecture
Manipulating Data Schedule: Timing Topic 40 minutes Lecture
Interacting with the Oracle Server
Writing Correlated Subqueries
What Is a View? EMPNO ENAME JOB EMP Table EMPVU10 View
Chapter 03 DBMS.
Lecture 16 : The Relational Data Model
Subqueries Schedule: Timing Topic 25 minutes Lecture
Restricting and Sorting Data
Lecture 16 : The Relational Data Model
Subqueries Schedule: Timing Topic 25 minutes Lecture
Copyright © Ellis Cohen
Presentation transcript:

1 Theory, Practice & Methodology of Relational Database Design and Programming Copyright © Ellis Cohen Cursors These slides are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License. For more information on how you may use them, please see

2 © Ellis Cohen Overview of Lecture PL/SQL Cursors Cursor-Based Fetch & Scrollability Cursor Sensitivity Cursor-Based Update Cursor Variables & Parameters Nested Cursors

3 © Ellis Cohen PL/SQL Cursors

4 © Ellis Cohen Cursors as Iterators Iterators are programming language objects which iterate over some sort of collection. Cursors are a special kind of iterator built-in to SQL-based embedded languages which iterate over result sets (i.e. the result of a query)

5 © Ellis Cohen Cursors DECLARE CURSOR curs IS SELECT deptno, count(*) AS knt FROM Emps WHERE job = 'ANALYST' GROUP BY deptno; BEGIN FOR aRec IN curs LOOP pl( aRec.deptno || ': ' || aRec.knt ); END LOOP; END; Separates query description from the use of the result set

6 © Ellis Cohen Parameterized Cursors DECLARE CURSOR curs( aJob varchar ) IS SELECT deptno, count(*) AS knt FROM Emps WHERE job = aJob GROUP BY deptno; BEGIN FOR aRec IN curs( 'ANALYST' ) LOOP pl( aRec.deptno || ': ' || aRec.knt ); END LOOP; END;

7 © Ellis Cohen Package Cursors BEGIN FOR aRec IN EmpPkg.DeptsByJobsCurs( :job ) LOOP pl( … ) END LOOP; EXCEPTION WHEN OTHERS THEN plerr(); END; Instantiates a cursor ShowDeptsByJob( :job ) PACKAGE BODY EmpPkg AS CURSOR DeptsByJobsCurs( theJob varchar ) IS SELECT deptno, count(*) AS knt FROM Emps WHERE job = theJob GROUP BY deptno; … Cursors can be defined in packages

8 © Ellis Cohen Cursor-Based Fetch & Scrollability

9 © Ellis Cohen Explicit Fetch Control DECLARE CURSOR curs … BEGIN FOR rec IN curs LOOP statements END LOOP; END; DECLARE CURSOR curs … rec curs%ROWTYPE; BEGIN OPEN curs; FETCH curs INTO rec; WHILE curs%FOUND LOOP statements FETCH curs INTO rec; END LOOP; CLOSE curs; END;

10 © Ellis Cohen Fetching Example DECLARE CURSOR curs( aJob varchar ) IS SELECT ename, deptno FROM Emps WHERE job = aJob; rec curs%ROWTYPE; BEGIN OPEN curs('ANALYST'); LOOP FETCH curs INTO rec; EXIT WHEN curs%NOTFOUND; INSERT INTO CoolEmps VALUES rec; END LOOP; CLOSE curs; END;

11 © Ellis Cohen Cursor Attributes %FOUND Before the first fetch from curs, curs%FOUND is NULL. Afterwards, it is TRUE if the last fetch returned a row, or FALSE if there are no rows left. %NOTFOUND Before the first fetch from curs, curs%FOUND is NULL. Afterwards, it is FALSE if the last fetch returned a row, or TRUE if there are no rows left. %ROWCOUNT curs%ROWCOUNT returns the number of rows fetched (0 if the cursor is not yet open) %ISOPEN curs%ISOPEN return TRUE if the cursor is open, FALSE if it is not

12 © Ellis Cohen More Fetching Example DECLARE CURSOR c1 IS SELECT * FROM Emps1 ORDER BY empno; CURSOR c2 IS SELECT * FROM Emps2 ORDER BY empno; jemps EmpPkg.EmpList; e1 c1%ROWTYPE; e2 c2%ROWTYPE; BEGIN OPEN c1; FETCH c1 INTO e1; OPEN c2; FETCH c2 INTO e2; WHILE (c1%FOUND or c2%FOUND) LOOP IF (c2%NOTFOUND or (c1%FOUND and (e1.empno < e2.empno))) THEN jemps(jemps.count + 1) := e1; FETCH c1 INTO e1; ELSE jemps(jemps.count + 1) := e2; FETCH c2 INTO e2; END IF; END LOOP; CLOSE c1; CLOSE c2; EmpPkg.DoSomethingCoolWith( jemps ); END; What does this do?

13 © Ellis Cohen Answer: More Fetching Example Emps1 and Emps2 are tables of employees, and we use the cursors c1 and c2 to iterate through them in order of their employee number. We compare the employees pointed to by c1 and c2, and take the employee with the smallest employee number, append it to the jemps array, and move that cursor forward to point to the next employee (in order) in the corresponding table. This is a MERGE, and jemps will contain all the employees, in order of their employee number. (SELECT empno FROM Emps1 UNION ALL (SELECT empno FROM Emps2) ORDER BY empno should be implemented internally in essentially the same way

14 © Ellis Cohen Scrollability Can FETCH only move forward through the result set, or can it move backwards or be repositioned to arbitrary rows? Oracle: Forward-Only SQL Server: Based on options available when defining the cursor

15 © Ellis Cohen Cursor Sensitivity

16 © Ellis Cohen Cursor Sensitivity Once we start iterating through the rows selected by a cursor, are the membership or contents of those rows sensitive to database changes made by this user or other users? Oracle: NO SQL Server: Based on options available when defining the cursor

17 © Ellis Cohen No Membership Sensitivity DECLARE CURSOR curs IS SELECT * from Emps WHERE job = 'ANALYST'; rec curs%ROWTYPE; BEGIN OPEN curs; DELETE Emps WHERE job = 'ANALYST'; COMMIT; LOOP FETCH curs INTO rec; EXIT WHEN curs%NOTFOUND; pl( rec.ename || ' ' || rec.deptno ); END LOOP; CLOSE curs; END; DELETE has no effect on output

18 © Ellis Cohen No Content Sensitivity DECLARE CURSOR curs IS SELECT * from Emps WHERE job = 'ANALYST'; rec curs%ROWTYPE; BEGIN OPEN curs; UPDATE Emps SET deptno = 10 WHERE job = 'ANALYST'; COMMIT; LOOP FETCH curs INTO rec; EXIT WHEN curs%NOTFOUND; pl( rec.ename || ' ' || rec.deptno ); END LOOP; CLOSE curs; END; UPDATE has no effect on output

19 © Ellis Cohen Cursor-Based Update

20 © Ellis Cohen Cursor FOR UPDATE CURSOR curs IS SELECT sal FROM Emps WHERE deptno = 30 FOR UPDATE; Specifies that the cursor will be used to update the underlying table Emps

21 © Ellis Cohen Cursored Update Model empno ename deptno sal comm 7499ALLEN MARTIN BLAKE KING TURNER STERN Emps Result Set curs FOR UPDATE maintains the connection (using ROWIDS) between a tuple in the Result Set and the corresponding tuple in the table that was queried CURRENT OF curs

22 © Ellis Cohen Programming with FOR UPDATE DECLARE CURSOR curs IS SELECT sal FROM Emps WHERE deptno = 30 FOR UPDATE; BEGIN FOR rec IN curs LOOP IF (...) THEN UPDATE Emps SET sal = sal * 1.05 WHERE CURRENT OF curs; END IF; END LOOP; END; enables the selected tuples to be updated through the cursor The tuple in Emps last fetched through the cursor Some complex test

23 © Ellis Cohen Update Sensitivity DECLARE CURSOR curs IS SELECT * from Emps WHERE deptno = 30 FOR UPDATE; rec curs%ROWTYPE; BEGIN OPEN curs; UPDATE Emps SET sal = 100 WHERE deptno = 30; LOOP FETCH curs INTO rec; EXIT WHEN curs%NOTFOUND; UPDATE Emps SET sal = sal * 1.1 WHERE CURRENT OF curs; END LOOP; CLOSE curs; END; What will the value of sal be for tuples where deptno = 30? Also, if the cursor was scrollable, what salary value would be obtained when scrolling back to a previously updated tuple?

24 © Ellis Cohen Cursor Variables & Parameters

25 © Ellis Cohen Cursors vs Ref Cursors CURSOR curs IS SELECT * from Emps WHERE deptno = 30 FOR UPDATE; does NOT declare a cursor variable. It is more like a TYPE or PROCEDURE declaration. Although we can open and fetch from it OPEN curs; FETCH curs INTO aRec; There is no way to store an open cursor into a variable pass an open cursor as a parameter return an open cursor from a function That's what REF CURSORs are for!

26 © Ellis Cohen Ref Cursors DECLARE TYPE EmpCursorType IS REF CURSOR RETURN Emps%ROWTYPE; cv EmpCursorType; rec cv%ROWTYPE; BEGIN IF :mtype = 'job' THEN OPEN cv FOR SELECT * FROM Emps WHERE (job LIKE :match); ELSIF :mtype = 'ename' THEN OPEN cv FOR SELECT * FROM Emps WHERE (ename LIKE :match); END IF; LOOP FETCH cv INTO rec; EXIT WHEN cv%NOTFOUND; pl( rec.ename || ' ' || rec.deptno ); END LOOP; CLOSE cv; END; Dynamically choose query to process Type checking

27 © Ellis Cohen Weak Ref Cursors DECLARE TYPE EmpCursorType IS REF CURSOR; cv EmpCursorType; rec Emps%ROWTYPE; BEGIN IF :mtype = 'job' THEN OPEN cv FOR SELECT * FROM Emps WHERE (job LIKE :match); ELSIF :mtype = 'ename' THEN OPEN cv FOR SELECT * FROM Emps WHERE (ename LIKE :match); END IF; LOOP FETCH cv INTO rec; EXIT WHEN cv%NOTFOUND; pl( rec.ename || ' ' || rec.deptno ); END LOOP; CLOSE cv; END; Weak REF CURSORs do not specify a RETURN type. No early type checking Type checking at FETCH-time

28 © Ellis Cohen SYS_REFCURSOR DECLARE cv SYS_REFCURSOR; rec Emps%ROWTYPE; BEGIN IF :mtype = 'job' THEN OPEN cv FOR SELECT * FROM Emps WHERE (job LIKE :match); ELSIF :mtype = 'ename' THEN OPEN cv FOR SELECT * FROM Emps WHERE (ename LIKE :match); END IF; LOOP FETCH cv INTO rec; EXIT WHEN cv%NOTFOUND; pl( rec.ename || ' ' || rec.deptno ); END LOOP; CLOSE cv; END; Built-in Weak REF CURSOR type

29 © Ellis Cohen Returning REF CURSORs SQL> variable rc REFCURSOR; SQL> execute :rc := EmpPkg.GetEmpByJob( 'ANALYST' ); SQL> print :rc Useful hack FUNCTION GetEmpByJob( aJob varchar ) RETURN SYS_REFCURSOR IS cv SYS_REFCURSOR; BEGIN OPEN cv FOR SELECT * FROM Emps WHERE (job = aJob) or (aJob IS NULL); RETURN cv; END; In EmpPkg CURSOR declarations are simpler Functions that return cursors can do error checking and raise exceptions

30 © Ellis Cohen Returning Result Sets SQL> variable rc REFCURSOR; SQL> execute :rc := EmpPkg.GetEmpByJob( 'ANALYST' ); SQL> print :rc EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO SCOTT ANALYST APR FORD ANALYST DEC SQL> execute :rc := EmpPkg.GetEmpByJob( null ); SQL> print :rc EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO SMITH CLERK DEC ALLEN SALESMAN FEB WARD SALESMAN FEB JONES MANAGER APR MARTIN SALESMAN SEP BLAKE MANAGER MAY CLARK MANAGER JUN SCOTT ANALYST APR KING PRESIDENT 17-NOV TURNER SALESMAN SEP ADAMS CLERK MAY JAMES CLERK DEC FORD ANALYST DEC MILLER CLERK JAN

31 © Ellis Cohen Using a REF Cursor DECLARE cv SYS_REFCURSOR; rec EmpPkg.DeptKntRec; BEGIN cv := EmpPkg.GetDeptsByJobsCurs( :job ); LOOP FETCH cv INTO aRec; EXIT WHEN cv%NOTFOUND; -- use rec to build part of result page END LOOP; EXCEPTION WHEN OTHERS THEN … -- generate error page … -- return; END; … -- build rest of result page & return END; Returns a REF cursor ShowDeptsByJob( :job )

32 © Ellis Cohen Defining & Opening a REF Cursor TYPE DeptKntRec IS RECORD ( deptno int, knt int ); FUNCTION GetDeptsByJobsCurs( theJob varchar ) RETURN SYS_REFCURSOR IS cv SYS_REFCURSOR; BEGIN OPEN cv FOR SELECT deptno, count(*) AS knt FROM Emps WHERE job = theJob GROUP BY deptno; RETURN cv; END; In EmpPkg

33 © Ellis Cohen Nested Cursors

34 © Ellis Cohen List Employees in Each Dept DECLARE fstr varchar(200); sep varchar(5); BEGIN FOR d IN (SELECT deptno,dname FROM Depts ORDER BY dname) LOOP fstr := d.dname; sep := ': '; FOR e IN (SELECT ename FROM Emps WHERE deptno = d.deptno) LOOP fstr := fstr || sep || e.ename; sep := ', '; END LOOP; pl( fstr ); END LOOP; END; ACCOUNTING: CLARK, KING, MILLER OPERATIONS RESEARCH: SMITH, JONES, SCOTT, ADAMS, FORD SALES: ALLEN, WARD, MARTIN, BLAKE, TURNER, JAMES

35 © Ellis Cohen Nested Cursors ACCOUNTING dname CLARK CURSOR(…) KING MILLER OPERATIONS dname RESEARCH SMITH JONES SCOTT … (EMPTY) … dname CURSOR CURSOR(…)

36 © Ellis Cohen Formatting with Nested Cursors DECLARE curs SYS_REFCURSOR := GetDeptEmpCursNest(); ncurs SYS_REFCURSOR; fstr varchar(200); sep char(2) ; nstr varchar(50); BEGIN LOOP FETCH curs INTO fstr, ncurs; EXIT WHEN curs%notfound; sep := ': '; LOOP FETCH ncurs INTO nstr; EXIT WHEN ncurs%notfound; fstr := fstr || sep || nstr; sep := ', '; END LOOP; pl( fstr ); END LOOP; END; Each tuple consists of a string (dname) plus an [opened] REF CURSOR Lists employees in each department

37 © Ellis Cohen Building Nested Cursors FUNCTION GetDeptEmpCursNest RETURN SYS_REFCURSOR IS cv SYS_REFCURSOR; BEGIN OPEN cv FOR SELECT dname, CURSOR( SELECT ename FROM Emps e WHERE e.deptno = d.deptno) FROM Depts d ORDER BY dname; RETURN cv; END; / Nested CURSOR expression Each tuple consists of a string (dname) plus an [opened] REF CURSOR