MainframeCICSProjects

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

TT
TopicTrick Team
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

text
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 end

Step 1: Create the DB2 Table

Before writing any CICS code, create the DB2 table that holds customer data.

sql
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.

text
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
         END

Assemble 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)

cobol
       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:

jcl
//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=SHR

Then bind the DBRM to create the DB2 package:

jcl
//BIND     EXEC PGM=IKJEFT01
//SYSTSPRT DD SYSOUT=*
//SYSTSIN  DD *
  DSN SYSTEM(DB2P)
  BIND PACKAGE(CUSTPKG) -
       MEMBER(CUSTINQ) -
       LIBRARY('YOUR.DBRMLIB') -
       ISOLATION(CS) -
       VALIDATE(BIND)
  END

Step 5: Define CICS Resources in the CSD

Use CEDA to define the program, mapset, and transaction:

text
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:

SymptomLikely cause
ABEND AICACOMMAREA length mismatch — check LENGTH parameter on RETURN
ABEND ASRAProgram check — verify host variable sizes match DCLGEN
SQLCODE -805Package not found — re-run BIND step
Blank screenBMS map not assembled — check load library
MAPFAILMap 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.

→ View the full CICS Mastery Course