IMS COBOL Programming: Your First DL/I Program

TT
TopicTrick

Writing your first IMS DL/I program in COBOL follows a specific structure that differs from standard batch COBOL. The program must define PCB masks in the LINKAGE SECTION, receive the PCBs through the PROCEDURE DIVISION entry, and issue every database call through CALL 'CBLTDLI'. This guide builds a complete, working IMS COBOL program from scratch.

The IMS COBOL Program Structure

An IMS DL/I COBOL program has these required elements:

  1. Standard DATA DIVISION (WORKING-STORAGE, LINKAGE SECTION)
  2. PCB mask definitions in LINKAGE SECTION
  3. PROCEDURE DIVISION USING with all PCB masks
  4. Database calls via CALL 'CBLTDLI'
  5. Status code checking after every call

Complete Working Example

The following program reads all CUSTOMER segments sequentially, and for each customer, reads all their ACCOUNT segments:

cobol
      *===================================================
      * IMSPROG1 - IMS DL/I Sequential Read Program
      * Reads all customers and their accounts
      *===================================================
       IDENTIFICATION DIVISION.
       PROGRAM-ID. IMSPROG1.

       ENVIRONMENT DIVISION.

       DATA DIVISION.

       WORKING-STORAGE SECTION.
      *---------------------------------------------------
      * DL/I Function Codes
      *---------------------------------------------------
       01 DLI-FUNCTIONS.
          05 GU-FUNC   PIC X(4) VALUE 'GU  '.
          05 GN-FUNC   PIC X(4) VALUE 'GN  '.
          05 GNP-FUNC  PIC X(4) VALUE 'GNP '.
          05 GHU-FUNC  PIC X(4) VALUE 'GHU '.
          05 ISRT-FUNC PIC X(4) VALUE 'ISRT'.
          05 DLET-FUNC PIC X(4) VALUE 'DLET'.
          05 REPL-FUNC PIC X(4) VALUE 'REPL'.

      *---------------------------------------------------
      * Segment Search Arguments
      *---------------------------------------------------
       01 CUSTOMER-UNQUAL-SSA  PIC X(9) VALUE 'CUSTOMER '.
       01 ACCOUNT-UNQUAL-SSA   PIC X(9) VALUE 'ACCOUNT  '.

      *---------------------------------------------------
      * I/O Areas (must match DBD segment sizes)
      *---------------------------------------------------
       01 CUSTOMER-IO-AREA.
          05 CUST-KEY     PIC X(10).
          05 CUST-NAME    PIC X(40).
          05 CUST-ADDRESS PIC X(80).
          05 CUST-PHONE   PIC X(15).
          05 CUST-STATUS  PIC X(02).
          05 FILLER       PIC X(53).

       01 ACCOUNT-IO-AREA.
          05 ACCT-KEY     PIC X(15).
          05 ACCT-TYPE    PIC X(03).
          05 ACCT-BALANCE PIC S9(13)V9(2) COMP-3.
          05 ACCT-OPENED  PIC X(08).
          05 FILLER       PIC X(22).

      *---------------------------------------------------
      * Program Control Flags
      *---------------------------------------------------
       01 WS-FLAGS.
          05 NO-MORE-CUSTOMERS PIC X VALUE 'N'.
          05 NO-MORE-ACCOUNTS  PIC X VALUE 'N'.

      *---------------------------------------------------
      * Counters
      *---------------------------------------------------
       01 WS-COUNTERS.
          05 CUST-COUNT   PIC 9(7) VALUE ZERO.
          05 ACCT-COUNT   PIC 9(7) VALUE ZERO.

      *===================================================
      * PCB Masks in LINKAGE SECTION
      *===================================================
       LINKAGE SECTION.
       01 CUSTOMER-PCB.
          05 PCB-DBD-NAME    PIC X(8).
          05 PCB-SEG-LEVEL   PIC XX.
          05 PCB-STATUS-CODE PIC XX.
          05 PCB-PROC-OPT    PIC X(4).
          05 FILLER          PIC S9(5) COMP.
          05 PCB-SEG-NAME    PIC X(8).
          05 PCB-KEY-LEN     PIC S9(5) COMP.
          05 PCB-NSEN-SEGS   PIC S9(5) COMP.
          05 PCB-KEY-FBCK    PIC X(25).

      *===================================================
      * PROCEDURE DIVISION — must list all PCBs
      *===================================================
       PROCEDURE DIVISION USING CUSTOMER-PCB.

       0000-MAIN.
           PERFORM 1000-READ-ALL-CUSTOMERS
           STOP RUN.

       1000-READ-ALL-CUSTOMERS.
           MOVE 'N' TO NO-MORE-CUSTOMERS.
           PERFORM 1100-GET-NEXT-CUSTOMER
               UNTIL NO-MORE-CUSTOMERS = 'Y'.
           DISPLAY 'CUSTOMERS PROCESSED: ' CUST-COUNT.
           DISPLAY 'ACCOUNTS  PROCESSED: ' ACCT-COUNT.

       1100-GET-NEXT-CUSTOMER.
           CALL 'CBLTDLI' USING GN-FUNC
                                CUSTOMER-PCB
                                CUSTOMER-IO-AREA
                                CUSTOMER-UNQUAL-SSA.
           EVALUATE PCB-STATUS-CODE
               WHEN '  '
                   ADD 1 TO CUST-COUNT
                   PERFORM 2000-READ-ACCOUNTS
               WHEN 'GB'
                   MOVE 'Y' TO NO-MORE-CUSTOMERS
               WHEN OTHER
                   PERFORM 9000-IMS-ERROR
           END-EVALUATE.

       2000-READ-ACCOUNTS.
           MOVE 'N' TO NO-MORE-ACCOUNTS.
           PERFORM 2100-GET-NEXT-ACCOUNT
               UNTIL NO-MORE-ACCOUNTS = 'Y'.

       2100-GET-NEXT-ACCOUNT.
           CALL 'CBLTDLI' USING GNP-FUNC
                                CUSTOMER-PCB
                                ACCOUNT-IO-AREA
                                ACCOUNT-UNQUAL-SSA.
           EVALUATE PCB-STATUS-CODE
               WHEN '  '
                   ADD 1 TO ACCT-COUNT
                   PERFORM 2200-PROCESS-ACCOUNT
               WHEN 'GE'
                   MOVE 'Y' TO NO-MORE-ACCOUNTS
               WHEN OTHER
                   PERFORM 9000-IMS-ERROR
           END-EVALUATE.

       2200-PROCESS-ACCOUNT.
           DISPLAY 'CUST: ' CUST-KEY
                   ' ACCT: ' ACCT-KEY
                   ' TYPE: ' ACCT-TYPE.

       9000-IMS-ERROR.
           DISPLAY 'IMS ERROR. STATUS: ' PCB-STATUS-CODE.
           DISPLAY 'SEGMENT:   ' PCB-SEG-NAME.
           DISPLAY 'KEY:       ' PCB-KEY-FBCK.
           MOVE 'Y' TO NO-MORE-CUSTOMERS.
           MOVE 'Y' TO NO-MORE-ACCOUNTS.

Compiling an IMS COBOL Program

IMS programs are compiled with the standard COBOL compiler but require special link-edit steps:

jcl
//COMPILE EXEC IGYWCL,PARM.COBOL='...',
//             PARM.LKED='LIST,RENT,REUS'
//COBOL.SYSIN  DD DSN=YOUR.SOURCE(IMSPROG1),DISP=SHR
//LKED.SYSIN   DD *
  INCLUDE SYSLIB(DFSLI000)    <- IMS language interface
  ENTRY DLITCBL               <- IMS entry point
  NAME IMSPROG1(R)
/*
//LKED.SYSLIB  DD DSN=IMS.SDFSRESL,DISP=SHR

The key step is including DFSLI000 (the IMS COBOL language interface module) and specifying ENTRY DLITCBL so IMS can invoke the program correctly.

Running the Program

The program needs JCL that defines the IMS environment:

jcl
//IMSBATCH EXEC PGM=DFSRRC00,
//   PARM='DLI,IMSPROG1,CUSTPGM,1024,...'
//DFSRESLB DD DSN=IMS.SDFSRESL,DISP=SHR
//IMS      DD DSN=IMS.PSBLIB,DISP=SHR
//         DD DSN=IMS.DBDLIB,DISP=SHR
//CUSTDB01 DD DSN=IMS.DATABASE.CUSTDB,DISP=SHR
//SYSOUT   DD SYSOUT=*

DFSRRC00 is the IMS batch region controller. CUSTPGM is the PSB name for this program.

Frequently Asked Questions

Q: Why is the PROCEDURE DIVISION USING different from regular COBOL? In standard COBOL, PROCEDURE DIVISION USING receives parameters from a calling program. In IMS, it receives the PCB masks passed by the IMS runtime. This is how your program accesses the PCB status codes and feedback after each DL/I call. Every IMS program has this structure — it is not optional.

Q: What is the difference between CBLTDLI and PLITDLI? CBLTDLI is the IMS language interface module for COBOL programs. PLITDLI is the equivalent for PL/I programs. Assembler programs use ASMTDLI. The function, PCB, I/O area, and SSA structure is the same regardless of the interface name.

Q: Do I need special COBOL compile options for IMS programs? Yes. IMS programs typically require RENT (reentrant) because MPP programs run in a reentrant region. Some sites also require RMODE and AMODE specifications. Your installation's standards document will specify the required compile and link-edit options.


Part of the IMS Mastery Course — Module 13 of 22.