Вы находитесь на странице: 1из 22

Explicit Cursor in For-Loop

----------------------Here we demonstrate a variation of the for-loop specifically used with cursors. The synatx is as follows for <record index variable> in <cursor name> loop .. end loop; <record index variable> is automatically declared by Oracle to be a record of a type identical to the type of a tuple in the cursor No need to use explicit OPEN, FETCH, and CLOSE because the magic Oracle FOR-loop performs the following logic: 1. OPENs the cursor at initialization 2. FETCHes into the record index variable the current record from the cursor(if any) at the begining of every iteration 3. Tests if CURSOR%FOUND after the FETCH. If no it exits the loop, otherwise it continues. 4. CLOSEs the cursor on loop exit.

declare cursor C1 is SELECT S.snum, FROM S, SPJ, P WHERE S.snum = AND SPJ.pnum = AND SPJ.jnum = S.sname, P.pname SPJ.snum P.pnum 'J2';

redparts number(3) := 0; -- redparts is limited 3 places -- redparts initialized to 0 begin dbms_output.put_line('These suppliers supplied ' || 'these parts to project J2'); -- FOR loop -- Automatically OPENs cursor C1 -- and FETCHes on each repetition. for C1Record in C1 loop -- auto FETCH into C1Record here dbms_output.put_line( 'Row Number '||C1%rowcount||' is '|| C1Record.snum ||' '|| C1Record.sname||' '|| C1Record.pname); end loop; dbms_output.new_line; dbms_output.put_line('The Red Parts are:'); -- Here the CURSOR is

-- even anonymously defined as part -- of the cursor for loop for i in (SELECT * -- anonymous cursor starts FROM P WHERE color='Red') loop dbms_output.put_line( i.pname || ' (' || rtrim(i.pnum) || ')'); redparts := redparts + 1; end loop; dbms_output.put_line('Total Red Parts: ' || redparts); end;

/ Database Procedure
----here we create a database procedure named 'getPartsByColor' this would be run from within SQLPLUS by saying exec getPartsByColor('Blue');

create or replace procedure getPartsByColor(p_color in P.color%type) is partsfound number(3) := 0; cursor ByColor is-- declare a cursor SELECT * FROM P WHERE color= p_color; ByColorRow ByColor%ROWTYPE; begin -- the start of the procedure dbms_output.put_line(p_color || ' Parts in the database are:'); open ByColor; fetch ByColor into ByColorRow; while ByColor%FOUND loop dbms_output.put_line( ByColorRow.pname || ' (' || rtrim(ByColorRow.pnum) || ')'); partsfound := partsfound + 1; fetch ByColor into ByColorRow; end loop; close ByColor; dbms_output.put_line('Total ' || p_color || ' Parts: ' || partsfound); end; -- end of declaration of getPartsByColor prompt To run this procedure type prompt exec getPartsByColor('Green'); prompt at the SQLPLUS prompt.

Cursor with a Parameter in a Database Procedure ------here we create a database procedure named 'getPartsByColor' this would be run from within SQLPLUS by saying exec getPartsByColor('Blue'); the same way as before. In this version, the cursor has a parameter and is declared separately

create or replace procedure getPartsByColor(p_color in P.color%type) is partsfound number(3) := 0; cursor getparts (c_color in P.color%type) is SELECT * FROM P WHERE color= c_color; -- notice that WHERE clause refers to -- the parameter of the cursor begin -- the start of the produre dbms_output.put_line(p_color || ' Parts in the database are:'); for i in getparts(p_color) loop dbms_output.put_line( i.pname || ' (' || rtrim(i.pnum) || ')'); partsfound := partsfound + 1; end loop; dbms_output.put_line('Total ' || p_color || ' Parts: ' || partsfound); end; -- end of declaration of getPartsByColor / prompt To run this procedure type prompt exec getPartsByColor('Green'); prompt at the SQLPLUS prompt http://www.slideshare.net/spin_naresh/plsql-cursors

In out parameters:

Oracle Database Interaction Using ODP.NET and ASP.NET: Accessing Stored Procedures, Functions - What about IN OUT parameter in a PL/SQL procedure? (Page 3 of 5 ) If we summarize our experience with IN as well as OUT of PL/SQL procedures, we can understand that IN is used for passing information to a PL/SQL procedure and OUT is used to get back the information from a PL/SQL procedure. But what about IN OUT? It is just the combination of both IN and OUT together. In brief, the same parameter can be used to pass and return the values. In our example below, we are trying to create a stored procedure with two parameters. One will be of type IN and the other will be of type IN OUT. Let us see the stored procedure first. PROCEDURE "SCOTT"."P_INCREASESALARY" ( "ENO" IN NUMBER, "INCSAL" IN OUT NUMBER) IS emp_sal emp.SAL%type; BEGIN update emp set sal = sal + "INCSAL" where empno = "ENO"; select sal into "INCSAL" from emp where empno = "ENO"; END "P_INCREASESALARY"; Within the above stored procedure, we need to understand several issues. The name of the stored procedure will be P_INCREASESALARY. It contains two parameters, ENO and INCSAL. ENO is an IN parameter (which means we can only pass values through it, but not return any values). INCSAL is an IN OUT parameter (which means we can pass and retrieve values). Within the body of the stored procedure, I am trying to update the particular employee (specified by ENO) with an incremental salary (specified by INCSAL). After successful updating, I would like to return the latest salary of the same employee back to the application. For that purpose, I am using a SELECT statement to retrieve the latest salary of the employee and assign it to INCSAL. The wonder is that you need not return it, as you generally do using a function. It would automatically reflect (as it is similar to a reference pointer) in the calling application -- in this case, it is an ASP.NET application. I hope that you understood the above stored procedure. Now, we shall see about accessing it using ODP.NET, in the next

PLSQL Cursors
2 years ago

Email Favorite Download Embed Zipcast More 340 x 284 425 x 355 510 x 426 595 x 497

Like this presentation? 0 comments

Embed Video Post Comment

Subscribe to comments

Edit your comment

Update

Cancel

Speaker Notes on slide 17

It contains info about SQL stmt. Set of data returned or affected

in the Oracle 11g Database Process Global Area(PGA)

PLSQL Cursors - Presentation Transcript


1. PL/SQL Cursors By Praveen & Naresh 2. What is Cursors ? o SQL: o > SELECT * FROM employee; o Oracle RDBMS : Assigns a private work area for that stmt. 3. contd.. o PL/SQL cursor is a mechanism by which o you can NAME that work area o and o manipulate the information within it 4. Declare/Open/Fetch/Close o CURSOR emp_cur IS SELECT * FROM employee ; o Open emp_cur ; o Fetch emp_cur INTO emp_rec; o CLOSE emp_cur ; 5. Types of cursors o Two Types: o 1) Implicit o 2) Explicit 6. Cursor Attributes

Attribute: %FOUND %ISOPEN %NOTFOUND %ROWCOUNT 7. Implicit Cursors o DML Statements o INSERT, UPDATE, DELETE o SELECT statement with INTO clause 8. Single Row Implicit Cursors o DECLARE o e_id employee.empid%TYPE; o e_name employee.empname%TYPE; o BEGIN o SELECT empid, empname INTO e_id, e_name o FROM employee where empid=23; o dbms_output.put_line( SQL%ROWCOUNT ); o END; o / 9. Multiple Row Implicit Cursors(1) o BEGIN o UPDATE employee SET emp_sal= emp_sal + 5000 o where emp_deptid=1; o IF SQL%FOUND THEN o dbms_output.put_line( ' Updated: '|| SQL%ROWCOUNT ); o ELSE o dbms_output.put_line( 'Nothing Updated' ); o END; o / 10. Multiple Row Implicit Cursors(2) o BEGIN o FOR e_cursor IN ( SELECT e_name FROM employee ) LOOP o dbms_output.put_line( e_cursor.e_name ); o END LOOP; o END; o / 11. Cursor FOR Loop o Scope : Inside FOR Loop o Cursor Index : o - a pointer to Query work area. o - Query work area is a memory region ( context area ) o Note: o SQL%ROWCOUNT attribute returns NULL . 12. Explicit Cursors o Define inside declaration block o Static or dynamic SELECT stmt. o Open/Fetch/Close
o o o o o

13. Syntax OPEN cursor_name [ (param1 , param2 ,....) ] FETCH cursor_name INTO (variable1,variable2,....) FETCH cursor_name INTO record_variable; CLOSE cursor_name ; 14. Static Explicit Cursors o SQL SELECT behavior doesn't change 15. Static Cursor o DECLARE o eid employee.empid%TYPE; o ename employee.empname%TYPE; o CURSOR cur IS o SELECT empid, empname FROM employee ; o BEGIN o OPEN cur ; o LOOP o FETCH cur INTO eid , ename ; o EXIT WHEN cur%NOTFOUND ; o dbms_output.put_line( 'NAME' || cur . ename ); o END LOOP; o CLOSE cur ; o END; o / 16. Eg- Cursor For Loop o DECLARE o CURSOR C IS o SELECT empid AS eid , empname AS ename FROM employee ; o BEGIN o FOR i IN C LOOP o dbms_output.put_line( 'NAME' || i.ename ); o END LOOP ; o END; o / 17. Static Cursor( Record) o DECLARE o TYPE emp_record IS RECORD ( eid NUMBER, ename VARCHAR2(30) ); o employee EMP_RECORD ; o CURSOR cur IS SELECT empid, empname FROM employee ; o BEGIN o OPEN cur ; o LOOP o FETCH cur INTO employee ; o EXIT WHEN cur%NOTFOUND ; o dbms_output.put_line( 'NAME' || employee . ename ); o END LOOP; o CLOSE cur ; o END;
o o o o

o / 18. Static Cursor( Record+FOR Loop) o DECLARE o TYPE emp_record IS RECORD ( eid NUMBER, ename VARCHAR2(30) ); o explicit_employee EMP_RECORD ; o CURSOR cur IS SELECT empid, empname FROM employee ; o BEGIN o FOR i IN cur LOOP o explicit_employee := i; o dbms_output.put_line( 'NAME' || explicit_employee . ename ); o END LOOP; o END; o / o Note: No Data Found , No error is raised 19. Static Cursor( No rows) o DECLARE o TYPE emp_record IS RECORD ( eid NUMBER, ename VARCHAR2(30) ); o employee EMP_RECORD ; o CURSOR cur IS SELECT empid, empname FROM employee where empid = -1 ; o BEGIN o OPEN cur ; o LOOP o FETCH cur INTO employee ; o IF cur%NOTFOUND THEN o IF cur%ROWCOUNT = 0 THEN o dbms_output.put_line( 'No Data Found' ); o END IF; o EXIT; o ELSE o dbms_output.put_line( 'NAME' || employee . ename ); o END IF; o END LOOP; o CLOSE cur ; o END; o / 20. Thanks

spin_naresh + Follow 388 views, 0 favs, 1 embed

Related

Oracle 807 views

Chinabankppt 381 views

About this presentation


Usage Rights
All Rights Reserved

Stats

0 Favorites 0 Comments 26 Downloads 385 Views on SlideShare 3 Views on Embeds 388 Total Views

Embed views

3 views on http://osntraining.wordpress.com

Accessibility
View text version

Additional Details

Uploaded via SlideShare Uploaded as Microsoft PowerPoint

Flagged as inappropriate Flag as inappropriate Flag as inappropriate Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details. Cancel

File a copyright complaint

Categories

Business & Mgmt Technology

Follow SlideShare

Twitter Facebook SlideShare Blog

1 tweet 5 shares WordPress Blogger More

OPEN caller_cur; LOOP FETCH caller_cur INTO caller_rec; EXIT WHEN NOT caller_cur%FOUND; UPDATE call SET caller_id = caller_rec.caller_id WHERE call_timestamp < SYSDATE; IF SQL%FOUND THEN DBMS_OUTPUT.PUT_LINE ( 'Calls updated for ' || caller_rec.caller_id); END IF; END LOOP; CLOSE caller_cur;

Sql%rowcount

You can declare explicit cursors in any declaration section of a PL/SQL block. This means that you can declare such cursors within packages and at the package level; not within a particular procedure or function in the package. We'll explore packages in general in Chapter 18. You may want to look ahead at that chapter to acquaint yourself with the basics of packages before plunging into the topic of declaring cursors in packages. Here are two examples:
CREATE OR REPLACE PACKAGE book_info

IS

CURSOR titles_cur IS SELECT title FROM book;

CURSOR books_cur (title_filter_in IN book.title%TYPE) RETURN book%ROWTYPE IS SELECT * FROM book WHERE title LIKE title_filter_in; END;

15.3.3.1 Examples of explicit cursors


The following examples illustrate the variety of possible fetches:

Fetch into a PL/SQL record:


DECLARE CURSOR company_cur is SELECT ...; company_rec company_cur%ROWTYPE; BEGIN OPEN company_cur; FETCH company_cur INTO company_rec;

Fetch into a variable:


FETCH new_balance_cur INTO new_balance_dollars;

Table 15-3. Values returned by cursor attributes


Name cursor%FOUND Description Returns TRUE if a record was fetched successfully. Returns the number of records fetched from the specified cursor at that point in time. Returns TRUE if the specified cursor is open.

cursor%NOTFOUND Returns TRUE if a record was not fetched successfully. cursor%ROWCOUNT cursor%ISOPEN

CREATE OR REPLACE PROCEDURE change_author_name ( old_name_in IN books.author%TYPE, new_name_in IN books.author%TYPE, changes_made_out OUT BOOLEAN) IS BEGIN UPDATE books SET author = new_name_in WHERE author = old_name_in; changes_made_out := SQL%FOUND; END;

CREATE OR REPLACE PROCEDURE change_author_name ( old_name_in IN books.author%TYPE, new_name_in IN books.author%TYPE, changes_made_out OUT BOOLEAN) IS BEGIN UPDATE books SET author = new_name_in WHERE author = old_name_in; changes_made_out := SQL%FOUND; END;

Attribute %ISOPEN %FOUND

Explanation - Returns TRUE if the cursor is open, FALSE if the cursor is closed. - Returns INVALID_CURSOR if cursor is declared, but not open; or if cursor has been closed. - Returns NULL if cursor is open, but fetch has not been executed.

- Returns TRUE if a successful fetch has been executed. - Returns FALSE if no row was returned. - Returns INVALID_CURSOR if cursor is declared, but not open; or if cursor has been closed. %NOTFOUND - Return NULL if cursor is open, but fetch has not been executed. - Returns FALSE if a successful fetch has been executed. - Returns TRUE if no row was returned. - Returns INVALID_CURSOR if cursor is declared, but not open; or if cursor has been closed. - Returns the number of rows fetched. %ROWCOUNT - The ROWCOUNT attribute doesn't give the real row count until you have iterated through the entire cursor. In other words, you shouldn't rely on this attribute to tell you how many rows are in a cursor after it is opened.

Below is an example of how you might use the %NOTFOUND attribute. CREATE OR REPLACE Function FindCourse ( name_in IN varchar2 ) RETURN number IS cnumber number; CURSOR c1 IS SELECT course_number from courses_tbl where course_name = name_in; BEGIN open c1; fetch c1 into cnumber; if c1%notfound then cnumber := 9999; end if;

close c1; RETURN cnumber; END;

Attribute %ISOPEN

Explanation - Returns TRUE if the cursor is open, FALSE if the cursor is closed. - Returns INVALID_CURSOR if cursor is declared, but not open; or if cursor has been closed.

%FOUND

- Returns NULL if cursor is open, but fetch has not been executed. - Returns TRUE if a successful fetch has been executed. - Returns FALSE if no row was returned. - Returns INVALID_CURSOR if cursor is declared, but not open; or if cursor has been closed.

%NOTFOUND

- Return NULL if cursor is open, but fetch has not been executed. - Returns FALSE if a successful fetch has been executed. - Returns TRUE if no row was returned. - Returns INVALID_CURSOR if cursor is declared, but not open; or if cursor has been closed. - Returns the number of rows fetched.

%ROWCOUNT - The ROWCOUNT attribute doesn't give the real row count until you have iterated through the entire cursor. In other words, you shouldn't rely on this attribute to tell you how many rows are in a cursor after it is opened.

Below is an example of how you might use the %NOTFOUND attribute. CREATE OR REPLACE Function FindCourse ( name_in IN varchar2 ) RETURN number IS cnumber number;

CURSOR c1 IS SELECT course_number from courses_tbl where course_name = name_in; BEGIN open c1; fetch c1 into cnumber; if c1%notfound then cnumber := 9999; end if; close c1; RETURN cnumber; END;

xample 6-24 Cursor Variable Returning a %ROWTYPE Variable


DECLARE TYPE TmpCurTyp IS REF CURSOR RETURN employees%ROWTYPE; tmp_cv TmpCurTyp; -- declare cursor variable TYPE EmpCurTyp IS REF CURSOR RETURN tmp_cv%ROWTYPE; emp_cv EmpCurTyp; -- declare cursor variable

You can also use %ROWTYPE to provide the datatype of a record variable, as shown in Example 625. Example 6-25 Using the %ROWTYPE Attribute to Provide the Datatype
DECLARE dept_rec departments%ROWTYPE; -- declare record variable TYPE DeptCurTyp IS REF CURSOR RETURN dept_rec%TYPE; dept_cv DeptCurTyp; -- declare cursor variable

Example 6-26 specifies a user-defined RECORD type in the RETURN clause: Example 6-26 Cursor Variable Returning a Record Type
DECLARE TYPE EmpRecTyp IS RECORD (

employee_id NUMBER, last_name VARCHAR2(25), salary NUMBER(8,2)); TYPE EmpCurTyp IS REF CURSOR RETURN EmpRecTyp; emp_cv EmpCurTyp; -- declare cursor variable

Passing Cursor Variables As Parameters


You can declare cursor variables as the formal parameters of functions and procedures. Example 6-27 defines a REF CURSOR type, then declares a cursor variable of that type as a formal parameter. Example 6-27 Passing a REF CURSOR as a Parameter
DECLARE TYPE empcurtyp IS REF CURSOR RETURN employees%ROWTYPE; emp empcurtyp; -- after result set is built, process all the rows inside a single procedure -- rather than calling a procedure for each row PROCEDURE process_emp_cv (emp_cv IN empcurtyp) IS person employees%ROWTYPE; BEGIN DBMS_OUTPUT.PUT_LINE('-----'); DBMS_OUTPUT.PUT_LINE('Here are the names from the result set:'); LOOP FETCH emp_cv INTO person; EXIT WHEN emp_cv%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Name = ' || person.first_name || ' ' || person.last_name); END LOOP; END; BEGIN -- First find 10 arbitrary employees. OPEN emp FOR SELECT * FROM employees WHERE ROWNUM < 11; process_emp_cv(emp); CLOSE emp; -- find employees matching a condition. OPEN emp FOR SELECT * FROM employees WHERE last_name LIKE 'R%'; process_emp_cv(emp); CLOSE emp; END; /

Like all pointers, cursor variables increase the possibility of parameter aliasing. See "Overloading Subprogram Names".

Controlling Cursor Variables: OPEN-FOR, FETCH, and CLOSE


You use three statements to control a cursor variable: OPEN-FOR, FETCH, and CLOSE. First, you OPEN a cursor variable FOR a multi-row query. Then, you FETCH rows from the result set. When all the rows are processed, you CLOSE the cursor variable.

Opening a Cursor Variable


The OPEN-FOR statement associates a cursor variable with a multi-row query, executes the query, and identifies the result set. The cursor variable can be declared directly in PL/SQL, or in a PL/SQL host environment such as an OCI program. For the syntax of the OPEN-FOR statement, see "OPEN-FOR Statement". The SELECT statement for the query can be coded directly in the statement, or can be a string variable or string literal. When you use a string as the query, it can include placeholders for bind variables, and you specify the corresponding values with a USING clause. This section discusses the static SQL case, in which select_statement is used. For the dynamic SQL case, in which dynamic_string is used, see "OPEN-FOR Statement". Unlike cursors, cursor variables take no parameters. Instead, you can pass whole queries (not just parameters) to a cursor variable. The query can reference host variables and PL/SQL variables, parameters, and functions. Example 6-28 opens a cursor variable. Notice that you can apply cursor attributes (%FOUND, %NOTFOUND, %ISOPEN, and %ROWCOUNT) to a cursor variable. Example 6-28 Checking If a Cursor Variable is Open
DECLARE TYPE empcurtyp IS REF CURSOR RETURN employees%ROWTYPE; emp_cv empcurtyp; BEGIN IF NOT emp_cv%ISOPEN THEN -- open cursor variable OPEN emp_cv FOR SELECT * FROM employees; END IF; CLOSE emp_cv; END; /

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/sqloperations.htm http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/toc.htm