In this section, we will delve into the concept of cursors in COBOL, particularly when working with databases like DB2. Cursors are essential for handling multiple rows of data retrieved from a database. They allow you to process each row individually, which is crucial for applications that need to handle large datasets.

What is a Cursor?

A cursor is a database object used to retrieve, manipulate, and navigate through a result set row by row. It acts as a pointer to the rows in a result set, enabling you to fetch and process each row sequentially.

Key Concepts of Cursors

  1. Declaration: Define the cursor and the SQL query it will execute.
  2. Opening: Execute the SQL query and establish the result set.
  3. Fetching: Retrieve rows from the result set one at a time.
  4. Closing: Release the cursor and its resources.

Declaring a Cursor

To declare a cursor in COBOL, you use the EXEC SQL DECLARE CURSOR statement. This statement specifies the SQL query that the cursor will execute.

Example

EXEC SQL
    DECLARE EMP_CURSOR CURSOR FOR
    SELECT EMP_ID, EMP_NAME, EMP_SALARY
    FROM EMPLOYEE
    WHERE DEPARTMENT = 'SALES'
END-EXEC.

In this example, EMP_CURSOR is declared to select employee details from the EMPLOYEE table where the department is 'SALES'.

Opening a Cursor

After declaring the cursor, you need to open it to execute the SQL query and establish the result set.

Example

EXEC SQL
    OPEN EMP_CURSOR
END-EXEC.

Fetching Data

Once the cursor is open, you can fetch rows from the result set. The FETCH statement retrieves the next row and moves the cursor to the subsequent row.

Example

EXEC SQL
    FETCH EMP_CURSOR INTO :EMP-ID, :EMP-NAME, :EMP-SALARY
END-EXEC.

In this example, the FETCH statement retrieves the next row from EMP_CURSOR and stores the values into COBOL variables EMP-ID, EMP-NAME, and EMP-SALARY.

Looping Through Rows

Typically, you will use a loop to fetch all rows from the cursor until no more rows are available.

Example

PERFORM UNTIL SQLCODE NOT = 0
    EXEC SQL
        FETCH EMP_CURSOR INTO :EMP-ID, :EMP-NAME, :EMP-SALARY
    END-EXEC

    IF SQLCODE = 0
        DISPLAY 'Employee ID: ' EMP-ID
        DISPLAY 'Employee Name: ' EMP-NAME
        DISPLAY 'Employee Salary: ' EMP-SALARY
    END-IF
END-PERFORM.

In this example, the loop continues fetching rows until SQLCODE is not equal to 0, indicating no more rows are available.

Closing a Cursor

After processing all rows, you should close the cursor to release its resources.

Example

EXEC SQL
    CLOSE EMP_CURSOR
END-EXEC.

Practical Exercise

Task

Write a COBOL program that uses a cursor to fetch and display all employees' details from the EMPLOYEE table where the department is 'HR'.

Solution

IDENTIFICATION DIVISION.
PROGRAM-ID. FetchEmployees.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 EMP-ID      PIC 9(5).
01 EMP-NAME    PIC X(20).
01 EMP-SALARY  PIC 9(7)V99.

EXEC SQL
    INCLUDE SQLCA
END-EXEC.

PROCEDURE DIVISION.
MAIN-LOGIC.
    EXEC SQL
        DECLARE HR_CURSOR CURSOR FOR
        SELECT EMP_ID, EMP_NAME, EMP_SALARY
        FROM EMPLOYEE
        WHERE DEPARTMENT = 'HR'
    END-EXEC.

    EXEC SQL
        OPEN HR_CURSOR
    END-EXEC.

    PERFORM UNTIL SQLCODE NOT = 0
        EXEC SQL
            FETCH HR_CURSOR INTO :EMP-ID, :EMP-NAME, :EMP-SALARY
        END-EXEC

        IF SQLCODE = 0
            DISPLAY 'Employee ID: ' EMP-ID
            DISPLAY 'Employee Name: ' EMP-NAME
            DISPLAY 'Employee Salary: ' EMP-SALARY
        END-IF
    END-PERFORM.

    EXEC SQL
        CLOSE HR_CURSOR
    END-EXEC.

    STOP RUN.

Explanation

  1. Declare Cursor: The cursor HR_CURSOR is declared to select employee details from the EMPLOYEE table where the department is 'HR'.
  2. Open Cursor: The cursor is opened to execute the SQL query.
  3. Fetch Rows: A loop fetches each row from the cursor and displays the employee details.
  4. Close Cursor: The cursor is closed after all rows are processed.

Common Mistakes and Tips

  • Forgetting to Close the Cursor: Always close the cursor to free up resources.
  • Handling SQLCODE: Check SQLCODE after each FETCH to handle any errors or end-of-data conditions.
  • Variable Mismatch: Ensure that the COBOL variables match the data types and lengths of the database columns.

Conclusion

In this section, you learned how to handle cursors in COBOL for database operations. Cursors are powerful tools for processing multiple rows of data efficiently. By mastering cursor operations, you can build robust COBOL applications that interact seamlessly with databases. In the next module, we will explore advanced topics in COBOL, including object-oriented programming and web services.

© Copyright 2024. All rights reserved