CICS inquiry operations are read-only file access operations used to retrieve data from files without modifying it. These operations are fundamental to CICS applications, enabling programs to query and display information to users. Inquiry operations include two main approaches: random access using the READ command and sequential browsing using browse commands (STARTBR, READNEXT, READPREV, ENDBR).
Understanding when and how to use each type of inquiry operation is crucial for building efficient CICS applications. Random access is ideal for looking up specific records, while sequential browsing is perfect for processing multiple records in order, generating reports, or displaying lists.
CICS provides two primary methods for inquiry operations:
| Method | Primary Command | Best Use Case | Access Pattern |
|---|---|---|---|
| Random Access | READ | Retrieving a specific record by key | Direct access to known record |
| Sequential Browsing | STARTBR, READNEXT, READPREV, ENDBR | Processing multiple records in sequence | Sequential access through file |
The READ command retrieves a specific record from a file based on a unique key. This is the most efficient method when you know exactly which record you need.
12345678910EXEC CICS READ FILE('file-name') INTO(data-area) LENGTH(data-length) RIDFLD(key-field) [KEYLENGTH(key-length)] [GENERIC] [RESP(response-code)] [RESP2(response-code-2)] END-EXEC.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152WORKING-STORAGE SECTION. 01 WS-CUSTOMER-RECORD. 05 WS-CUSTOMER-ID PIC X(8). 05 WS-CUSTOMER-NAME PIC X(40). 05 WS-CUSTOMER-BALANCE PIC S9(9)V99 COMP-3. 05 WS-CUSTOMER-STATUS PIC X(1). 01 WS-RESPONSE PIC S9(8) COMP. 01 WS-RESPONSE2 PIC S9(8) COMP. 01 WS-SEARCH-ID PIC X(8). PROCEDURE DIVISION. *> Get customer ID from user input EXEC CICS RECEIVE INTO(WS-SEARCH-ID) LENGTH(8) END-EXEC *> Read customer record by ID MOVE WS-SEARCH-ID TO WS-CUSTOMER-ID EXEC CICS READ FILE('CUSTOMER') INTO(WS-CUSTOMER-RECORD) RIDFLD(WS-CUSTOMER-ID) LENGTH(LENGTH OF WS-CUSTOMER-RECORD) RESP(WS-RESPONSE) RESP2(WS-RESPONSE2) END-EXEC *> Check response and handle result EVALUATE WS-RESPONSE WHEN DFHRESP(NORMAL) *> Customer found - display information EXEC CICS SEND FROM('Customer found: ' WS-CUSTOMER-NAME) END-EXEC EXEC CICS SEND FROM('Balance: ' WS-CUSTOMER-BALANCE) END-EXEC WHEN DFHRESP(NOTFND) *> Customer not found EXEC CICS SEND FROM('Customer ' WS-SEARCH-ID ' not found') END-EXEC WHEN OTHER *> Error occurred EXEC CICS SEND FROM('Error reading customer file') END-EXEC END-EVALUATE EXEC CICS RETURN END-EXEC.
| Response Code | Numeric Value | Meaning |
|---|---|---|
| NORMAL | 0 | Record read successfully |
| NOTFND | 13 | Record not found - the specified key does not exist |
| FILENOTFOUND | 8 | File error - file not found or access denied |
| NOTAUTH | 10 | Not authorized to access the file |
Browse operations allow you to read records sequentially from a file. This is ideal for processing multiple records, generating reports, or displaying lists of data. A browse operation consists of four main commands: STARTBR, READNEXT/READPREV, and ENDBR.
The typical browse operation follows this pattern:
STARTBR (Start Browse) initiates a browse operation and positions to an initial record. It establishes a browse cursor that tracks your current position in the file.
12345678910EXEC CICS STARTBR FILE('file-name') RIDFLD(key-field) [GTEQ | EQUAL] [REQID(request-id)] [KEYLENGTH(key-length)] [GENERIC] [RESP(response-code)] [RESP2(response-code-2)] END-EXEC.
READNEXT retrieves the next record in ascending order (forward), while READPREV retrieves the previous record in descending order (backward). Both commands advance the browse cursor.
123456789101112131415161718192021* Forward browsing EXEC CICS READNEXT FILE('file-name') INTO(data-area) RIDFLD(key-field) LENGTH(data-length) [REQID(request-id)] [RESP(response-code)] [RESP2(response-code-2)] END-EXEC. * Backward browsing EXEC CICS READPREV FILE('file-name') INTO(data-area) RIDFLD(key-field) LENGTH(data-length) [REQID(request-id)] [RESP(response-code)] [RESP2(response-code-2)] END-EXEC.
ENDBR (End Browse) terminates the browse operation and releases resources. Always issue ENDBR after starting a browse, even if an error occurs, to prevent resource leaks.
1234567EXEC CICS ENDBR FILE('file-name') [REQID(request-id)] [NOSUSPEND] [RESP(response-code)] [RESP2(response-code-2)] END-EXEC.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778WORKING-STORAGE SECTION. 01 WS-CUSTOMER-RECORD. 05 WS-CUSTOMER-ID PIC X(8). 05 WS-CUSTOMER-NAME PIC X(40). 05 WS-CUSTOMER-BALANCE PIC S9(9)V99 COMP-3. 01 WS-RESPONSE PIC S9(8) COMP. 01 WS-EOF-FLAG PIC X VALUE 'N'. 88 END-OF-FILE VALUE 'Y'. 88 NOT-END-OF-FILE VALUE 'N'. 01 WS-RECORD-COUNT PIC 9(4) VALUE 0. PROCEDURE DIVISION. *> Start browse from beginning of file MOVE LOW-VALUES TO WS-CUSTOMER-ID EXEC CICS STARTBR FILE('CUSTOMER') RIDFLD(WS-CUSTOMER-ID) GTEQ RESP(WS-RESPONSE) END-EXEC *> Check if browse started successfully IF WS-RESPONSE NOT = DFHRESP(NORMAL) IF WS-RESPONSE = DFHRESP(NOTFND) EXEC CICS SEND FROM('No customers found') END-EXEC ELSE EXEC CICS SEND FROM('Error starting browse') END-EXEC END-IF EXEC CICS RETURN END-EXEC END-IF *> Read and display up to 100 customers PERFORM UNTIL END-OF-FILE OR WS-RECORD-COUNT >= 100 EXEC CICS READNEXT FILE('CUSTOMER') INTO(WS-CUSTOMER-RECORD) RIDFLD(WS-CUSTOMER-ID) LENGTH(LENGTH OF WS-CUSTOMER-RECORD) RESP(WS-RESPONSE) END-EXEC EVALUATE WS-RESPONSE WHEN DFHRESP(NORMAL) *> Record read successfully ADD 1 TO WS-RECORD-COUNT EXEC CICS SEND FROM(WS-CUSTOMER-ID ' - ' WS-CUSTOMER-NAME) END-EXEC WHEN DFHRESP(ENDFILE) *> End of file reached SET END-OF-FILE TO TRUE WHEN OTHER *> Error occurred EXEC CICS SEND FROM('Error reading customer: ' WS-RESPONSE) END-EXEC SET END-OF-FILE TO TRUE END-EVALUATE END-PERFORM *> Always end the browse EXEC CICS ENDBR FILE('CUSTOMER') NOSUSPEND RESP(WS-RESPONSE) END-EXEC *> Display summary EXEC CICS SEND FROM('Total customers displayed: ' WS-RECORD-COUNT) END-EXEC EXEC CICS RETURN END-EXEC.
RESETBR (Reset Browse) repositions a browse operation to a new starting position without ending it. This is useful when you need to jump to a different position within an active browse session.
123456789EXEC CICS RESETBR FILE('file-name') RIDFLD(new-key-field) [GTEQ | EQUAL] [REQID(request-id)] [KEYLENGTH(key-length)] [RESP(response-code)] [RESP2(response-code-2)] END-EXEC.
| Scenario | Use READ | Use Browse |
|---|---|---|
| Looking up a specific customer by ID | Yes - direct access by key | No - inefficient for single record |
| Generating a customer list report | No - would require multiple READs | Yes - efficient sequential processing |
| Displaying search results | No - need to process multiple records | Yes - process results sequentially |
| Validating a single record exists | Yes - check response code | No - overkill for single check |
| Processing all records matching criteria | No - cannot efficiently find matches | Yes - read sequentially and filter |
Always check response codes after every inquiry operation. Handle common conditions like NOTFND (record not found) and ENDFILE (end of file) as normal conditions, not errors.
Every STARTBR must have a corresponding ENDBR, even if an error occurs. Use NOSUSPEND option on ENDBR to avoid transactional issues when errors occur. This prevents resource leaks and ensures proper cleanup.
Use READ for single record lookups and browse operations for sequential processing. Don't use multiple READs when a browse would be more efficient.
Response code 20 (ENDFILE) is a normal condition, not an error. It indicates you've reached the end of the file during sequential processing. Handle it gracefully by ending your read loop.
If you need multiple concurrent browse operations on the same file, use the REQID parameter to distinguish between them. Each browse maintains its own position independently.
Remember that you cannot update records during a browse. To update a record found during browsing, end the browse with ENDBR, use READ with UPDATE option, perform the update, and optionally restart the browse if needed.
1234567891011121314151617* Look up a specific record by key MOVE search-key TO record-key EXEC CICS READ FILE('FILE-NAME') INTO(record-area) RIDFLD(record-key) LENGTH(LENGTH OF record-area) RESP(response-code) END-EXEC IF response-code = DFHRESP(NORMAL) * Process the found record ELSE IF response-code = DFHRESP(NOTFND) * Record not found - handle appropriately ELSE * Error occurred - handle error END-IF.
1234567891011121314151617181920212223242526272829303132333435* Process all records sequentially MOVE LOW-VALUES TO start-key EXEC CICS STARTBR FILE('FILE-NAME') RIDFLD(start-key) GTEQ RESP(response-code) END-EXEC IF response-code = DFHRESP(NORMAL) PERFORM UNTIL end-of-file EXEC CICS READNEXT FILE('FILE-NAME') INTO(record-area) RIDFLD(record-key) LENGTH(LENGTH OF record-area) RESP(response-code) END-EXEC IF response-code = DFHRESP(NORMAL) * Process the record ELSE IF response-code = DFHRESP(ENDFILE) SET end-of-file TO TRUE ELSE * Error - exit loop SET end-of-file TO TRUE END-IF END-PERFORM END-IF * Always end the browse EXEC CICS ENDBR FILE('FILE-NAME') NOSUSPEND END-EXEC.
123456789101112131415161718192021222324252627282930313233343536373839404142* Browse and filter records MOVE search-criteria TO start-key EXEC CICS STARTBR FILE('FILE-NAME') RIDFLD(start-key) GTEQ RESP(response-code) END-EXEC IF response-code = DFHRESP(NORMAL) PERFORM UNTIL end-of-file OR max-results-reached EXEC CICS READNEXT FILE('FILE-NAME') INTO(record-area) RIDFLD(record-key) LENGTH(LENGTH OF record-area) RESP(response-code) END-EXEC IF response-code = DFHRESP(NORMAL) * Check if record matches criteria IF record-matches-criteria * Process matching record ADD 1 TO result-count END-IF * Check if we've exceeded search range IF record-key > end-of-search-range SET end-of-file TO TRUE END-IF ELSE IF response-code = DFHRESP(ENDFILE) SET end-of-file TO TRUE ELSE SET end-of-file TO TRUE END-IF END-PERFORM END-IF EXEC CICS ENDBR FILE('FILE-NAME') NOSUSPEND END-EXEC.
Imagine you have a big book with lots of pages:
READ is like looking up a specific page number. You know exactly which page you want (like page 42), so you flip directly to that page and read it. This is fast when you know what you're looking for!
Browse is like reading the book from start to finish. You open the book (STARTBR), then read page by page going forward (READNEXT) or backward (READPREV), and when you're done, you close the book (ENDBR). This is great when you want to read many pages in order!
Just like you choose whether to jump to a specific page or read through the book, CICS programs choose whether to use READ (jump to a record) or browse (read through records)!
Write a CICS program that reads a customer ID from the terminal and uses READ to retrieve and display the customer's name and balance.
12345678910111213141516171819202122232425262728* Get customer ID from user EXEC CICS RECEIVE INTO(WS-CUSTOMER-ID) LENGTH(8) END-EXEC * Read customer record EXEC CICS READ FILE('CUSTOMER') INTO(WS-CUSTOMER-RECORD) RIDFLD(WS-CUSTOMER-ID) LENGTH(LENGTH OF WS-CUSTOMER-RECORD) RESP(WS-RESPONSE) END-EXEC * Display results IF WS-RESPONSE = DFHRESP(NORMAL) EXEC CICS SEND FROM('Customer: ' WS-CUSTOMER-NAME) END-EXEC EXEC CICS SEND FROM('Balance: ' WS-CUSTOMER-BALANCE) END-EXEC ELSE EXEC CICS SEND FROM('Customer not found') END-EXEC END-IF.
Write a CICS program that uses browse operations to display the first 50 customers in the file.
1234567891011121314151617181920212223242526272829303132333435363738* Start browse from beginning MOVE LOW-VALUES TO WS-CUSTOMER-ID EXEC CICS STARTBR FILE('CUSTOMER') RIDFLD(WS-CUSTOMER-ID) GTEQ RESP(WS-RESPONSE) END-EXEC IF WS-RESPONSE = DFHRESP(NORMAL) * Read up to 50 customers PERFORM UNTIL WS-RECORD-COUNT >= 50 EXEC CICS READNEXT FILE('CUSTOMER') INTO(WS-CUSTOMER-RECORD) RIDFLD(WS-CUSTOMER-ID) LENGTH(LENGTH OF WS-CUSTOMER-RECORD) RESP(WS-RESPONSE) END-EXEC IF WS-RESPONSE = DFHRESP(NORMAL) ADD 1 TO WS-RECORD-COUNT EXEC CICS SEND FROM(WS-CUSTOMER-ID ' - ' WS-CUSTOMER-NAME) END-EXEC ELSE IF WS-RESPONSE = DFHRESP(ENDFILE) EXIT PERFORM ELSE EXIT PERFORM END-IF END-PERFORM END-IF * End browse EXEC CICS ENDBR FILE('CUSTOMER') NOSUSPEND END-EXEC.
1. What is the primary purpose of CICS inquiry operations?
2. Which command is used for random access to a specific record?
3. What is the correct sequence for a browse operation?
4. Can you update a record while a browse operation is active?
5. What response code indicates end of file during a browse?