CoreCobol
Read many rows with a cursor and commit safely
The batch pattern: WITH HOLD, periodic commit, and a restart record.
WORKING-STORAGE SECTION.
EXEC SQL INCLUDE SQLCA END-EXEC.
01 WS-COMMIT-FREQ PIC S9(5) COMP VALUE 5000.
01 WS-SINCE-COMMIT PIC S9(5) COMP VALUE ZERO.
01 WS-PROCESSED PIC S9(9) COMP VALUE ZERO.
01 WS-LAST-KEY PIC X(10) VALUE LOW-VALUES.
EXEC SQL DECLARE ACCT_CUR CURSOR WITH HOLD FOR
SELECT ACCT_ID, BALANCE
FROM PAYPROD.ACCOUNT
WHERE ACCT_ID > :WS-LAST-KEY
AND STATUS = 'A'
ORDER BY ACCT_ID
WITH CS
END-EXEC.
1000-RESTART.
EXEC SQL
SELECT LAST_KEY INTO :WS-LAST-KEY
FROM PAYPROD.RESTART_CTL
WHERE PGM_NAME = 'PAYUPD'
END-EXEC
IF SQLCODE = +100
MOVE LOW-VALUES TO WS-LAST-KEY
END-IF.
2000-PROCESS.
EXEC SQL FETCH ACCT_CUR
INTO :WS-ACCT-ID, :WS-BALANCE END-EXEC
EVALUATE SQLCODE
WHEN 0
PERFORM 2100-UPDATE-ROW
MOVE WS-ACCT-ID TO WS-LAST-KEY
ADD 1 TO WS-SINCE-COMMIT WS-PROCESSED
IF WS-SINCE-COMMIT >= WS-COMMIT-FREQ
PERFORM 2900-CHECKPOINT
END-IF
WHEN +100 SET END-OF-CURSOR TO TRUE
WHEN OTHER PERFORM 9000-SQL-ERROR
END-EVALUATE.
2900-CHECKPOINT.
EXEC SQL
UPDATE PAYPROD.RESTART_CTL
SET LAST_KEY = :WS-LAST-KEY,
ROWS_DONE = :WS-PROCESSED
WHERE PGM_NAME = 'PAYUPD'
END-EXEC
EXEC SQL COMMIT END-EXEC
MOVE ZERO TO WS-SINCE-COMMIT.- WITH HOLD keeps the cursor open across the commit. Without it the next FETCH fails with -501.
- The restart key is updated in the same unit of work as the data, so a failure never leaves them inconsistent.
- The commit frequency is a variable, so it can be tuned without recompiling.
- The WHERE clause uses the restart key, so a restart resumes rather than reprocessing.
Stuck on something else?
Ask the community or search the full course.