DB2 - Banco de dados - DECLARE CURSOR - www.cadcobol.com.br
The DECLARE CURSOR statement defines a cursor.
This statement can only be embedded in an application program. It is not an executable statement. It must not be specified in Java.
For each table or view identified in the SELECT statement of the cursor, the privilege set must include at least one of the following:
If the select-statement contains an SQL data change statement, the authorization requirements of that statement also apply to the DECLARE CURSOR statement.
The SELECT statement of the cursor is one of the following:
If statement-name is specified:
If select-statement is specified:
Notes:
holdability:
returnability:
rowset-positioning:
A cursor that defined as ASENSITIVE will be either insensitive or sensitive dynamic; it will not be sensitive static. For information about how the effective sensitivity of the cursor is returned to the application with the GET DIAGNOSTICS statement or in the SQLCA, see OPEN.
The sensitivity of a cursor is a factor in the choice of access path. Explicitly specify the sensitivity level that you need, instead of specifying ASENSITIVE.
If DB2® cannot make changes visible to the cursor, then an error is issued at bind time for OPEN CURSOR. DB2 cannot make changes visible to the cursor when the cursor implicitly becomes read-only. For example, when the result table must be materialized, as when the FROM clause of the SELECT statement contains more than one table or view.
The default is DYNAMIC.
If a SENSITIVE DYNAMIC cursor is not possible, an error is returned. For example, if a temporary table is needed an error is returned. The SELECT statement of a cursor that is defined as SENSITIVE DYNAMIC cannot contain an SQL data change statement.
The FETCH FIRST n ROWS ONLY clause must not be specified for the outermost fullselect for a sensitive dynamic cursor.
A STATIC cursor has visibility to changes made by this cursor using positioned updates or deletes. Committed changes made outside this cursor are visible with the SENSITIVE option of the FETCH statement. A FETCH SENSITIVE can result in a hole in the result table (that is, a difference between the result table and its underlying base table). If an updated row in the base table of a cursor no longer satisfies the predicate of its SELECT statement, an update hole occurs in the result table. If a row of a cursor was deleted in the base table, a delete hole occurs in the result table. When a FETCH SENSITIVE detects an update hole, no data is returned (a warning is issued), and the cursor is left positioned on the update hole. When a FETCH SENSITIVE detects a delete hole, no data is returned (a warning is issued), and the cursor is left positioned on the delete hole.
Updates through a cursor result in an automatic re-fetch of the row. This re-fetch means that updates can create a hole themselves. The re-fetched row also reflects changes as a result of triggers updating the same row. It is important to reflect these changes to maintain the consistency of data in the row.
Using a function that is not deterministic (built-in or user-defined) in the WHERE clause of the select-statement or statement-name of a SENSITIVE STATIC cursor can cause misleading results. This situation occurs because DB2 constructs a temporary result table and retrieves rows from this table for FETCH INSENSITIVE statements. When DB2 processes a FETCH SENSITIVE statement, rows are fetched from the underlying table and predicates are re-evaluated. Using a function that is not deterministic can yield a different result on each FETCH SENSITIVE of the same row, which could also result in the row no longer being considered a match.
A FETCH INSENSITIVE on a SENSITIVE STATIC SCROLL cursor is not sensitive to changes made outside the cursor, unless a previous FETCH SENSITIVE has already refreshed that row; however, positioned updates and delete changes with the cursor are visible.
STATIC cursors are insensitive to insertions.
When WITH HOLD is specified, a commit operation commits all of the changes in the current unit of work. For example, with a non-scrollable cursor, an initial FETCH statement is needed after a COMMIT statement to position the cursor on the row that follows the row that the cursor was positioned on before the commit operation.
WITH HOLD has no effect on an SQL data change statement within a SELECT statement. When a COMMIT is issued, the changes caused by the SQL data change statement are committed, regardless of whether or not the cursor is declared WITH HOLD.
All cursors are implicitly closed by a connect (Type 1) or rollback operation. A cursor is also implicitly closed by a commit operation if WITH HOLD is ignored or not specified.
Cursors that are declared with WITH HOLD in CICS® or in IMS™ non-message-driven programs will not be closed by a rollback operation if the cursor was opened in a previous unit of work and no changes have been made to the database in the current unit of work. The cursor cannot be closed because CICS and IMS do not broadcast the rollback request to DB2 for a null unit of work.
If a cursor is closed before the commit operation, the effect is the same as if the cursor was declared without the option WITH HOLD.
WITH HOLD is ignored in IMS message driven programs (MPP, IFP, and message-driven BMP). WITH HOLD maintains the cursor position in a CICS pseudo-conversational program until the end-of-task (EOT).
For details on restrictions that apply to declaring cursors with WITH HOLD, see DB2 Application Programming and SQL Guide.
When a cursor that is declared using the WITH RETURN TO CALLER clause remains open at the end of a program or routine, that cursor defines a result set from the program or routine. Use the CLOSE statement to close a cursor that is not intended to be a result set from the program or routine. Although DB2 will automatically close any cursors that are not declared using with a WITH RETURN clause, the use of the CLOSE statement is recommended to increase the portability of applications.
For non-scrollable cursors, the result set consists of all rows from the current cursor position to the end of the result table. For scrollable cursors, the result set consists of all rows of the result table.
If the statement is contained within the source code for a procedure, WITH RETURN TO CALLER specifies that the cursor can be used as a result set cursor. A result set cursor is used when the result table of a cursor is to be returned from a procedure. Specifying TO CALLER is optional.
In other cases, the clause is ignored and the cursor cannot be used as a result set cursor.
DB2 REXX applications do not support cursors that are declared WITH ROWSET POSITIONING. To allow a cursor for a SELECT statement in a DB2 REXX application to be used with row-positioned or rowset-positioned FETCH statements, specify WITH ROWSET POSITIONING in the attribute string of the PREPARE statement for the SELECT statement.
The select-statement must not include parameter markers (except for REXX), but can include references to host variables. In host languages, other than REXX, the declarations of the host variables must precede the DECLARE CURSOR statement in the source program. In REXX, parameter markers must be used in place of host variables and the statement must be prepared.
The USING clause of the OPEN statement can be used to specify host variables that will override the values of the host variables or parameter markers that are specified as part of the statement in the DECLARE CURSOR statement.
The select-statement must not contain an SQL data change statement if the cursor is defined as SENSITIVE DYNAMIC or SENSITIVE STATIC.
The prepared select-statement must not contain an SQL data change statement if the cursor is defined as SENSITIVE DYNAMIC or SENSITIVE STATIC.
A cursor in the open state designates a result table and a position relative to the rows of that table. The table is the result table specified by the SELECT statement of the cursor.
If the result table is read-only, the cursor is read-only. The cursor that references a view with instead of triggers are read-only since positioned UPDATE and positioned DELETE statements are not allowed using those cursors. The result table is read-only if one or more of the following statements is true about the select-statement of the cursor:
If the result table is not read-only, the cursor can be used to update or delete the underlying rows of the result table.
For static scrollable cursor declarations that contain empty strings, DB2 assigns one byte in the temporary table space for each empty string. The following example shows a scrollable cursor declaration with an empty string:
EXEC SQL DECLARE CSROWSTAT SENSITIVE STATIC SCROLL CURSOR WITH ROWSET POSITIONING WITH HOLD FOR SELECT ID1,'' FROM TB;
Although the scope of a cursor is the program in which it is declared, each package (or DBRM of a plan) created from the program includes a separate instance of the cursor, and more than one instance of the cursor can be used in the same execution of the program. For example, assume a program is precompiled with the CONNECT(2) option and its DBRM is used to create a package at location X and a package at location Y. The program contains the following SQL statements:
DECLARE C CURSOR FOR ... CONNECT TO X OPEN C FETCH C INTO ... CONNECT TO Y OPEN C FETCH C INTO ...
The second OPEN C statement does not cause an error because it refers to a different instance of cursor C. The same notion applies to a single location if the packages are in different collections.
A SELECT statement is evaluated at the time the cursor is opened. If the same cursor is opened, closed, and then opened again, the results can be different. If the SELECT statement of the cursor contains CURRENT DATE, CURRENT TIME or CURRENT TIMESTAMP, all references to these special registers yields the same respective datetime value on each FETCH operation. The value is determined when the cursor is opened. Multiple cursors using the same SELECT statement can be opened concurrently. They are each considered independent activities.
The result set is the set of all rows after the current position of the cursor after exiting the stored procedure. The result set is assumed to be read-only. If that same procedure is invoked again, open result set cursors for a stored procedure at a given site are automatically closed by the database management system.
Multiple instances of a cursor that is defined with RETURN TO CLIENT: If the cursor is declared in a native SQL procedure, a cursor that is declared as WITH RETURN TO CLIENT can be opened even when a cursor with the same name is already in the open state. In this case, the already open cursor becomes a result set cursor and is no longer accessible by using its cursor name. A new cursor is opened and becomes accessible by using the cursor name. When a CLOSE statement is issued, the last instance of the cursor will be closed. Closing the new cursor does not make the cursor that was previously accessible by that name accessible by the cursor name again. Cursors that become result set cursors in this way cannot be accessed at the server and can be processed only at the client.
The statements in the following examples are assumed to be in PL/I programs.
EXEC SQL DECLARE C1 CURSOR FOR SELECT DEPTNO , DEPTNAME , MGRNO FROM DSN8A10.DEPT WHERE ADMRDEPT = 'A00';
EXEC SQL DECLARE C1 CURSOR FOR SELECT DEPTNO , DEPTNAME , MGRNO FROM DSN8A10.DEPT WHERE ADMRDEPT = 'A00' FOR READ ONLY WITH RS USE AND KEEP EXCLUSIVE LOCKS;
EXEC SQL DECLARE C2 CURSOR FOR STMT2;
EXEC SQL DECLARE C3 CURSOR WITH HOLD FOR SELECT * FROM DSN8A10.EMP FOR UPDATE OF WORKDEPT, PHONENO, JOB, EDLEVEL, SALARY;
EXEC SQL DECLARE C4 CURSOR WITH HOLD WITH RETURN FOR SELECT PROJNO , PROJNAME FROM DSN8A10.PROJ WHERE DEPTNO = 'A01';
EXEC SQL DECLARE C5 SENSITIVE STATIC SCROLL CURSOR FOR SELECT DEPTNO , DEPTNAME , MGRNO FROM DSN8A10.DEPT WHERE ADMRDEPT = 'A00';
EXEC SQL DECLARE C6 INSENSITIVE SCROLL CURSOR FOR SELECT DEPTNO , DEPTNAME , MGRNO FROM DSN8A10.DEPT WHERE DEPTNO;
CREATE TABLE ORDER (ORDERNUM INTEGER, CUSTNUM INTEGER, CUSTNAME VARCHAR(20), ORDERDATE CHAR(8), ORDERAMT DECIMAL(8,3), COMMENTS VARCHAR(20));
EXEC SQL DECLARE CURSOR ORDERSCROLL SENSITIVE DYNAMIC SCROLL FOR SELECT ORDERNUM , CUSTNAME , ORDERAMT , ORDERDATE FROM ORDER WHERE ORDERAMT > 1000 FOR UPDATE OF COMMENTS;
OPEN CURSOR ORDERSCROLL;
-- Loop-to-fill-screen -- do 10 times FETCH FROM ORDERSCROLL INTO :HV1, :HV2, :HV3, :HV4; -- end
-- Skip-forward-100-rows FETCH RELATIVE +100 FROM ORDERSCROLL INTO :HV1, :HV2, :HV3, :HV4;
-- Skip-backward-50-rows FETCH RELATIVE -50 FROM ORDERSCROLL INTO :HV1, :HV2, :HV3, :HV4;
Fetch ABSOLUTE from the scrollable cursor.
-- Re-read-the-third-row FETCH ABSOLUTE +3 FROM ORDERSCROLL INTO :HV1, :HV2, :HV3, :HV4;
Fetch RELATIVE from scrollable cursor.
-- Read-the-third-row-from current position FETCH SENSITIVE RELATIVE +3 FROM ORDERSCROLL INTO :HV1, :HV2, :HV3, :HV4;
Do a positioned update through the scrollable cursor.
-- Update-the-current-row UPDATE ORDER SET COMMENTS = "Expedite" WHERE CURRENT OF ORDERSCROLL;
Close the scrollable cursor.
CLOSE CURSOR ORDERSCROLL;
Declare C1 as the cursor of a query to retrieve a rowset from the table DEPT. The prepared statement is MYCURSOR.
EXEC SQL DECLARE C1 CURSOR WITH ROWSET POSITIONING FOR MYCURSOR;