Cursors And Bulk Collect

CURSORS

Cursor is a pointer to memory location which is called as context area which contains the information necessary for processing, including the number of rows processed by the statement, a pointer to the parsed representation of the statement, and the active set which is the set of rows returned by the query.
Cursor contains two parts

  • Header
  • Body

Header includes cursor name, any parameters and the type of data being loaded.
Body includes the select statement.
Ex:
Cursor c(dno in number) return dept%rowtype is select *from dept;
In the above
Header – cursor c(dno in number) return dept%rowtype
Body – select *from dept

CURSOR TYPES

  • Implicit (SQL)
  • Explicit
  1. Parameterized cursors
  2. REF cursors

Explicit Cursor: The set of rows returned by a query can consist of zero, one, or multiple rows, depending on how many rows meet your search criteria. When a query returns multiple rows, you can explicitly define a cursor to process the rows. You use three commands to control the cursor:
CURSOR STAGES

  1. Open
  2. Fetch
  3. Close

Implicit Cursors: ORACLE implicitly opens a cursor to process each SQL statement not associated with an explicitly declared cursor.PL/SQL lets you refer to the most recent implicit cursor as the SQL” cursor. So, although you cannot use the OPEN,
FETCH, and CLOSE statements to control an implicit cursor, you can still use cursor attributes to access information about the most recently executed SQL statement.

CURSOR ATTRIBUTES

  1. %found
  2. %notfound
  3. %rowcount
  4. %isopen
  5. %bulk_rowcount
  6. %bulk_exceptions

CURSOR DECLERATION
Syntax:
Cursor <cursor_name> is select statement;
Ex:
Cursor c is select *from dept;

CURSOR LOOPS

  1. Simple loop
  2. While loop
  3. For loop

SIMPLE LOOP
Syntax:
Loop
Fetch <cursor_name> into <record_variable>;
Exit when <cursor_name> % notfound;
<statements>;
End loop;
Ex:

Output:
Name = saketh
Name = srinu
Name = satish
Name = sudha

WHILE LOOP
Syntax:
While <cursor_name> % found loop
Fetch <cursor_name> nto <record_variable>;
<statements>;
End loop;
Ex:

Output:
Name = saketh
Name = srinu
Name = satish
Name = sudha

FOR LOOP
Syntax:
for <record_variable> in <cursor_name> loop
<statements>;
End loop;
Ex:

Output:
Name = saketh
Name = srinu
Name = satish
Name = sudha

PARAMETARIZED CURSORS

  1. This was used when you are going to use the cursor in more than one place with different values for the same where clause.
  2. Cursor parameters must be in mode.
  3. Cursor parameters may have default values.
  4. The scope of cursor parameter is within the select statement.

Ex:

 

PACKAGED CURSORS WITH HEADER IN SPEC AND BODY IN PACKAGE BODY

  1. Cursors declared in packages will not close automatically.
  2. In packaged cursors you can modify the select statement without making any changes to the cursor header in the package specification.
  3. Packaged cursors with must be defined in the package body itself, and then use it as global for the package.
  4. You can not define the packaged cursor in any subprograms.
  5. Cursor declaration in package with out body needs the return clause.

 

REF CURSORS AND CURSOR VARIABLES

  1. This is unconstrained cursor which will return different types depends upon the user input.
  2. Ref cursors cannot be closed implicitly.
  3. Ref cursor with return type is called strong cursor.
  4. Ref cursor without return type is called weak cursor.
  5. You can declare ref cursor type in package spec as well as body.
  6. You can declare ref cursor types in local subprograms or anonymous blocks.
  7. Cursor variables can be assigned from one to another.
  8. You can declare a cursor variable in one scope and assign another cursor variable with different scope, then you can use the cursor variable even though the assigned cursor variable goes out of scope.
  9. Cursor variables can be passed as parameters to the subprograms.
  10. Cursor variables modes are in or out or in out.
  11. Cursor variables cannot be declared in package spec and package body (excluding subprograms).
  12. You cannot user remote procedure calls to pass cursor variables from one server to another.
  13. Cursor variables cannot use for update clause.
  14. You can not assign nulls to cursor variables.
  15. You cannot compare cursor variables for equality, inequality and nullity.

 

CURSOR EXPRESSIONS

  1. You can use cursor expressions in explicit cursors.
  2. You can use cursor expressions in dynamic SQL.
  3. You can use cursor expressions in REF cursor declarations and variables.
  4. You cannot use cursor expressions in implicit cursors.
  5. Oracle opens the nested cursor defined by a cursor expression implicitly as soon as it fetches the data containing the cursor expression from the parent or outer cursor.
  6. Nested cursor closes if you close explicitly.
  7. Nested cursor closes whenever the outer or parent cursor is executed again or closed or canceled.
  8. Nested cursor closes whenever an exception is raised while fetching data from a parent cursor.
  9. Cursor expressions cannot be used when declaring a view.
  10. Cursor expressions can be used as an argument to table function.
  11. You cannot perform bind and execute operations on cursor expressions when using the cursor expressions in dynamic SQL.

USING NESTED CURSORS OR CURSOR EXPRESSIONS

 CURSOR CLAUSES

  1. Return
  2. For update
  3. Where current of
  4. Bulk collect

RETURN
Cursor c return dept%rowtype is select *from dept;
Or
Cursor c1 is select *from dept;
Cursor c return c1%rowtype is select *from dept;
Or
Type t is record(deptno dept.deptno%type, dname dept.dname%type);
Cursor c return t is select deptno, dname from dept;

FOR UPDATE AND WHERE CURRENT OF
Normally, a select operation will not take any locks on the rows being accessed. This will allow other sessions connected to the database to change the data being selected. The result set is still consistent. At open time, when the active set is determined, oracle takes a snapshot of the table. Any changes that have been committed prior to this point are reflected in the active set. Any changes made after this point, even if they are committed, are not reflected unless the cursor is reopened, which will evaluate the active set again.

However, if the FOR UPDATE caluse is pesent, exclusive row locks are taken on the rows in the active set before the open returns. These locks prevent other sessions from changing the rows in the active set until the transaction is committed or rolled back. If another session already has locks on the rows in the active set, then SELECT … FOR UPDATE operation will wait for these locks to be released by the other session. There is no time-out for this waiting period. The SELECT…FOR UPDATE will hang until the other session releases the lock. To handle this situation, the NOWAIT clause is available.
Syntax:
Select …from … for update of column_name [wait n];

If the cursor is declared with the FOR UPDATE clause, the WHERE CURRENT OF clause can be used in an update or delete statement.
Syntax:
Where current of cursor;

 

BULK COLLECT

  1. This is used for array fetches
  2. With this you can retrieve multiple rows of data with a single roundtrip.
  3. This reduces the number of context switches between the pl/sql and sql engines.
  4. Reduces the overhead of retrieving data.
  5. You can use bulk collect in both dynamic and static sql.
  6. You can use bulk collect in select, fetch into and returning into clauses.
  7. SQL engine automatically initializes and extends the collections you reference in the bulk collect clause.
  8. Bulk collect operation empties the collection referenced in the into clause before executing the query.
  9. You can use the limit clause of bulk collect to restrict the no of rows retrieved.
  10. You can fetch into multible collections with one column each.
  11. Using the returning clause we can return data to the another collection.

BULK COLLECT IN FETCH

 

BULK COLLECT IN SELECT

 

LIMIT IN BULK COLLECT
You can use this to limit the number of rows to be fetched.

 MULTIPLE FETCHES IN INTO CLAUSE

 RETURNING CLAUSE IN BULK COLLECT

You can use this to return the processed data to the ouput variables or typed variables.

POINTS TO REMEMBER

  1. Cursor name can be up to 30 characters in length.
  2. Cursors declared in anonymous blocks or subprograms closes automatically when that block terminates execution.
  3. %bulk_rowcount and %bulk_exceptions can be used only with forall construct.
  4. Cursor declarations may have expressions with column aliases.
  5. These expressions are called virtual columns or calculated columns.

Related posts:

Leave a Reply