CICS Project Tutorial: Build a Pseudo-Conversational Inquiry Screen with DB2

CICS Project Tutorial: Build a Pseudo-Conversational Inquiry Screen with DB2
The best way to consolidate CICS knowledge is to build something that exercises all the moving parts together: BMS maps, COMMAREA, EXEC CICS commands, DB2 SQL, and the pseudo-conversational pattern. This tutorial walks through a complete, working customer inquiry application from design to execution.
By the end, you will have a two-screen CICS transaction that accepts a customer ID, queries a DB2 table, and displays the customer record — using the same patterns found in production mainframe applications.
Application Design
What We Are Building
CUSTINQ — a customer inquiry transaction with two screens:
- Screen 1 (CUSTMAP1): Input screen. User enters a customer ID and presses Enter.
- Screen 2 (CUSTMAP2): Detail screen. Displays customer name, address, account type, and balance retrieved from DB2. User presses PF3 to return to Screen 1 or PF12 to exit.
Pseudo-Conversational Flow
User presses Enter on Screen 1
→ CICS starts CUSTINQ task
→ Program reads COMMAREA (first entry: no COMMAREA)
→ Program sends Screen 1 (CUSTMAP1)
→ Program issues RETURN TRANSID(CINQ) COMMAREA(WS-COMMAREA)
→ CICS terminates task, frees storage
User enters customer ID, presses Enter
→ CICS starts CUSTINQ task again
→ Program reads COMMAREA (contains screen indicator)
→ Program issues RECEIVE MAP for CUSTMAP1
→ Program executes DB2 SELECT for customer ID
→ Program sends Screen 2 (CUSTMAP2) with results
→ Program issues RETURN TRANSID(CINQ) COMMAREA(WS-COMMAREA)
User presses PF3 on Screen 2
→ CICS starts CUSTINQ task again
→ Program reads COMMAREA, detects PF3 via EIB
→ Program clears Screen 2, sends Screen 1 again
→ Continues loop
User presses PF12
→ Program issues EXEC CICS RETURN (no TRANSID) to endStep 1: Create the DB2 Table
Before writing any CICS code, create the DB2 table that holds customer data.
CREATE TABLE CUSTLIB.CUSTOMER (
CUST_ID CHAR(8) NOT NULL,
CUST_NAME VARCHAR(50) NOT NULL,
ADDRESS VARCHAR(100),
ACCT_TYPE CHAR(10),
BALANCE DECIMAL(12,2),
CONSTRAINT PK_CUST PRIMARY KEY (CUST_ID)
);
INSERT INTO CUSTLIB.CUSTOMER VALUES
('C0000001', 'Alice Johnson', '123 Main St, Chicago', 'SAVINGS', 15420.50),
('C0000002', 'Robert Chen', '456 Oak Ave, New York', 'CURRENT', 87234.00),
('C0000003', 'Maria Garcia', '789 Elm Rd, Houston', 'SAVINGS', 3210.75);Run RUNSTATS after the inserts to ensure the optimizer has current statistics.
Step 2: Define the BMS Mapset
The BMS mapset defines both screens. Assemble this JCL to create the load module.
CUSTMAPS DFHMSD TYPE=&SYSPARM, X
LANG=COBOL, X
MODE=INOUT, X
TERM=3270-2, X
CTRL=FREEKB, X
STORAGE=AUTO, X
TIOAPFX=YES
* ── SCREEN 1: CUSTOMER SEARCH ──────────────────────────────────────
CUSTMAP1 DFHMDI SIZE=(24,80),LINE=1,COLUMN=1
DFHMDF POS=(1,25),LENGTH=25,ATTRB=(NORM,PROT), X
INITIAL='CUSTOMER INQUIRY SYSTEM'
DFHMDF POS=(3,2),LENGTH=15,ATTRB=(NORM,PROT), X
INITIAL='Customer ID:'
CUSTID DFHMDF POS=(3,18),LENGTH=8,ATTRB=(NORM,UNPROT,IC), X
COLOR=GREEN
DFHMDF POS=(3,27),LENGTH=1,ATTRB=(NORM,PROT,ASKIP)
MSGO1 DFHMDF POS=(22,2),LENGTH=78,ATTRB=(NORM,PROT), X
COLOR=RED
DFHMDF POS=(24,2),LENGTH=42,ATTRB=(NORM,PROT), X
INITIAL='PF12=Exit'
* ── SCREEN 2: CUSTOMER DETAIL ──────────────────────────────────────
CUSTMAP2 DFHMDI SIZE=(24,80),LINE=1,COLUMN=1
DFHMDF POS=(1,25),LENGTH=25,ATTRB=(NORM,PROT), X
INITIAL='CUSTOMER DETAIL'
DFHMDF POS=(3,2),LENGTH=10,ATTRB=(NORM,PROT),INITIAL='ID:'
DSPID DFHMDF POS=(3,13),LENGTH=8,ATTRB=(NORM,PROT),COLOR=TURQUOISE
DFHMDF POS=(5,2),LENGTH=10,ATTRB=(NORM,PROT),INITIAL='Name:'
DSPNAME DFHMDF POS=(5,13),LENGTH=50,ATTRB=(NORM,PROT),COLOR=TURQUOISE
DFHMDF POS=(7,2),LENGTH=10,ATTRB=(NORM,PROT),INITIAL='Address:'
DSPADDR DFHMDF POS=(7,13),LENGTH=78,ATTRB=(NORM,PROT),COLOR=TURQUOISE
DFHMDF POS=(9,2),LENGTH=13,ATTRB=(NORM,PROT), X
INITIAL='Account Type:'
DSPACCT DFHMDF POS=(9,16),LENGTH=10,ATTRB=(NORM,PROT),COLOR=TURQUOISE
DFHMDF POS=(11,2),LENGTH=9,ATTRB=(NORM,PROT),INITIAL='Balance:'
DSPBAL DFHMDF POS=(11,12),LENGTH=15,ATTRB=(NORM,PROT),COLOR=TURQUOISE
MSGO2 DFHMDF POS=(22,2),LENGTH=78,ATTRB=(NORM,PROT),COLOR=RED
DFHMDF POS=(24,2),LENGTH=42,ATTRB=(NORM,PROT), X
INITIAL='PF3=Search Again PF12=Exit'
DFHMSD TYPE=FINAL
ENDAssemble the mapset using JCL that invokes the IBM assembler with DFHMAPS and stores the output in your CICS load library.
Step 3: The COBOL Program (CUSTINQ)
IDENTIFICATION DIVISION.
PROGRAM-ID. CUSTINQ.
*----------------------------------------------------------------*
* CICS Customer Inquiry - Pseudo-Conversational *
*----------------------------------------------------------------*
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
* COMMAREA layout
01 WS-COMMAREA.
05 WS-SCREEN-IND PIC X(1).
88 WS-SCREEN-1 VALUE '1'.
88 WS-SCREEN-2 VALUE '2'.
05 WS-SAVED-CUSTID PIC X(8).
* Copy the BMS map symbolic descriptions
COPY CUSTMAPS.
* DB2 host variables
01 HV-CUST-ID PIC X(8).
01 HV-CUST-NAME PIC X(50).
01 HV-ADDRESS PIC X(100).
01 HV-ACCT-TYPE PIC X(10).
01 HV-BALANCE PIC S9(10)V99 COMP-3.
* Formatted balance for display
01 WS-BALANCE-FMT PIC ZZZ,ZZZ,ZZ9.99.
LINKAGE SECTION.
01 DFHCOMMAREA PIC X(9).
PROCEDURE DIVISION.
MAIN-LOGIC.
EVALUATE TRUE
WHEN EIBCALEN = ZERO
PERFORM INIT-SCREEN-1
WHEN WS-SCREEN-1
PERFORM PROCESS-SCREEN-1
WHEN WS-SCREEN-2
PERFORM PROCESS-SCREEN-2
WHEN OTHER
PERFORM INIT-SCREEN-1
END-EVALUATE
STOP RUN.
*----------------------------------------------------------------*
INIT-SCREEN-1.
* First entry: send blank search screen
MOVE LOW-VALUES TO CUSTMAP1O
MOVE '1' TO WS-SCREEN-IND
MOVE SPACES TO WS-SAVED-CUSTID
EXEC CICS SEND
MAP('CUSTMAP1')
MAPSET('CUSTMAPS')
MAPONLY
ERASE
END-EXEC
EXEC CICS RETURN
TRANSID('CINQ')
COMMAREA(WS-COMMAREA)
LENGTH(9)
END-EXEC.
*----------------------------------------------------------------*
PROCESS-SCREEN-1.
* Receive input from search screen
MOVE DFHCOMMAREA TO WS-COMMAREA
IF EIBAID = DFHPF12
EXEC CICS RETURN END-EXEC
END-IF
EXEC CICS RECEIVE
MAP('CUSTMAP1')
MAPSET('CUSTMAPS')
RESP(WS-RESP)
END-EXEC
IF CUSTIDI = SPACES OR LOW-VALUES
MOVE 'Please enter a Customer ID'
TO MSGO1O
EXEC CICS SEND
MAP('CUSTMAP1')
MAPSET('CUSTMAPS')
DATAONLY
CURSOR
END-EXEC
EXEC CICS RETURN
TRANSID('CINQ')
COMMAREA(WS-COMMAREA)
LENGTH(9)
END-EXEC
END-IF
MOVE CUSTIDI TO WS-SAVED-CUSTID
PERFORM FETCH-CUSTOMER
.
*----------------------------------------------------------------*
FETCH-CUSTOMER.
MOVE WS-SAVED-CUSTID TO HV-CUST-ID
EXEC SQL
SELECT CUST_NAME, ADDRESS, ACCT_TYPE, BALANCE
INTO :HV-CUST-NAME, :HV-ADDRESS,
:HV-ACCT-TYPE, :HV-BALANCE
FROM CUSTLIB.CUSTOMER
WHERE CUST_ID = :HV-CUST-ID
END-EXEC
EVALUATE SQLCODE
WHEN 0
PERFORM DISPLAY-CUSTOMER
WHEN +100
MOVE 'Customer not found'
TO MSGO1O
MOVE '1' TO WS-SCREEN-IND
EXEC CICS SEND
MAP('CUSTMAP1')
MAPSET('CUSTMAPS')
DATAONLY
END-EXEC
EXEC CICS RETURN
TRANSID('CINQ')
COMMAREA(WS-COMMAREA)
LENGTH(9)
END-EXEC
WHEN OTHER
MOVE 'DB2 error - contact support'
TO MSGO1O
EXEC CICS SEND
MAP('CUSTMAP1')
MAPSET('CUSTMAPS')
DATAONLY
END-EXEC
EXEC CICS RETURN
TRANSID('CINQ')
COMMAREA(WS-COMMAREA)
LENGTH(9)
END-EXEC
END-EVALUATE.
*----------------------------------------------------------------*
DISPLAY-CUSTOMER.
MOVE LOW-VALUES TO CUSTMAP2O
MOVE WS-SAVED-CUSTID TO DSPIDO
MOVE HV-CUST-NAME TO DSPNAMEO
MOVE HV-ADDRESS TO DSPADDRO
MOVE HV-ACCT-TYPE TO DSPACCTO
MOVE HV-BALANCE TO WS-BALANCE-FMT
MOVE WS-BALANCE-FMT TO DSPBALO
MOVE '2' TO WS-SCREEN-IND
EXEC CICS SEND
MAP('CUSTMAP2')
MAPSET('CUSTMAPS')
ERASE
END-EXEC
EXEC CICS RETURN
TRANSID('CINQ')
COMMAREA(WS-COMMAREA)
LENGTH(9)
END-EXEC.
*----------------------------------------------------------------*
PROCESS-SCREEN-2.
MOVE DFHCOMMAREA TO WS-COMMAREA
IF EIBAID = DFHPF12
EXEC CICS RETURN END-EXEC
END-IF
IF EIBAID = DFHPF3
PERFORM INIT-SCREEN-1
ELSE
EXEC CICS RETURN
TRANSID('CINQ')
COMMAREA(WS-COMMAREA)
LENGTH(9)
END-EXEC
END-IF.Step 4: DB2 Precompile and Bind
Before compiling, precompile the COBOL program to extract the embedded SQL and generate the DBRM:
//PRECOMP EXEC PGM=DSNHPC,PARM='HOST(COBOL)'
//DBRMLIB DD DSN=YOUR.DBRMLIB(CUSTINQ),DISP=SHR
//SYSCIN DD DSN=&&MODIFIED,DISP=(NEW,PASS)
//SYSIN DD DSN=YOUR.SOURCE(CUSTINQ),DISP=SHRThen bind the DBRM to create the DB2 package:
//BIND EXEC PGM=IKJEFT01
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DB2P)
BIND PACKAGE(CUSTPKG) -
MEMBER(CUSTINQ) -
LIBRARY('YOUR.DBRMLIB') -
ISOLATION(CS) -
VALIDATE(BIND)
ENDStep 5: Define CICS Resources in the CSD
Use CEDA to define the program, mapset, and transaction:
CEDA DEF PROGRAM(CUSTINQ)
GROUP(CUSTGRP)
LANGUAGE(COBOL)
DESCRIPTION(Customer Inquiry Program)
CEDA DEF MAPSET(CUSTMAPS)
GROUP(CUSTGRP)
DESCRIPTION(Customer Inquiry Maps)
CEDA DEF TRANSACTION(CINQ)
GROUP(CUSTGRP)
PROGRAM(CUSTINQ)
DESCRIPTION(Customer Inquiry Transaction)
TWASIZE(0)
CEDA INSTALL GROUP(CUSTGRP)Step 6: Run and Test
Type CINQ at the CICS terminal and press Enter. Screen 1 should appear with the customer ID input field. Enter C0000001 and press Enter — Screen 2 should display Alice Johnson's details. Press PF3 to return to Screen 1, or PF12 to exit.
Common issues:
| Symptom | Likely cause |
|---|---|
| ABEND AICA | COMMAREA length mismatch — check LENGTH parameter on RETURN |
| ABEND ASRA | Program check — verify host variable sizes match DCLGEN |
| SQLCODE -805 | Package not found — re-run BIND step |
| Blank screen | BMS map not assembled — check load library |
| MAPFAIL | Map received before it was sent — check pseudo-conversational flow logic |
What You Practised
This project exercised every core CICS skill:
- BMS mapset definition — two-screen mapset with input and output fields, field attributes, and PF key labelling
- Pseudo-conversational design — RETURN with TRANSID and COMMAREA, EIB interrogation on re-entry
- COMMAREA state transfer — saving screen indicator and customer ID across task boundaries
- DB2 embedded SQL — SELECT with host variables inside a CICS program, SQLCODE handling
- Error handling — not-found condition (SQLCODE +100) and unexpected DB2 errors, both routed back to the input screen with meaningful messages
- CSD resource definitions — PROGRAM, MAPSET, TRANSACTION definitions and INSTALL
Ready to Master CICS?
This project is part of the CICS Mastery Course — 22 modules covering every CICS concept from fundamentals to DB2 integration and REST API modernisation. Free, fresher to senior.
