Case Study 1: Customer Account Hierarchy in IMS
Background
First National Federal Bank has served the mid-Atlantic region for over sixty years, processing millions of transactions daily across checking, savings, mortgage, and investment accounts. The bank's core customer data resides in an IMS (Information Management System) hierarchical database that was designed in 1978 and has been continuously refined. The database models the natural hierarchy of banking relationships: a customer owns one or more accounts, and each account contains a history of transactions.
In early 2025, senior systems programmer Raymond Okafor was tasked with building a new customer inquiry program. Branch tellers needed a consolidated view of a customer's entire relationship with the bank -- every account and the most recent transactions on each account -- displayed on a single CICS screen. The back-end COBOL program would navigate the IMS hierarchy using DL/I (Data Language/I) calls, retrieve the necessary segments, and format the data for presentation.
This case study examines how Raymond designed the IMS database structure, defined the Program Communication Block (PCB) masks in COBOL, and coded the DL/I calls to navigate the customer-account-transaction hierarchy.
The IMS Database Structure
The IMS database, named CUSTDB, uses a simple three-level hierarchy:
CUSTOMER (root segment)
|
+-- ACCOUNT (child of CUSTOMER)
|
+-- TRANSACTION (child of ACCOUNT)
Each segment type has a fixed layout:
- CUSTOMER (root): Contains customer ID, name, address, phone, and relationship date. The customer ID is the sequence field.
- ACCOUNT: Contains account number, account type (CHK, SAV, MTG, INV), status (ACTIVE, CLOSED, FROZEN), current balance, and date opened. The account number is the sequence field within each customer occurrence.
- TRANSACTION: Contains transaction ID, date, type (DEP, WDR, TFR, PMT, INT), amount, running balance, and description. The transaction ID is the sequence field within each account occurrence.
The Database Description (DBD) defines these segments and their relationships. In production, the DBD is generated by the DBA team and assembled into the IMS catalog. The COBOL programmer does not code the DBD but must understand its structure to write correct DL/I calls.
The Program Specification Block (PSB)
Before a COBOL program can access an IMS database, a PSB must be defined. The PSB specifies which segments the program is authorized to access and what operations (Get, Insert, Replace, Delete) are permitted. Raymond's inquiry program needed read-only access to all three segment types:
PCB TYPE=DB,DBDNAME=CUSTDB,PROCOPT=G,KEYLEN=25
SENSEG NAME=CUSTOMER,PARENT=0
SENSEG NAME=ACCOUNT,PARENT=CUSTOMER
SENSEG NAME=TRANSACT,PARENT=ACCOUNT
The PROCOPT=G restricts the program to Get operations only -- no updates, inserts, or deletes. This is appropriate for an inquiry program and provides a safety net against accidental data modification.
COBOL Program: PCB Mask and Segment Layouts
The heart of any IMS COBOL program is the linkage between the program and IMS, established through the PCB mask and the ENTRY statement. Raymond defined the following structures:
IDENTIFICATION DIVISION.
PROGRAM-ID. CUSTINQ1.
*================================================================*
* CUSTINQ1 - Customer Account Inquiry Program *
* Navigates the CUSTDB IMS hierarchy to retrieve a customer's *
* complete relationship: all accounts and recent transactions. *
*================================================================*
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
*================================================================*
* DL/I function codes *
*================================================================*
01 WS-DLI-GU PIC X(4) VALUE 'GU '.
01 WS-DLI-GN PIC X(4) VALUE 'GN '.
01 WS-DLI-GNP PIC X(4) VALUE 'GNP '.
01 WS-DLI-GHU PIC X(4) VALUE 'GHU '.
01 WS-DLI-GHN PIC X(4) VALUE 'GHN '.
*================================================================*
* Status code evaluation fields *
*================================================================*
01 WS-GOOD-STATUS PIC XX VALUE SPACES.
01 WS-NOT-FOUND PIC XX VALUE 'GE'.
01 WS-END-OF-PARENT PIC XX VALUE 'GE'.
01 WS-END-OF-DB PIC XX VALUE 'GB'.
*================================================================*
* Customer segment I/O area *
*================================================================*
01 WS-CUSTOMER-SEG.
05 WS-CUST-ID PIC X(10).
05 WS-CUST-LAST-NAME PIC X(25).
05 WS-CUST-FIRST-NAME PIC X(20).
05 WS-CUST-MIDDLE-INIT PIC X(1).
05 WS-CUST-ADDR-LINE1 PIC X(30).
05 WS-CUST-ADDR-LINE2 PIC X(30).
05 WS-CUST-CITY PIC X(20).
05 WS-CUST-STATE PIC X(2).
05 WS-CUST-ZIP PIC X(10).
05 WS-CUST-PHONE PIC X(15).
05 WS-CUST-REL-DATE PIC X(10).
05 WS-CUST-TIER PIC X(2).
05 FILLER PIC X(25).
*================================================================*
* Account segment I/O area *
*================================================================*
01 WS-ACCOUNT-SEG.
05 WS-ACCT-NUMBER PIC X(12).
05 WS-ACCT-TYPE PIC X(3).
05 WS-ACCT-STATUS PIC X(8).
05 WS-ACCT-BALANCE PIC S9(11)V99 COMP-3.
05 WS-ACCT-OPEN-DATE PIC X(10).
05 WS-ACCT-LAST-ACTIVITY PIC X(10).
05 WS-ACCT-BRANCH PIC X(4).
05 FILLER PIC X(20).
*================================================================*
* Transaction segment I/O area *
*================================================================*
01 WS-TRANSACT-SEG.
05 WS-TXN-ID PIC X(15).
05 WS-TXN-DATE PIC X(10).
05 WS-TXN-TYPE PIC X(3).
05 WS-TXN-AMOUNT PIC S9(9)V99 COMP-3.
05 WS-TXN-RUN-BALANCE PIC S9(11)V99 COMP-3.
05 WS-TXN-DESC PIC X(30).
05 FILLER PIC X(10).
*================================================================*
* Segment Search Arguments (SSAs) *
*================================================================*
01 WS-CUST-QUAL-SSA.
05 FILLER PIC X(9) VALUE 'CUSTOMER('.
05 FILLER PIC X(10) VALUE 'CUST_ID ='.
05 WS-SSA-CUST-ID PIC X(10).
05 FILLER PIC X(1) VALUE ')'.
01 WS-ACCT-UNQUAL-SSA.
05 FILLER PIC X(9) VALUE 'ACCOUNT '.
01 WS-TXN-UNQUAL-SSA.
05 FILLER PIC X(9) VALUE 'TRANSACT '.
*================================================================*
* Program control fields *
*================================================================*
01 WS-INPUT-CUST-ID PIC X(10).
01 WS-ACCT-COUNT PIC 9(3) VALUE ZEROS.
01 WS-TXN-COUNT PIC 9(5) VALUE ZEROS.
01 WS-TOTAL-BALANCE PIC S9(13)V99 VALUE ZEROS.
01 WS-MAX-TXN-PER-ACCT PIC 9(3) VALUE 10.
01 WS-TXN-DISPLAY-COUNT PIC 9(3) VALUE ZEROS.
01 WS-MORE-ACCOUNTS PIC X VALUE 'Y'.
88 NO-MORE-ACCOUNTS VALUE 'N'.
01 WS-MORE-TRANSACTIONS PIC X VALUE 'Y'.
88 NO-MORE-TRANSACTIONS VALUE 'N'.
01 WS-ERROR-FLAG PIC X VALUE 'N'.
88 PROCESSING-ERROR VALUE 'Y'.
01 WS-ERROR-MSG PIC X(80) VALUE SPACES.
01 WS-BALANCE-EDITED PIC $$$,$$$,$$$,$$9.99-.
01 WS-AMOUNT-EDITED PIC $$$$,$$$,$$9.99-.
*================================================================*
* PCB Mask - defined in LINKAGE SECTION *
*================================================================*
LINKAGE SECTION.
01 LS-PCB-MASK.
05 LS-DBD-NAME PIC X(8).
05 LS-SEG-LEVEL PIC XX.
05 LS-STATUS-CODE PIC XX.
05 LS-PROC-OPTIONS PIC X(4).
05 LS-RESERVED PIC S9(5) COMP.
05 LS-SEG-NAME PIC X(8).
05 LS-KEY-LENGTH PIC S9(5) COMP.
05 LS-NUM-SENS-SEGS PIC S9(5) COMP.
05 LS-KEY-FEEDBACK PIC X(25).
*================================================================*
* PROCEDURE DIVISION with IMS entry point *
*================================================================*
PROCEDURE DIVISION USING LS-PCB-MASK.
0000-MAIN-CONTROL.
PERFORM 1000-INITIALIZE
PERFORM 2000-RETRIEVE-CUSTOMER
IF NOT PROCESSING-ERROR
PERFORM 3000-RETRIEVE-ACCOUNTS
END-IF
PERFORM 9000-WRAP-UP
GOBACK.
*================================================================*
* 1000-INITIALIZE: Set up program variables and accept input. *
*================================================================*
1000-INITIALIZE.
MOVE ZEROS TO WS-ACCT-COUNT
MOVE ZEROS TO WS-TXN-COUNT
MOVE ZEROS TO WS-TOTAL-BALANCE
MOVE 'N' TO WS-ERROR-FLAG
MOVE 'Y' TO WS-MORE-ACCOUNTS
* In a CICS environment, the customer ID would come from
* the terminal input. Here we accept it for batch testing.
ACCEPT WS-INPUT-CUST-ID FROM SYSIN
DISPLAY '============================================='
DISPLAY ' CUSTOMER RELATIONSHIP INQUIRY'
DISPLAY ' Searching for Customer: ' WS-INPUT-CUST-ID
DISPLAY '============================================='
.
*================================================================*
* 2000-RETRIEVE-CUSTOMER: Issue GU call with qualified SSA to *
* position directly on the target customer segment. *
*================================================================*
2000-RETRIEVE-CUSTOMER.
MOVE WS-INPUT-CUST-ID TO WS-SSA-CUST-ID
CALL 'CBLTDLI' USING WS-DLI-GU
LS-PCB-MASK
WS-CUSTOMER-SEG
WS-CUST-QUAL-SSA
EVALUATE LS-STATUS-CODE
WHEN WS-GOOD-STATUS
PERFORM 2100-DISPLAY-CUSTOMER
WHEN WS-NOT-FOUND
MOVE 'Y' TO WS-ERROR-FLAG
STRING 'Customer ' WS-INPUT-CUST-ID
' not found in database.'
DELIMITED SIZE INTO WS-ERROR-MSG
DISPLAY WS-ERROR-MSG
WHEN OTHER
MOVE 'Y' TO WS-ERROR-FLAG
STRING 'Unexpected DL/I status: '
LS-STATUS-CODE
' on GU CUSTOMER call.'
DELIMITED SIZE INTO WS-ERROR-MSG
DISPLAY WS-ERROR-MSG
PERFORM 8000-DLI-ERROR-HANDLER
END-EVALUATE
.
*================================================================*
* 2100-DISPLAY-CUSTOMER: Format and display customer details. *
*================================================================*
2100-DISPLAY-CUSTOMER.
DISPLAY ' '
DISPLAY ' CUSTOMER INFORMATION'
DISPLAY ' --------------------'
DISPLAY ' Customer ID: ' WS-CUST-ID
DISPLAY ' Name: '
WS-CUST-FIRST-NAME ' '
WS-CUST-MIDDLE-INIT '. '
WS-CUST-LAST-NAME
DISPLAY ' Address: ' WS-CUST-ADDR-LINE1
IF WS-CUST-ADDR-LINE2 NOT = SPACES
DISPLAY ' ' WS-CUST-ADDR-LINE2
END-IF
DISPLAY ' '
WS-CUST-CITY ', ' WS-CUST-STATE ' '
WS-CUST-ZIP
DISPLAY ' Phone: ' WS-CUST-PHONE
DISPLAY ' Member Since: ' WS-CUST-REL-DATE
DISPLAY ' Tier: ' WS-CUST-TIER
.
*================================================================*
* 3000-RETRIEVE-ACCOUNTS: Use GNP to retrieve all account *
* segments under the current customer. For each account, also *
* retrieve recent transactions. *
*================================================================*
3000-RETRIEVE-ACCOUNTS.
DISPLAY ' '
DISPLAY ' ACCOUNTS ON FILE'
DISPLAY ' ================'
MOVE 'Y' TO WS-MORE-ACCOUNTS
PERFORM 3100-GET-NEXT-ACCOUNT
PERFORM UNTIL NO-MORE-ACCOUNTS
ADD 1 TO WS-ACCT-COUNT
PERFORM 3200-DISPLAY-ACCOUNT
ADD WS-ACCT-BALANCE TO WS-TOTAL-BALANCE
PERFORM 4000-RETRIEVE-TRANSACTIONS
PERFORM 3100-GET-NEXT-ACCOUNT
END-PERFORM
PERFORM 3300-DISPLAY-ACCOUNT-SUMMARY
.
*================================================================*
* 3100-GET-NEXT-ACCOUNT: Issue GNP call to get the next *
* account segment under the established customer parent. *
* GNP (Get Next within Parent) ensures we stay within the *
* current customer's subtree. *
*================================================================*
3100-GET-NEXT-ACCOUNT.
CALL 'CBLTDLI' USING WS-DLI-GNP
LS-PCB-MASK
WS-ACCOUNT-SEG
WS-ACCT-UNQUAL-SSA
EVALUATE LS-STATUS-CODE
WHEN WS-GOOD-STATUS
CONTINUE
WHEN 'GE'
MOVE 'N' TO WS-MORE-ACCOUNTS
WHEN OTHER
MOVE 'N' TO WS-MORE-ACCOUNTS
MOVE 'Y' TO WS-ERROR-FLAG
STRING 'DL/I error ' LS-STATUS-CODE
' on GNP ACCOUNT call.'
DELIMITED SIZE INTO WS-ERROR-MSG
DISPLAY WS-ERROR-MSG
PERFORM 8000-DLI-ERROR-HANDLER
END-EVALUATE
.
*================================================================*
* 3200-DISPLAY-ACCOUNT: Format and display account information. *
*================================================================*
3200-DISPLAY-ACCOUNT.
MOVE WS-ACCT-BALANCE TO WS-BALANCE-EDITED
DISPLAY ' '
DISPLAY ' Account #' WS-ACCT-COUNT ': '
WS-ACCT-NUMBER
DISPLAY ' Type: '
WS-ACCT-TYPE
DISPLAY ' Status: '
WS-ACCT-STATUS
DISPLAY ' Current Balance: '
WS-BALANCE-EDITED
DISPLAY ' Opened: '
WS-ACCT-OPEN-DATE
DISPLAY ' Last Activity: '
WS-ACCT-LAST-ACTIVITY
DISPLAY ' Branch: '
WS-ACCT-BRANCH
.
*================================================================*
* 3300-DISPLAY-ACCOUNT-SUMMARY: Show total accounts and *
* combined balance across all accounts. *
*================================================================*
3300-DISPLAY-ACCOUNT-SUMMARY.
MOVE WS-TOTAL-BALANCE TO WS-BALANCE-EDITED
DISPLAY ' '
DISPLAY ' ================'
DISPLAY ' RELATIONSHIP SUMMARY'
DISPLAY ' Total Accounts: ' WS-ACCT-COUNT
DISPLAY ' Combined Balance: ' WS-BALANCE-EDITED
DISPLAY ' Total Transactions: ' WS-TXN-COUNT
DISPLAY ' ================'
.
*================================================================*
* 4000-RETRIEVE-TRANSACTIONS: Use GNP to retrieve transaction *
* segments under the current account. Limits display to the *
* most recent N transactions (WS-MAX-TXN-PER-ACCT). *
*================================================================*
4000-RETRIEVE-TRANSACTIONS.
DISPLAY ' Recent Transactions:'
DISPLAY ' DATE TYPE AMOUNT'
' BALANCE DESCRIPTION'
DISPLAY ' ---------- ---- ------------'
' -------------- ---------------------'
MOVE 'Y' TO WS-MORE-TRANSACTIONS
MOVE ZEROS TO WS-TXN-DISPLAY-COUNT
PERFORM 4100-GET-NEXT-TRANSACTION
PERFORM UNTIL NO-MORE-TRANSACTIONS
OR WS-TXN-DISPLAY-COUNT >= WS-MAX-TXN-PER-ACCT
ADD 1 TO WS-TXN-COUNT
ADD 1 TO WS-TXN-DISPLAY-COUNT
PERFORM 4200-DISPLAY-TRANSACTION
PERFORM 4100-GET-NEXT-TRANSACTION
END-PERFORM
IF WS-TXN-DISPLAY-COUNT = ZEROS
DISPLAY ' (No transactions on file)'
END-IF
.
*================================================================*
* 4100-GET-NEXT-TRANSACTION: Issue GNP to get the next *
* transaction under the current account parent. *
*================================================================*
4100-GET-NEXT-TRANSACTION.
CALL 'CBLTDLI' USING WS-DLI-GNP
LS-PCB-MASK
WS-TRANSACT-SEG
WS-TXN-UNQUAL-SSA
EVALUATE LS-STATUS-CODE
WHEN WS-GOOD-STATUS
CONTINUE
WHEN 'GE'
MOVE 'N' TO WS-MORE-TRANSACTIONS
WHEN OTHER
MOVE 'N' TO WS-MORE-TRANSACTIONS
MOVE 'Y' TO WS-ERROR-FLAG
STRING 'DL/I error ' LS-STATUS-CODE
' on GNP TRANSACT call.'
DELIMITED SIZE INTO WS-ERROR-MSG
DISPLAY WS-ERROR-MSG
PERFORM 8000-DLI-ERROR-HANDLER
END-EVALUATE
.
*================================================================*
* 4200-DISPLAY-TRANSACTION: Format and display one transaction. *
*================================================================*
4200-DISPLAY-TRANSACTION.
MOVE WS-TXN-AMOUNT TO WS-AMOUNT-EDITED
MOVE WS-TXN-RUN-BALANCE TO WS-BALANCE-EDITED
DISPLAY ' '
WS-TXN-DATE ' '
WS-TXN-TYPE ' '
WS-AMOUNT-EDITED ' '
WS-BALANCE-EDITED ' '
WS-TXN-DESC
.
*================================================================*
* 8000-DLI-ERROR-HANDLER: Centralized error handling for *
* unexpected DL/I status codes. Logs diagnostic information. *
*================================================================*
8000-DLI-ERROR-HANDLER.
DISPLAY '*** DL/I ERROR DIAGNOSTIC ***'
DISPLAY ' DBD Name: ' LS-DBD-NAME
DISPLAY ' Segment Level: ' LS-SEG-LEVEL
DISPLAY ' Status Code: ' LS-STATUS-CODE
DISPLAY ' Segment Name: ' LS-SEG-NAME
DISPLAY ' Key Feedback: ' LS-KEY-FEEDBACK
DISPLAY '*** END DIAGNOSTIC ***'
.
*================================================================*
* 9000-WRAP-UP: Final processing. *
*================================================================*
9000-WRAP-UP.
IF PROCESSING-ERROR
DISPLAY ' '
DISPLAY '*** INQUIRY COMPLETED WITH ERRORS ***'
DISPLAY ' ' WS-ERROR-MSG
ELSE
DISPLAY ' '
DISPLAY '*** INQUIRY COMPLETED SUCCESSFULLY ***'
END-IF
.
Solution Walkthrough
Step 1: Understanding the DL/I Call Structure
Every DL/I call in COBOL follows the same pattern:
CALL 'CBLTDLI' USING function-code
pcb-mask
io-area
ssa-1
[ssa-2 ...]
The four components are:
- Function code: A 4-byte field specifying the operation (GU, GN, GNP, ISRT, REPL, DLET).
- PCB mask: The Program Communication Block defined in the LINKAGE SECTION, through which IMS returns status information.
- I/O area: A WORKING-STORAGE record where IMS places the retrieved segment data (on Get calls) or from which IMS reads the data to store (on Insert/Replace calls).
- SSA (Segment Search Argument): Specifies which segment type to operate on, and optionally a qualification (key value match).
Step 2: The GU Call for Direct Access
The program begins by issuing a GU (Get Unique) call to position directly on the target customer:
CALL 'CBLTDLI' USING WS-DLI-GU
LS-PCB-MASK
WS-CUSTOMER-SEG
WS-CUST-QUAL-SSA
The qualified SSA CUSTOMER(CUST_ID =0000012345) tells IMS to search the database for the customer segment whose CUST_ID field matches the specified value. This is a direct, random access operation -- IMS uses its internal index to locate the segment without scanning sequentially.
After the call, the program checks LS-STATUS-CODE:
- Spaces (blank): The segment was found and placed in WS-CUSTOMER-SEG.
- GE: No segment matching the qualification was found.
- Any other value: An unexpected error occurred and must be logged.
Step 3: GNP Calls for Dependent Segments
After establishing position on the customer segment, the program uses GNP (Get Next within Parent) to retrieve dependent segments. The critical distinction between GN and GNP is:
- GN (Get Next): Moves forward through the entire database. If you reach the last child of a parent, GN will move to the next root segment -- crossing parent boundaries.
- GNP (Get Next within Parent): Moves forward only within the children of the established parent. When there are no more children, IMS returns status code GE instead of crossing to another parent.
For the account retrieval, the parent is the customer established by the GU call:
CALL 'CBLTDLI' USING WS-DLI-GNP
LS-PCB-MASK
WS-ACCOUNT-SEG
WS-ACCT-UNQUAL-SSA
The unqualified SSA ACCOUNT (padded with spaces to 9 bytes) tells IMS to retrieve the next ACCOUNT segment under the current parent, regardless of its key value. Each successive GNP call retrieves the next account until GE is returned.
For transactions, the parent context shifts to the current account. IMS maintains a position at each level of the hierarchy. When a GNP retrieves an ACCOUNT segment, that account becomes the established parent for TRANSACT segments. Subsequent GNP calls with the TRANSACT SSA retrieve only transactions belonging to that specific account.
Step 4: Status Code Handling
Raymond implemented an EVALUATE structure for status code checking, which is the recommended pattern in production IMS programs:
EVALUATE LS-STATUS-CODE
WHEN WS-GOOD-STATUS
CONTINUE
WHEN 'GE'
MOVE 'N' TO WS-MORE-ACCOUNTS
WHEN OTHER
PERFORM 8000-DLI-ERROR-HANDLER
END-EVALUATE
The WHEN OTHER clause is essential. Status codes such as AI (segment I/O area problem), AK (invalid SSA), or AD (function code error) indicate programming errors and must be caught immediately. In production, the error handler would write to a log dataset, issue a WTO (Write to Operator) message, and potentially call the IMS ROLB (Rollback) function to undo any partial updates.
Step 5: The PCB Mask as Diagnostic Tool
The PCB mask is not merely a parameter to DL/I calls -- it is a rich diagnostic resource. After every call, IMS updates the PCB mask with:
- LS-DBD-NAME: Confirms which database was accessed.
- LS-SEG-LEVEL: The hierarchical level of the last segment accessed (01 for root, 02 for first child level, etc.).
- LS-STATUS-CODE: The result of the operation.
- LS-SEG-NAME: The name of the last segment type accessed.
- LS-KEY-FEEDBACK: The concatenated key of the current position in the database. For the CUSTDB hierarchy, this would contain the customer ID followed by the account number followed by the transaction ID, showing exactly where IMS is positioned.
Raymond's error handler displays all of these fields, giving support staff the information they need to diagnose problems without requiring a dump analysis.
Key Design Decisions
Why GNP Instead of Qualified GN
Raymond chose unqualified GNP calls for accounts and transactions rather than qualified GN calls. The alternative would have been to retrieve all account numbers first, then issue qualified GU calls for each. The GNP approach is superior because:
- Fewer calls: GNP sequentially retrieves each child with one call per segment. The GU approach would require an extra retrieval step to get the account list.
- Natural hierarchy: GNP follows the IMS hierarchy naturally, making the code self-documenting.
- Performance: Sequential access within a parent is the fastest path in IMS. Each GNP typically requires zero or one physical I/O because dependent segments are stored physically near their parent.
Why a Transaction Limit
The program limits transaction display to ten per account (WS-MAX-TXN-PER-ACCT). Some accounts have thousands of historical transactions. Retrieving all of them for a screen inquiry would be wasteful and slow. The limit is a configurable field that could be driven by user preference or screen capacity.
Why GOBACK Instead of STOP RUN
In an IMS environment, the program must return control to IMS rather than terminating the region. GOBACK returns control to the calling program or to IMS. STOP RUN would abnormally terminate the IMS region, which is a serious operational problem. Raymond emphasized this distinction in his team's coding standards.
Common Pitfalls in IMS COBOL Programming
-
Forgetting to check status codes: Every DL/I call must be followed by a status code check. A missing check can cause the program to process garbage data from a failed retrieval.
-
Confusing GN with GNP: Using GN when GNP is intended causes the program to cross parent boundaries, retrieving segments belonging to other customers.
-
SSA formatting errors: SSAs must be exactly 9 bytes for the segment name (padded with spaces), and qualified SSAs must follow precise formatting rules. A misplaced parenthesis or incorrect field name produces status code AK.
-
I/O area size mismatches: The COBOL I/O area must be at least as large as the largest segment that will be retrieved into it. An undersized I/O area causes storage overlays.
-
Using STOP RUN in IMS programs: As noted above, STOP RUN terminates the IMS region. Always use GOBACK.
Discussion Questions
-
The GU call with a qualified SSA provides direct access to a specific customer. What happens to database positioning if the GU call returns status code GE (not found)? Can the program issue GNP calls after a failed GU? Why or why not?
-
In the current design, the program retrieves all accounts sequentially using GNP. How would you modify the program to retrieve only active accounts (those with WS-ACCT-STATUS = 'ACTIVE')? What type of SSA would you use, and what would it look like?
-
The PCB mask uses PROCOPT=G (read only). If the program needed to update a customer's phone number during the inquiry, what changes would be needed to the PSB, the PCB mask, and the COBOL code?
-
Compare the IMS hierarchical model used in this case study with a relational database approach. What are the advantages of the hierarchical model for this specific use case (customer-account-transaction)? What are the disadvantages?
-
The error handler displays diagnostic information to the console. In a production CICS environment, console output is not appropriate. How would you redesign the error handling for a production transaction processing environment? Consider logging, operator notification, and user-facing error messages.
-
If the bank added a new segment type, BENEFICIARY, as a child of ACCOUNT (sibling to TRANSACTION), what changes would be required in the PSB, the PCB mask, the SSAs, and the program logic? Would existing GNP calls for transactions still work correctly without modification?