writing explicit cursors
DESCRIPTION
Writing Explicit Cursors. About Cursors. Every SQL statement executed by the Oracle Server has an individual cursor associated with it: Implicit cursors: Declared for all DML and PL/SQL SELECT statements Explicit cursors: Declared and named by the programmer. Cursor. - PowerPoint PPT PresentationTRANSCRIPT
Writing Explicit Writing Explicit CursorsCursors
Writing Explicit Writing Explicit CursorsCursors
About CursorsAbout CursorsAbout CursorsAbout Cursors
Every SQL statement executed by the Every SQL statement executed by the Oracle Server has an individual Oracle Server has an individual cursor associated with it:cursor associated with it: Implicit cursors: Declared for all DML Implicit cursors: Declared for all DML
and PL/SQL SELECT statementsand PL/SQL SELECT statements Explicit cursors: Declared and named by Explicit cursors: Declared and named by
the programmerthe programmer
Every SQL statement executed by the Every SQL statement executed by the Oracle Server has an individual Oracle Server has an individual cursor associated with it:cursor associated with it: Implicit cursors: Declared for all DML Implicit cursors: Declared for all DML
and PL/SQL SELECT statementsand PL/SQL SELECT statements Explicit cursors: Declared and named by Explicit cursors: Declared and named by
the programmerthe programmer
Explicit Cursor FunctionsExplicit Cursor FunctionsExplicit Cursor FunctionsExplicit Cursor Functions
Active setActive set
Current rowCurrent rowCursor
7369 SMITH CLERK
7566 JONES MANAGER
7788 SCOTT ANALYST
7876 ADAMS CLERK
7902 FORD ANALYST
Controlling Explicit CursorsControlling Explicit CursorsControlling Explicit CursorsControlling Explicit Cursors
• Create a Create a named named SQL areaSQL area
DECLAREDECLAREDECLAREDECLARE
• Identify Identify the active the active setset
OPENOPENOPENOPEN
• Load the Load the current current row into row into variablesvariables
FETCHFETCHFETCHFETCH
• Test for Test for existing existing rowsrows
EMPTY?
• Return to Return to FETCH if FETCH if rows rows foundfound
NoNo
• Release Release the active the active setset
CLOSECLOSECLOSECLOSEYesYes
Controlling Explicit CursorsControlling Explicit CursorsControlling Explicit CursorsControlling Explicit CursorsOpen the cursor.Open the cursor.
CursorCursor
PointerPointer
Fetch a row from the cursor.Fetch a row from the cursor.
CursorCursor
PointerPointer
Continue until empty.Continue until empty.
CursorCursor
PointerPointer
Close the cursor.Close the cursor.
CursorCursor
Declaring the CursorDeclaring the CursorDeclaring the CursorDeclaring the Cursor
SyntaxSyntax
Do not include the INTO clause in the cursor declaration.Do not include the INTO clause in the cursor declaration. If processing rows in a specific sequence is required, use the If processing rows in a specific sequence is required, use the
ORDER BY clause in the query.ORDER BY clause in the query.
SyntaxSyntax
Do not include the INTO clause in the cursor declaration.Do not include the INTO clause in the cursor declaration. If processing rows in a specific sequence is required, use the If processing rows in a specific sequence is required, use the
ORDER BY clause in the query.ORDER BY clause in the query.
CURSOR cursor_name IS
select_statement;
CURSOR cursor_name IS
select_statement;
Opening the CursorOpening the CursorOpening the CursorOpening the Cursor
SyntaxSyntax
Open the cursor to execute the query Open the cursor to execute the query and identify the active set.and identify the active set.
If the query returns no rows, no If the query returns no rows, no exception is raised.exception is raised.
Use cursor attributes to test the outcome Use cursor attributes to test the outcome after a fetch.after a fetch.
SyntaxSyntax
Open the cursor to execute the query Open the cursor to execute the query and identify the active set.and identify the active set.
If the query returns no rows, no If the query returns no rows, no exception is raised.exception is raised.
Use cursor attributes to test the outcome Use cursor attributes to test the outcome after a fetch.after a fetch.
OPEN cursor_name; OPEN cursor_name;
Fetching Data from the CursorFetching Data from the CursorFetching Data from the CursorFetching Data from the Cursor
SyntaxSyntax
Retrieve the current row values into Retrieve the current row values into output variables.output variables.
Include the same number of variables.Include the same number of variables. Match each variable to correspond to the Match each variable to correspond to the
columns positionally.columns positionally. Test to see if the cursor contains rows.Test to see if the cursor contains rows.
SyntaxSyntax
Retrieve the current row values into Retrieve the current row values into output variables.output variables.
Include the same number of variables.Include the same number of variables. Match each variable to correspond to the Match each variable to correspond to the
columns positionally.columns positionally. Test to see if the cursor contains rows.Test to see if the cursor contains rows.
FETCH cursor_name INTO [variable1, variable2, ...]
| record_name];
FETCH cursor_name INTO [variable1, variable2, ...]
| record_name];
Fetching Data from the CursorFetching Data from the CursorFetching Data from the CursorFetching Data from the Cursor
ExamplesExamples
ExamplesExamples
FETCH emp_cursor INTO v_empno, v_ename;FETCH emp_cursor INTO v_empno, v_ename;
...OPEN defined_cursor;LOOP FETCH defined_cursor INTO defined_variables EXIT WHEN ...; ... -- Process the retrieved data ...END;
...OPEN defined_cursor;LOOP FETCH defined_cursor INTO defined_variables EXIT WHEN ...; ... -- Process the retrieved data ...END;
Closing the CursorClosing the CursorClosing the CursorClosing the Cursor
SyntaxSyntax
Close the cursor after completing the Close the cursor after completing the processing of the rows.processing of the rows.
Reopen the cursor, if required.Reopen the cursor, if required. Do not attempt to fetch data from a Do not attempt to fetch data from a
cursor once it has been closed.cursor once it has been closed.
SyntaxSyntax
Close the cursor after completing the Close the cursor after completing the processing of the rows.processing of the rows.
Reopen the cursor, if required.Reopen the cursor, if required. Do not attempt to fetch data from a Do not attempt to fetch data from a
cursor once it has been closed.cursor once it has been closed.
CLOSE cursor_name; CLOSE cursor_name;
Explicit Cursor AttributesExplicit Cursor AttributesExplicit Cursor AttributesExplicit Cursor Attributes
Obtain status information about a Obtain status information about a cursor.cursor.
Obtain status information about a Obtain status information about a cursor.cursor.Attribute Type Description
%ISOPEN Boolean Evaluates to TRUE if the cursor is open
%NOTFOUND Boolean Evaluates to TRUE if the most recent fetch does not return a row
%FOUND Boolean Evaluates to TRUE if the mostrecent fetch returns a row; complement of %NOTFOUND
%ROWCOUNT Number Evaluates to the total number of rows returned so far
Controlling Multiple FetchesControlling Multiple FetchesControlling Multiple FetchesControlling Multiple Fetches
Process several rows from an explicit Process several rows from an explicit cursor using a loop.cursor using a loop.
Fetch a row with each iteration.Fetch a row with each iteration. Use the %NOTFOUND attribute to write Use the %NOTFOUND attribute to write
a test for an unsuccessful fetch.a test for an unsuccessful fetch. Use explicit cursor attributes to test the Use explicit cursor attributes to test the
success of each fetch.success of each fetch.
Process several rows from an explicit Process several rows from an explicit cursor using a loop.cursor using a loop.
Fetch a row with each iteration.Fetch a row with each iteration. Use the %NOTFOUND attribute to write Use the %NOTFOUND attribute to write
a test for an unsuccessful fetch.a test for an unsuccessful fetch. Use explicit cursor attributes to test the Use explicit cursor attributes to test the
success of each fetch.success of each fetch.
The %ISOPEN AttributeThe %ISOPEN AttributeThe %ISOPEN AttributeThe %ISOPEN Attribute Fetch rows only when the cursor is Fetch rows only when the cursor is
open. open. Use the %ISOPEN cursor attribute Use the %ISOPEN cursor attribute
before performing a fetch to test whether before performing a fetch to test whether the cursor is open.the cursor is open.
ExampleExample
Fetch rows only when the cursor is Fetch rows only when the cursor is open. open.
Use the %ISOPEN cursor attribute Use the %ISOPEN cursor attribute before performing a fetch to test whether before performing a fetch to test whether the cursor is open.the cursor is open.
ExampleExampleIF NOT emp_cursor%ISOPEN THEN
OPEN emp_cursor;END IF;LOOP FETCH emp_cursor...
IF NOT emp_cursor%ISOPEN THENOPEN emp_cursor;
END IF;LOOP FETCH emp_cursor...
The %NOTFOUND The %NOTFOUND and %ROWCOUNT Attributesand %ROWCOUNT Attributes
The %NOTFOUND The %NOTFOUND and %ROWCOUNT Attributesand %ROWCOUNT Attributes
Use the %ROWCOUNT cursor attribute Use the %ROWCOUNT cursor attribute to retrieve an exact number of rows.to retrieve an exact number of rows.
Use the %NOTFOUND cursor attribute Use the %NOTFOUND cursor attribute to determine when to exit the loop.to determine when to exit the loop.
Use the %ROWCOUNT cursor attribute Use the %ROWCOUNT cursor attribute to retrieve an exact number of rows.to retrieve an exact number of rows.
Use the %NOTFOUND cursor attribute Use the %NOTFOUND cursor attribute to determine when to exit the loop.to determine when to exit the loop.
Cursors and RecordsCursors and RecordsCursors and RecordsCursors and Records Process the rows of the active set Process the rows of the active set
conveniently by fetching values into a conveniently by fetching values into a PL/SQL RECORD.PL/SQL RECORD.
ExampleExample
Process the rows of the active set Process the rows of the active set conveniently by fetching values into a conveniently by fetching values into a PL/SQL RECORD.PL/SQL RECORD.
ExampleExampleDECLARE CURSOR emp_cursor IS SELECT empno, ename FROM emp; emp_record emp_cursor%ROWTYPE;BEGIN OPEN emp_cursor; LOOP FETCH emp_cursor INTO emp_record; ...
DECLARE CURSOR emp_cursor IS SELECT empno, ename FROM emp; emp_record emp_cursor%ROWTYPE;BEGIN OPEN emp_cursor; LOOP FETCH emp_cursor INTO emp_record; ...
SyntaxSyntax
The cursor FOR loop is a shortcut to The cursor FOR loop is a shortcut to process explicit cursors.process explicit cursors.
Implicit open, fetch, and close occur.Implicit open, fetch, and close occur. The record is implicitly declared.The record is implicitly declared.
SyntaxSyntax
The cursor FOR loop is a shortcut to The cursor FOR loop is a shortcut to process explicit cursors.process explicit cursors.
Implicit open, fetch, and close occur.Implicit open, fetch, and close occur. The record is implicitly declared.The record is implicitly declared.
Cursor FOR LoopsCursor FOR LoopsCursor FOR LoopsCursor FOR Loops
FOR record_name IN cursor_name LOOP
statement1;
statement2;
. . .
END LOOP;
FOR record_name IN cursor_name LOOP
statement1;
statement2;
. . .
END LOOP;
Cursor FOR LoopsCursor FOR LoopsCursor FOR LoopsCursor FOR Loops
Retrieve employees one by one until Retrieve employees one by one until no more are left.no more are left.
ExampleExample
Retrieve employees one by one until Retrieve employees one by one until no more are left.no more are left.
ExampleExampleDECLARE CURSOR emp_cursor IS SELECT ename, deptno FROM emp;BEGIN FOR emp_record IN emp_cursor LOOP -- implicit open and implicit fetch occur IF emp_record.deptno = 30 THEN ... END LOOP; -- implicit close occursEND;
DECLARE CURSOR emp_cursor IS SELECT ename, deptno FROM emp;BEGIN FOR emp_record IN emp_cursor LOOP -- implicit open and implicit fetch occur IF emp_record.deptno = 30 THEN ... END LOOP; -- implicit close occursEND;
Cursor FOR Loops Cursor FOR Loops Using SubqueriesUsing Subqueries
Cursor FOR Loops Cursor FOR Loops Using SubqueriesUsing Subqueries
No need to declare the cursor.No need to declare the cursor. ExampleExample
No need to declare the cursor.No need to declare the cursor. ExampleExample
BEGIN FOR emp_record IN ( SELECT ename, deptno FROM emp) LOOP -- implicit open and implicit fetch occur IF emp_record.deptno = 30 THEN ... END LOOP; -- implicit close occursEND;
BEGIN FOR emp_record IN ( SELECT ename, deptno FROM emp) LOOP -- implicit open and implicit fetch occur IF emp_record.deptno = 30 THEN ... END LOOP; -- implicit close occursEND;
Cursors with ParametersCursors with Parameters
SyntaxSyntax
Pass parameter values to a cursor when Pass parameter values to a cursor when the cursor is opened and the query is the cursor is opened and the query is executed.executed.
Open an explicit cursor several times with Open an explicit cursor several times with a different active set each time.a different active set each time.
CURSOR cursor_name [(parameter_name datatype, ...)]IS select_statement;
CURSOR cursor_name [(parameter_name datatype, ...)]IS select_statement;
Cursors with ParametersCursors with ParametersCursors with ParametersCursors with Parameters
Pass the department number and job title Pass the department number and job title to the WHERE clause. to the WHERE clause.
ExampleExample
Pass the department number and job title Pass the department number and job title to the WHERE clause. to the WHERE clause.
ExampleExampleDECLARE CURSOR emp_cursor (v_deptno NUMBER, v_job VARCHAR2) IS SELECT empno, ename FROM emp WHERE deptno = v_deptno AND job = v_job;BEGIN OPEN emp_cursor(10, 'CLERK');...
DECLARE CURSOR emp_cursor (v_deptno NUMBER, v_job VARCHAR2) IS SELECT empno, ename FROM emp WHERE deptno = v_deptno AND job = v_job;BEGIN OPEN emp_cursor(10, 'CLERK');...
The FOR UPDATE ClauseThe FOR UPDATE ClauseThe FOR UPDATE ClauseThe FOR UPDATE Clause
SyntaxSyntax
Explicit locking lets you deny access for Explicit locking lets you deny access for the duration of a transaction.the duration of a transaction.
Lock the rows Lock the rows before before the update or the update or delete.delete.
SyntaxSyntax
Explicit locking lets you deny access for Explicit locking lets you deny access for the duration of a transaction.the duration of a transaction.
Lock the rows Lock the rows before before the update or the update or delete.delete.
SELECT ... FROM ...FOR UPDATE [OF column_reference][NOWAIT]
SELECT ... FROM ...FOR UPDATE [OF column_reference][NOWAIT]
The FOR UPDATE ClauseThe FOR UPDATE ClauseThe FOR UPDATE ClauseThe FOR UPDATE Clause
Retrieve the employees who work in Retrieve the employees who work in department 30. department 30.
ExampleExample
Retrieve the employees who work in Retrieve the employees who work in department 30. department 30.
ExampleExampleDECLARE CURSOR emp_cursor IS SELECT empno, ename, sal FROM emp WHERE deptno = 30 FOR UPDATE NOWAIT;
DECLARE CURSOR emp_cursor IS SELECT empno, ename, sal FROM emp WHERE deptno = 30 FOR UPDATE NOWAIT;
The WHERE CURRENT OF The WHERE CURRENT OF ClauseClause
SyntaxSyntax
Use cursors to update or delete the Use cursors to update or delete the current row.current row.
Include the FOR UPDATE clause in the Include the FOR UPDATE clause in the cursor query to lock the rows first.cursor query to lock the rows first.
Use the WHERE CURRENT OF clause Use the WHERE CURRENT OF clause to reference the current row from an to reference the current row from an explicit cursor.explicit cursor.
WHERE CURRENT OF cursor WHERE CURRENT OF cursor
The WHERE CURRENT OF The WHERE CURRENT OF ClauseClause
DECLARE CURSOR sal_cursor IS SELECT sal FROM emp WHERE deptno = 30 FOR UPDATE NOWAIT;BEGIN FOR emp_record IN sal_cursor LOOP UPDATE emp SET sal = emp_record.sal * 1.10 WHERE CURRENT OF sal_cursor; END LOOP; COMMIT;END;
DECLARE CURSOR sal_cursor IS SELECT sal FROM emp WHERE deptno = 30 FOR UPDATE NOWAIT;BEGIN FOR emp_record IN sal_cursor LOOP UPDATE emp SET sal = emp_record.sal * 1.10 WHERE CURRENT OF sal_cursor; END LOOP; COMMIT;END;
ExampleExampleExampleExample
Cursors with SubqueriesCursors with SubqueriesCursors with SubqueriesCursors with Subqueries
DECLARE CURSOR my_cursor IS SELECT t1.deptno, dname, STAFF FROM dept t1, (SELECT deptno, count(*) STAFF FROM emp GROUP BY deptno) t2 WHERE t1.deptno = t2.deptno AND STAFF >= 5;
DECLARE CURSOR my_cursor IS SELECT t1.deptno, dname, STAFF FROM dept t1, (SELECT deptno, count(*) STAFF FROM emp GROUP BY deptno) t2 WHERE t1.deptno = t2.deptno AND STAFF >= 5;
ExampleExampleExampleExample
SummarySummarySummarySummary Cursor types:Cursor types:
• Implicit cursors: Used for all DML statements Implicit cursors: Used for all DML statements and single-row queries.and single-row queries.
• Explicit cursors: Used for queries of Explicit cursors: Used for queries of zero, zero, one, or more rows.one, or more rows.
You can manipulate explicit cursors.You can manipulate explicit cursors. You can evaluate the cursor status by You can evaluate the cursor status by
using cursor attributes.using cursor attributes. You can use cursor FOR loops.You can use cursor FOR loops.
Cursor types:Cursor types:• Implicit cursors: Used for all DML statements Implicit cursors: Used for all DML statements
and single-row queries.and single-row queries.• Explicit cursors: Used for queries of Explicit cursors: Used for queries of zero, zero,
one, or more rows.one, or more rows. You can manipulate explicit cursors.You can manipulate explicit cursors. You can evaluate the cursor status by You can evaluate the cursor status by
using cursor attributes.using cursor attributes. You can use cursor FOR loops.You can use cursor FOR loops.
SummarySummarySummarySummary
You can return different active sets using You can return different active sets using cursors with parameters.cursors with parameters.
You can define cursors with subqueries You can define cursors with subqueries and correlated subqueries.and correlated subqueries.
You can manipulate explicit cursors with You can manipulate explicit cursors with commands:commands:• FOR UPDATE ClauseFOR UPDATE Clause• WHERE CURRENT OF ClauseWHERE CURRENT OF Clause
You can return different active sets using You can return different active sets using cursors with parameters.cursors with parameters.
You can define cursors with subqueries You can define cursors with subqueries and correlated subqueries.and correlated subqueries.
You can manipulate explicit cursors with You can manipulate explicit cursors with commands:commands:• FOR UPDATE ClauseFOR UPDATE Clause• WHERE CURRENT OF ClauseWHERE CURRENT OF Clause