Cursor


Why Cursor?


Assume that the SELECT WHERE condition retrieves more than one row while reading the DB2 table in the application program. In that case, the query returns the first row from the result set to the host variables from the result set and returns the SQLCODE as -811.

As per the standard error handling, the program gets abend if SQL query returns SQLCODE other than ZERO or 100.

To avoid the program abending, we need to retrieve the SQLCODE from the executed query and validate it like below -

IF SQLCODE EQUALS ZERO 
OR SQLCODE EQUALS -811
	Continue-the-program-flow
ELSE
	abend-the-program
END-IF.

In the above case, we can only retrieve any row that satisfies the condition and can’t retrieve the further rows that satisfy the same condition.

If our requirement is to retrieve the first row even though the WHERE condition coded retrieving more than one row, then handling the SQLCODE is sufficient.

However, if we need to process all the satisfied rows one by one, a simple SELECT statement can't do it on a single iteration.

This requires a unique mechanism to retrieve all rows and process them one by one. The mechanism is known as "CURSOR" in DB2.

What is Cursor?


The cursor is used to retrieve rows from a result set and process them one by one. The process is almost the same as pointing the finger at a specific line on the printed page.

The application program retrieves and processes one or more rows that satisfy the WHERE condition in the SELECT statement using the cursor.

The application program processes the rows one by one sequentially after being retrieved. It’s like the sequential access of the file. The rows can be retrieved based on the search condition (WHERE) provided.

We can use the cursor in two areas to retrieve the data from the table, and those are -

  • Application program
  • DB2 stored procedure

We will discuss the application program with the cursor concept in this topic.

The result set is also referred to as the result table while using the cursor.

Cursor Life Cycle -


The cursor plays an important role in retrieving the rows one by one from the result table. The cursor life cycle has the following phases -

PhaseDescription
Declare Cursor Declares a cursor in the application program.
Open Cursor Opens the cursor declared in the application program.
Fetch Cursor Retrieves the current positioned row data and assigns it to the corresponding variable(s) / host variable(s).
Close Cursor Closes the cursor specified with it.

Cursor Types -


The CURSOR can divide into various types based on its definition and usage in the application program. Those are -

  • Data modification based cursors
  • Data modification statement based cursors
  • Positioning based cursors
  • Modified data reflection-based cursors
  • Processing stability based cursors
  • Mixed feature cursors

All cursor types are explained in detail in the Cursor Types topic.

Practical Example -


Scenario - The below example describes how the cursor is declared and used in the COBOL + DB2 program.

Requirement - Display employee id, name, designation from department 1000 in the employee_details table.

Input- employee_details table

employee_details table

CURSOR Example Code -

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
***************************** Top of Data ******************************
       IDENTIFICATION DIVISION.                                         
       PROGRAM-ID. CREADONL.                                            
                                                                        
       ENVIRONMENT DIVISION.                                            
       DATA DIVISION.                                                   
       WORKING-STORAGE SECTION.                                         
                                                                        
           EXEC SQL                                                     
             INCLUDE SQLCA                                              
           END-EXEC.                                                    
                                                                        
           EXEC SQL                                                     
             INCLUDE EMPLDET                                            
           END-EXEC.                                                    
                                                                        
      * DECLARING CURSOR                                                
                                                                        
           EXEC SQL                                                     
                DECLARE CSR1 CURSOR FOR                                 
                SELECT EMP_ID,                                          
                       EMP_NAME,                                        
                       DESIGNATION                                      
                FROM   EMPLOYEE_DETAILS                                 
                WHERE  DEPT_ID = 1000                                   
                FOR    FETCH ONLY                                       
           END-EXEC.                                                    
                                                                        
       PROCEDURE DIVISION.                                              
                                                                        
      * OPENING CURSOR                                                  
                                                                        
           EXEC SQL                                                     
                OPEN CSR1                                               
           END-EXEC.                                                    
                                                                        
      * FETCHING CURSOR LOOP UNTIL END OF RESULT TABLE                  
                                                                        
           IF SQLCODE EQUAL ZERO                                        
              PERFORM FETCH-EMP-DETAILS                                 
                 THRU FETCH-EMP-DETAILS-EXIT                            
                UNTIL SQLCODE NOT EQUAL 0                               
           END-IF.                                                      
                                                                        
      * CLOSING CURSOR                                                  
                                                                        
           EXEC SQL                                                     
                CLOSE CSR1                                              
           END-EXEC.                                                    
                                                                        
           STOP RUN.                                                    
                                                                        
       FETCH-EMP-DETAILS.                                               
                                                                        
      * FETCH CURSOR                                                    
                                                                        
           EXEC SQL                                                     
                FETCH CSR1                                              
                INTO   :EMP-ID,                                         
                       :EMP-NAME,                                       
                       :DESIGNATION                                     
           END-EXEC.                                                    
                                                                        
           EVALUATE SQLCODE                                             
               WHEN ZERO                                                
                    DISPLAY  EMP-ID, "|", EMP-NAME, "|",                
                             DESIGNATION                                
               WHEN 100                                                 
                    CONTINUE                                            
               WHEN OTHER                                               
                    DISPLAY "DB2 ERROR:  ", SQLCODE                     
           END-EVALUATE.                                                
                                                                        
       FETCH-EMP-DETAILS-EXIT.                                          
           EXIT.                                                        
**************************** Bottom of Data ****************************

Output -

CURSOR Program Output