IMS Cursor Positioning and Sequential Retrieval
IMS maintains a current position in the database for each PCB — essentially a pointer to the last segment successfully processed. Every DL/I call either uses this position (GN, GNP) or resets it (GU). Understanding how IMS tracks and updates position is critical for writing correct sequential processing programs.
What is IMS Database Position?
After a successful DL/I call, IMS stores the hierarchical position of the retrieved segment in the PCB. This includes:
- The segment type retrieved
- The full hierarchical key path to that segment
- The physical location in the database
Subsequent GN calls start from this position and move forward. GNP calls return segments within the current parent at this position.
GU Resets Position
A GU call always resets position regardless of where IMS was previously positioned. After a GU:
- The position is set to the segment returned by the GU
- Subsequent GN calls start from that point forward
This means you can use GU as a way to "seek" to a specific location in the database before starting sequential processing:
* Position at customer 1001 before sequential account scan
MOVE '1001000001' TO SSA-CUST-KEY.
CALL 'CBLTDLI' USING GU-FUNC
CUSTOMER-PCB
CUSTOMER-IO-AREA
CUSTOMER-QUAL-SSA.
* Now GNP for accounts under customer 1001
PERFORM READ-ACCOUNTS UNTIL NO-MORE-ACCOUNTS.GN Moves Forward from Current Position
GN reads the next segment in hierarchical sequence from the current position. It respects the hierarchy — it will read child segments, sibling segments, and then move to the next parent's segments.
The sequence GN follows:
- Move to the first child of the current segment (if any)
- If no children, move to the next sibling
- If no more siblings, move up to the parent's next sibling
- Continue until the end of the database (status
GB)
* Sequential scan of the ENTIRE database
PERFORM UNTIL END-OF-DB
CALL 'CBLTDLI' USING GN-FUNC
CUSTOMER-PCB
GENERIC-IO-AREA
*> no SSA = any segment type
EVALUATE PCB-STATUS-CODE
WHEN ' '
EVALUATE PCB-SEG-NAME
WHEN 'CUSTOMER' PERFORM PROCESS-CUSTOMER
WHEN 'ACCOUNT ' PERFORM PROCESS-ACCOUNT
WHEN 'TRANSACT' PERFORM PROCESS-TRANSACT
END-EVALUATE
WHEN 'GB'
MOVE 'Y' TO END-OF-DB
END-EVALUATE
END-PERFORM.GNP — Position Constrained to Parent
GNP returns the next segment within the current parent. Once all children of the current parent are exhausted, GNP returns GE and does not advance to the next parent.
After a GNP returns GE:
- IMS position is at the end of the current parent's subtree
- The next GN will move to the next segment after this parent's entire subtree
- The next GNP would also return
GE(no more children here)
To move to the next parent and process its children, issue a new GN (or GHN in an update loop):
* Pattern: process all customers and their accounts
PERFORM UNTIL NO-MORE-CUSTOMERS
*> Get next customer
CALL 'CBLTDLI' USING GN-FUNC
CUSTOMER-PCB
CUSTOMER-IO-AREA
CUSTOMER-UNQUAL-SSA
EVALUATE PCB-STATUS-CODE
WHEN ' '
PERFORM PROCESS-ACCOUNTS-FOR-THIS-CUSTOMER
WHEN 'GB'
MOVE 'Y' TO NO-MORE-CUSTOMERS
END-EVALUATE
END-PERFORM.
PROCESS-ACCOUNTS-FOR-THIS-CUSTOMER.
MOVE 'N' TO NO-MORE-ACCOUNTS.
PERFORM UNTIL NO-MORE-ACCOUNTS
CALL 'CBLTDLI' USING GNP-FUNC
CUSTOMER-PCB
ACCOUNT-IO-AREA
ACCOUNT-UNQUAL-SSA
EVALUATE PCB-STATUS-CODE
WHEN ' ' PERFORM PROCESS-ONE-ACCOUNT
WHEN 'GE' MOVE 'Y' TO NO-MORE-ACCOUNTS
WHEN OTHER PERFORM IMS-ERROR
END-EVALUATE
END-PERFORM.Position Loss: When Position Becomes Unpredictable
Position can be disturbed or lost in several situations:
ISRT on a new segment type: Inserting a new root segment changes position in the database. If you are mid-scan and insert a new root, subsequent GN may not behave as expected.
Database errors: Status codes other than blank, GE, and GB indicate problems. After an unexpected status code, position should be re-established with a GU before continuing.
PSB PROCOPT restrictions: If your PCB does not have sensitivity to a segment type, IMS skips it during GN but still advances position past it. The program does not see skipped segments but position moves through them.
Multiple PCBs: Each PCB maintains its own independent position. Using PCB1 does not affect position in PCB2.
Saving and Restoring Position
The PCB key feedback area contains the concatenated key of the last retrieved segment. You can save this value and later use it in a GU call to restore position:
* Save position
MOVE PCB-KEY-FBCK TO WS-SAVED-KEY.
* Restore position later
MOVE WS-SAVED-KEY TO CUSTOMER-GU-SSA-KEY.
CALL 'CBLTDLI' USING GU-FUNC
CUSTOMER-PCB
CUSTOMER-IO-AREA
CUSTOMER-QUAL-SSA.Frequently Asked Questions
Q: What happens to position when an IMS program issues a SYNCPOINT? A SYNCPOINT (commit) does not reset IMS database position. Programs can continue sequential processing across SYNCPOINT calls. This is important for long-running batch programs that commit every N records — position is preserved through each commit.
Q: Can I process a database backwards (in reverse sequence)? IMS does not support backward navigation. All sequential movement is forward only. To process in reverse key order, you must retrieve all relevant keys in a forward pass, store them, and then process in reverse order using GU calls. Alternatively, load the data into a COBOL table and sort it.
Q: What does the L command code in an SSA do for position?
The L command code (SEGNAME*L) navigates to the last occurrence of a segment type under the current parent. After a GNP with L command code, position is at the last child, and subsequent GNP calls return GE (no more children forward). L is useful when you need to append to the end of a series of twin segments.
Part of the IMS Mastery Course — Module 15 of 22.
