IMS DL/I Overview

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

This page is written against ISO/IEC 1989:2023 (edition 3, January 2023; an upcoming 4th edition is in ballot), which says nothing about IMS because DL/I is an IBM product interface and not part of the COBOL language; against IBM Enterprise COBOL for z/OS 6.5 (PTFs through September 2026) on z/OS 3.2; and against IBM IMS 15.6, whose Application Programming and Application Programming APIs manuals (the 2026 editions) were read for every call, field and status code shown. GnuCOBOL 3.2 (28 July 2023, the latest release) has no IMS support, so nothing on this page was run: the one complete program is "z/OS; not run here", and its source was only syntax-checked with cobc -fsyntax-only -Wall (and with -std=ibm), which reported no warnings and proves nothing about the DL/I calls themselves.

IMS (Information Management System) is two products that run together: IMS Database Manager (IMS DB), a hierarchical database, and IMS Transaction Manager (IMS TM), a transaction monitor with message queues. A COBOL program talks to IMS DB by calling a language interface module with CALL and testing a status code afterwards, which is a different style from the embedded SQL of Embedded SQL and Db2 or the commands of CICS Online Programming. This page covers the hierarchical model, the control blocks that describe a program’s view of a database, the call interface, the main calls, the status codes, a complete Circulation example, IMS TM in one paragraph, and where readers will meet IMS. The CALL statement itself is on Subprograms, CALL and Linkage, the LINKAGE SECTION and PROCEDURE DIVISION USING that receive the PCBs are there too, and the z/OS environment around a batch step is in Mainframe Environment Primer and JCL for COBOL Programmers.

Where the book is outdated: Taulli’s Modern Mainframe Development (2022, chapter 8) describes IMS DB and TM and DL/I calls with a PCB mask for IMS 15.1, which is one release behind the IMS 15.6 documentation used here; the DL/I call interface itself has not changed, so the ideas carry over. The book is a survey, so the call formats, SSA layout, PCB mask fields and status codes here come from the IBM manuals, and the Circulation database and program are original.

The hierarchical model

An IMS database is a collection of database records, and a record is a tree. The unit of data is the segment, a fixed or variable block of bytes (what a COBOL programmer would call a group item) that has a type name such as MEMBER or LOAN. The rules are few:

  • The top segment of a record is the root; there is exactly one root occurrence per record. Every other segment type is a dependent (a child of the segment above it, and a parent of the segments below it).

  • A parent can have many occurrences of a child type. Occurrences of one type under one parent are twins and are usually kept in the order of a sequence field (the key).

  • A segment has one parent only, so every segment is reached by a hierarchical path from its root. The concatenated key of a segment is the keys of the whole path, root first.

  • The segments of a record are numbered in hierarchic sequence: top to bottom, left to right, parents before their children and each child type in turn.

The Circulation run keeps its members and their loans in such a database. MEMBER is the root (key MEMBID, the same 60 bytes as the MEMBREC copybook of the whole section), LOAN is a child (key BOOKID) and FINE is a second child type. The diagram shows the segment types on the left and, on the right, one database record in hierarchic sequence.

The Circulation IMS database: a MEMBER root segment with LOAN and FINE child segment types, and one database record in hierarchic sequence with each segment numbered in the order that unqualified GN calls return them

Compare this with a relational design, where loans would be rows with a foreign key to the member. In IMS the parent-child path is the access path, which makes a retrieval along that path (a member and all their loans) very fast and very simple to program, and makes any other path (all the loans of one book) something the database designer has to plan for with an index or a logical relationship. This is why IMS databases are designed around the transactions that will use them.

DBD, PSB and PCB

Three kinds of IMS control blocks describe what a program may see, and a COBOL programmer meets all three even if the database administrator writes them.

Control block What it is

DBD (database description)

Defines one physical database: its segment types, the hierarchy, the field names (at least the sequence field) and how it is stored. It is generated by the DBDGEN utility into a library. The segment and field names in an SSA must exist in the DBD.

PSB (program specification block)

Defines one application program’s view: the list of PCBs the program uses. It is generated by PSBGEN.

PCB (program communication block)

One entry in a PSB. A DB PCB names a database and lists the segments (with SENSEG statements) and the kind of processing (PROCOPT) that the program is allowed. IMS keeps the position in the database and the result of the last call in the PCB. An I/O PCB is the program’s connection to its terminal or message queue and to the system services; a batch program gets one only if the PSB says CMPAT=YES.

A program is therefore sensitive only to the segments its PCB lists, and the least capability needed (PROCOPT=G to read, A for get, insert, delete and replace) keeps data available to other programs. A PSB for the Circulation program below, as an excerpt (z/OS; not run here), looks like this:

         PCB   TYPE=DB,DBDNAME=CIRCDB,PROCOPT=A,KEYLEN=12
         SENSEG NAME=MEMBER,PARENT=0
         SENSEG NAME=LOAN,PARENT=MEMBER
         PSBGEN LANG=COBOL,PSBNAME=CIRCPSB,CMPAT=YES

KEYLEN=12 is the length of the longest concatenated key the program can see (the 6-byte MEMBID and the 6-byte BOOKID), and it is the size of the key feedback area in the PCB mask below. The PSB lists MEMBER and LOAN only, so the program is not sensitive to FINE and can neither read nor change fine segments.

The call interface from COBOL

A DL/I request is one CALL to the IMS language interface module. IMS gives COBOL programs three entry points. The first two take the PCB directly; the third takes an AIB (application interface block) that names the PCB:

CALL 'CBLTDLI' USING function db-pcb i-o-area ssa-1 ... ssa-15
CALL 'CEETDLI' USING function db-pcb i-o-area ssa-1 ... ssa-15
CALL 'AIBTDLI' USING function aib i-o-area ssa-1 ... ssa-15
  • function is a 4-byte alphanumeric data item holding the function code ('GU ', 'ISRT', …​). Short codes are padded on the right with blanks.

  • db-pcb is the PCB mask (below) that IMS passed to the program. It selects the database and holds the position and the status code. With AIBTDLI the AIB names the PCB instead.

  • i-o-area is the data item that receives the segment on a get call or supplies it on an insert or replace.

  • The SSAs (up to 15) narrow the request to a path of segments. They are optional on most get calls and required on ISRT.

  • A parmcount item can precede the function code in COBOL, but it is never required there. Examples in the IBM manuals show calls both with and without it.

  • CEETDLI behaves like CBLTDLI but takes part in Language Environment condition handling, which CBLTDLI does not always support under IMS. The IBM manual for Enterprise COBOL also lists EXEC SQLIMS statements as a third way to reach IMS data, through SQL; it is not covered here.

Nothing is returned in a register or in RETURN-CODE: the outcome is the two-character status code in the PCB, and the program must test it after every call. The program does not open or close the database with COBOL statements, and in an IMS message program it does not use the OPEN, READ or WRITE statements for non-IMS files at all.

The PCB mask in the LINKAGE SECTION

IMS keeps the PCBs outside the program. IMS passes their addresses when it starts the program, and the program receives them through PROCEDURE DIVISION USING, one 01 item per PCB in the order that the PSB lists them (I/O PCB first when there is one). Each 01 item is a mask: a description of the PCB’s fields in the same order and length, so that the program can read them and, by passing the mask to CALL, tell IMS which PCB the call is for. The program can look at the fields but must not change them.

Field Bytes Picture Meaning

Database name

8

X(8)

The DBD name.

Segment level number

2

XX

Level of the last segment that satisfied the call (numeric characters, right-justified).

Status code

2

XX

Result of the last call: blanks if completely successful.

Processing options

4

X(4)

The PROCOPT of the PCB.

Reserved for IMS

4

S9(9) COMP

Not used by the program.

Segment name

8

X(8)

Name of the last segment that satisfied the call.

Length of key feedback area

4

S9(9) COMP

Current length of the key in the next field.

Number of sensitive segments

4

S9(9) COMP

How many segment types the PCB makes visible.

Key feedback area

KEYLEN

X(n)

The concatenated key of the last segment retrieved.

The status code is the field a program uses most; the level, segment name and key feedback tell it where it is after an unqualified GN or an unsuccessful call. IMS updates the status code after every call and never clears it between calls, so a program that tests it must test it immediately. When the program is first scheduled the field holds a data-availability code, not a call result. The I/O PCB mask has a different layout (terminal name, 2 reserved bytes, a 2-byte status code, date, time, message sequence number and more) and is used with the message calls described near the end of the page.

Segment search arguments

An SSA tells IMS which segment type, and optionally which occurrence, a call is about. It is data in WORKING-STORAGE with a fixed layout:

  • An unqualified SSA is the 8-byte segment name, padded with blanks, followed by one blank, 9 bytes in all (LOAN and four blanks and then a blank).

  • A qualified SSA is the segment name (8), a left parenthesis, a field name (8, padded), a 2-byte relational operator, the value, and a right parenthesis, with no blanks around the parenthesis. The value must be exactly as long as the field defined in the DBD, with leading zeros for numbers and trailing blanks for text, because IMS compares the bytes.

  • The operators are EQ (or a blank followed by =), GT, LT, GE, LE and NE, and the symbolic forms >=, <=, and so on. Command codes (a * in byte 9, then letters such as D, N or P) change how the call works; they are not covered here.

  • A call can carry one SSA per level, from the root down. Leaving out the SSA of a level means "whatever is current at that level".

The Circulation program defines three SSAs: MEMBER-SSA (qualified on MEMBID, with its key moved in before each call), LOAN-SSA-KEYED (qualified on BOOKID) and LOAN-SSA-ANY (unqualified). Because the value field of a qualified SSA is part of a 01 item, the usual pattern is a group with FILLER entries for the fixed parts and one named field for the value.

The database calls

The calls below are the core of DL/I database processing. Each has a hold form for the calls that change data.

Function Hold form What it does

GU

GHU

Get Unique: retrieves the segment that the SSAs describe, wherever the program is. It is the only call that can move backwards, and it starts the position for sequential processing. With a qualified SSA at each level it is a direct lookup.

GN

GHN

Get Next: returns the next segment in hierarchic sequence from the current position, or the next one that satisfies its SSAs. A loop of unqualified GN reads the whole database, ending with status GB.

GNP

GHNP

Get Next within Parent: like GN but stays under the established parent, the segment the last successful GU or GN found. It returns the dependents one at a time and ends with GE when the parent has no more.

ISRT

none

Inserts the segment built in the I/O area. The last SSA names the segment type being inserted and the earlier SSAs identify its parents; a root needs one unqualified SSA only.

REPL

none

Replaces the segment that the previous get-hold call retrieved with the contents of the I/O area.

DLET

none

Deletes the segment that the previous get-hold call retrieved, and all its dependents.

The rules that matter most in practice are these:

  • REPL and DLET must follow a get-hold call (GHU, GHN or GHNP) on the same PCB; IMS rejects them otherwise. A GU or GN without H does not qualify.

  • IMS rejects a DLET if the preceding call for that PCB was not a get-hold, REPL or DLET call, so the get-hold call must come immediately before. After the get-hold call the program should change the I/O area only as the segment layout allows (do not change field lengths).

  • A DLET deletes the whole subtree, so deleting a MEMBER removes all of the member’s loans and fines, even those the program cannot see.

  • On ISRT the segment goes where its key says (or where the DBD’s insert rule says for segments without a unique key). Inserting a child needs the parent identified, so the call passes the qualified parent SSA followed by the unqualified child SSA.

  • A successful GU or GN sets the parent for later GNP calls and an unsuccessful one cancels it, so a GNP loop starts with a successful get of the parent.

A complete Circulation program

The program below (z/OS; not run here) lists one member’s loans, adds a fine to the member, adds a loan and deletes another. It uses the MEMBREC copybook of the whole section as the I/O area of the MEMBER segment, tests the status code after every call, and uses level 88 names for the codes it expects.

      * LOANIMS - Circulation inquiry and update against the IMS
      * database CIRCDB (z/OS; not run here).
       IDENTIFICATION DIVISION.
       PROGRAM-ID. LOANIMS.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  DLI-FUNCTIONS.
           05  DLI-GU              PIC X(4) VALUE 'GU  '.
           05  DLI-GHU             PIC X(4) VALUE 'GHU '.
           05  DLI-GNP             PIC X(4) VALUE 'GNP '.
           05  DLI-ISRT            PIC X(4) VALUE 'ISRT'.
           05  DLI-REPL            PIC X(4) VALUE 'REPL'.
           05  DLI-DLET            PIC X(4) VALUE 'DLET'.
      * Segment search arguments: 8-byte name, then either a blank
      * (unqualified) or "(", 8-byte field, 2-byte operator, value, ")".
       01  MEMBER-SSA.
           05  FILLER              PIC X(8) VALUE 'MEMBER  '.
           05  FILLER              PIC X    VALUE '('.
           05  FILLER              PIC X(8) VALUE 'MEMBID  '.
           05  FILLER              PIC X(2) VALUE 'EQ'.
           05  MEMBER-SSA-KEY      PIC X(6).
           05  FILLER              PIC X    VALUE ')'.
       01  LOAN-SSA-KEYED.
           05  FILLER              PIC X(8) VALUE 'LOAN    '.
           05  FILLER              PIC X    VALUE '('.
           05  FILLER              PIC X(8) VALUE 'BOOKID  '.
           05  FILLER              PIC X(2) VALUE 'EQ'.
           05  LOAN-SSA-KEY        PIC X(6).
           05  FILLER              PIC X    VALUE ')'.
       01  LOAN-SSA-ANY.
           05  FILLER              PIC X(8) VALUE 'LOAN    '.
           05  FILLER              PIC X    VALUE SPACE.
      * I/O areas: the MEMBER segment is the 60-byte MEMBREC record.
           COPY MEMBREC.
       01  LOAN-SEG.
           05  LS-BOOK-ID          PIC X(6).
           05  LS-LOAN-DATE        PIC X(8).
           05  LS-DUE-DATE         PIC X(8).
       LINKAGE SECTION.
       01  IO-PCB.
           05  FILLER              PIC X(10).
           05  IO-STATUS           PIC XX.
           05  FILLER              PIC X(20).
       01  CIRC-PCB.
           05  CIRC-DBD-NAME       PIC X(8).
           05  CIRC-SEG-LEVEL      PIC XX.
           05  CIRC-STATUS         PIC XX.
               88  CIRC-OK         VALUE SPACES.
               88  CIRC-NOT-FOUND  VALUE 'GE'.
               88  CIRC-END-DB     VALUE 'GB'.
               88  CIRC-DUPLICATE  VALUE 'II'.
           05  CIRC-PROC-OPTIONS   PIC X(4).
           05  FILLER              PIC S9(9) COMP.
           05  CIRC-SEG-NAME       PIC X(8).
           05  CIRC-KEY-LENGTH     PIC S9(9) COMP.
           05  CIRC-SENSEG-COUNT   PIC S9(9) COMP.
           05  CIRC-KEY-FEEDBACK   PIC X(12).
       PROCEDURE DIVISION USING IO-PCB CIRC-PCB.
       MAIN-PARAGRAPH.
           MOVE '000100' TO MEMBER-SSA-KEY
           PERFORM LIST-LOANS
           PERFORM CHARGE-FINE
           MOVE '000003' TO LS-BOOK-ID
           MOVE '20261020' TO LS-LOAN-DATE
           MOVE '20261110' TO LS-DUE-DATE
           PERFORM CHECK-OUT
           MOVE '000001' TO LOAN-SSA-KEY
           PERFORM RETURN-BOOK
           GOBACK.
       LIST-LOANS.
           CALL 'CBLTDLI' USING DLI-GU CIRC-PCB MEMBER-RECORD
               MEMBER-SSA
           IF NOT CIRC-OK
               DISPLAY 'MEMBER NOT READ, STATUS ' CIRC-STATUS
           ELSE
               DISPLAY MEMBER-NAME
               PERFORM UNTIL NOT CIRC-OK
                   CALL 'CBLTDLI' USING DLI-GNP CIRC-PCB LOAN-SEG
                       LOAN-SSA-ANY
                   IF CIRC-OK
                       DISPLAY '  LOAN ' LS-BOOK-ID ' DUE ' LS-DUE-DATE
                   END-IF
               END-PERFORM
               IF NOT CIRC-NOT-FOUND
                   DISPLAY 'GNP FAILED, STATUS ' CIRC-STATUS
               END-IF
           END-IF.
       CHECK-OUT.
           CALL 'CBLTDLI' USING DLI-ISRT CIRC-PCB LOAN-SEG
               MEMBER-SSA LOAN-SSA-ANY
           EVALUATE TRUE
               WHEN CIRC-OK
                   DISPLAY 'LOAN ADDED'
               WHEN CIRC-DUPLICATE
                   DISPLAY 'BOOK ALREADY ON LOAN TO THIS MEMBER'
               WHEN CIRC-NOT-FOUND
                   DISPLAY 'NO SUCH MEMBER'
               WHEN OTHER
                   DISPLAY 'ISRT FAILED, STATUS ' CIRC-STATUS
           END-EVALUATE.
       RETURN-BOOK.
           CALL 'CBLTDLI' USING DLI-GHU CIRC-PCB LOAN-SEG
               MEMBER-SSA LOAN-SSA-KEYED
           IF CIRC-OK
               CALL 'CBLTDLI' USING DLI-DLET CIRC-PCB LOAN-SEG
               IF CIRC-OK
                   DISPLAY 'LOAN DELETED'
               ELSE
                   DISPLAY 'DLET FAILED, STATUS ' CIRC-STATUS
               END-IF
           ELSE
               DISPLAY 'LOAN NOT FOUND, STATUS ' CIRC-STATUS
           END-IF.
       CHARGE-FINE.
           CALL 'CBLTDLI' USING DLI-GHU CIRC-PCB MEMBER-RECORD
               MEMBER-SSA
           IF CIRC-OK
               ADD 2.14 TO MEMBER-FINES
               CALL 'CBLTDLI' USING DLI-REPL CIRC-PCB MEMBER-RECORD
               IF NOT CIRC-OK
                   DISPLAY 'REPL FAILED, STATUS ' CIRC-STATUS
               END-IF
           END-IF.

How it works:

  • Working-storage. DLI-FUNCTIONS holds the six function codes as X(4). MEMBER-SSA, LOAN-SSA-KEYED and LOAN-SSA-ANY are the SSAs, laid out as described above. MEMBER-RECORD (from MEMBREC) and LOAN-SEG are the I/O areas.

  • Linkage. IO-PCB and CIRC-PCB are the masks, in the order of the PSB (CMPAT=YES gives the I/O PCB first). The 88 levels on CIRC-STATUS name the blank (success), GE, GB and II codes. Binary fields are S9(9) COMP, 4 bytes.

  • LIST-LOANS. A GU with the qualified member SSA finds the member and so establishes parentage. A PERFORM UNTIL loop then issues GNP with the unqualified LOAN SSA; each call returns the next loan under that member, and GE ends the loop. A status other than GE after the loop is an error and is reported.

  • CHARGE-FINE. GHU holds the member, the program changes MEMBER-FINES in the I/O area, and REPL writes it back.

  • CHECK-OUT. The I/O area holds the new loan and the call carries the qualified member SSA and the unqualified LOAN SSA. A blank status means the loan was added, II means a loan with that book key already exists under the member, and GE means the member (the parent) was not found.

  • RETURN-BOOK. GHU with two SSAs (the member, then the loan by book) holds the loan and only the loan is returned into LOAN-SEG, because no command code asks for the path. DLET then removes it. Neither call is repeated after a failure.

Under a batch (DL/I) region IMS passes control to the program through PROCEDURE DIVISION USING with the PCBs. A batch job step starts the IMS region controller and names the program and the PSB in its parameter (z/OS; not run here; an excerpt, with the library names as placeholders):

//STEP1    EXEC PGM=DFSRRC00,PARM='DLI,LOANIMS,CIRCPSB'
//STEPLIB  DD DSN=IMS.SDFSRESL,DISP=SHR
//         DD DSN=USERID.CIRC.LOADLIB,DISP=SHR
//IMS      DD DSN=IMS.PSBLIB,DISP=SHR
//         DD DSN=IMS.DBDLIB,DISP=SHR
//CIRCDB   DD DSN=USERID.CIRC.IMSDB,DISP=SHR
//SYSPRINT DD SYSOUT=*

DLI selects a DL/I batch region (the other forms in the IBM manual are BMP and DBB), the IMS DD names the PSB and DBD libraries it loads from, and the CIRCDB DD name is the one the DBD gives to the database data set. IMS supplies catalogued procedures (IMSCOBOL and IMSCOBGO) that compile the program and bind the language interface module to it, so that most sites do not code that step by hand. Under IMS TM the same program logic runs in a message processing region and IMS schedules it from a transaction code instead of JCL. The compile and link side of this is on Compiling, Linking and Language Environment.

Status codes

After every call the status code is blank when the call was completely successful. Anything else is either an expected condition or an error. The IBM manuals divide codes into four groups: successful or exceptional but valid conditions, errors in the program, I/O or system errors, and data-availability codes. These are the ones a COBOL programmer meets first:

Code Group Meaning

blank

Success

The call completed.

GE

Valid condition

No segment satisfies the SSAs of a get call (the usual "not found" and the end of the children under a parent for GNP); on ISRT one of the parents does not exist.

GB

Valid condition

A GN reached the end of the database without satisfying the call, the normal end of a sequential scan. After a GB another GN would start over at the first segment.

GA

Valid condition

An unqualified GN or GNP crossed a hierarchic boundary into a higher level. Information only.

GK

Valid condition

An unqualified GN or GNP returned a different segment type at the same level. Information only.

II

Valid condition

An ISRT tried to insert a segment that already exists (for example an equal key under the same parent).

AJ

Program error

The format of an SSA is invalid (for example a qualified SSA on REPL, or a malformed qualification).

AK

Program error

An SSA names a field that is not defined in the DBD; the PCB’s level number tells which SSA.

AM

Program error

The call function is not compatible with the PCB’s processing option or segment sensitivity, or with the program type (for example a REPL on a segment the PCB is not sensitive to for replace, whose I/O area differs from the held segment).

AI

System error

A database open error (for example a missing DD statement).

QC, QD

Message calls

No more messages in the queue for the program (QC), or no more segments in this message (QD).

A program should treat blank as success, name the codes it expects (GE, GB, II), and stop on everything else. A common pattern is a status-check paragraph that displays the PCB’s database name, segment name, level and status, then ends the step with an abend or a non-zero return code, since the IBM manuals say a program that receives an error status code should terminate so that the problem can be found and fixed. The exact causes and corrections of every code are in the status code explanations of the IMS messages and codes manual.

IMS Transaction Manager in one paragraph

Under IMS TM a user at a terminal (or another system) enters a transaction code, IMS puts the input message on a queue, and IMS schedules the message processing program (MPP) associated with that code in a message processing region. The MPP loops through five steps: retrieve a message, process it and access the database as needed, respond, repeat until no message is left, then end. It retrieves the first segment of a message with a GU call on the I/O PCB (GN calls fetch any further segments, ending with QD), and it answers by building the reply and issuing ISRT against the I/O PCB, which already holds the name of the terminal that sent the input. When the queue is empty the next GU returns QC, and the program ends. The database calls inside an MPP are the same GU, GN, ISRT, REPL and DLET calls of the previous sections, using DB PCBs; message calls use the I/O PCB; and the program uses no ACCEPT or file I/O of its own. A batch-oriented BMP (a batch program that runs in an IMS region) is the other common form: it reads and updates the same databases, and it should take checkpoints so that its updates are committed and it can be restarted.

When you will meet IMS

IMS is one of the oldest mainframe database and transaction systems and is still documented and released by IBM, so programs written for it are still maintained. You are likely to meet it in these places:

  • Banking, insurance and airline back ends where a high-volume, key-oriented workload was moved to IMS decades ago and never needed to be replaced.

  • Batch programs and message programs in the same shops as Db2 and CICS, where an MPP or a BMP updates an IMS database that another system reads through an extract.

  • CICS programs that use DL/I through the database control (DBCTL) interface instead of the batch call interface: they use EXEC DLI commands or call CBLTDLI and obtain the PCB addresses from the user interface block (UIB) after a PCB call.

  • Modernisation projects where the question is how to expose an IMS transaction or database to a Java or REST client (IMS Connect, the IMS solutions for Java, or SQL access to IMS data) or how to migrate the hierarchy to relational tables, which is the topic of Modernization Strategies.

If your first task is a change to an existing program, the useful habits are to read the PSB and DBD first (they say what the program can do), to look for the status-check paragraph, and to remember that a deleted parent takes its dependents with it.

Common mistakes

  • Not testing the status code after every call. IMS does not abend the program for most exceptional conditions, and the code stays in the PCB until the next call changes it. A missed GE shows up later as stale data in the I/O area.

  • REPL or DLET after a plain GU or GN. They must follow a get-hold call (GHU, GHN or GHNP).

  • Treating GE as an error in a GNP loop. It is how the end of the children is reported; test for it and leave the loop.

  • Qualified value of the wrong length. The SSA comparison is by bytes, so '1' does not match the X(6) field '000001'.

  • Wrong PCB order. The PROCEDURE DIVISION USING list must be in the PSB’s order, with the I/O PCB first, or every call refers to the wrong database.

  • Deleting a parent without realising. DLET removes the segment and all its dependents.

  • Passing the wrong data item as the function code. It must be exactly four characters, padded on the right.

  • Declaring the PCB mask with the wrong field sizes. The binary fields are 4 bytes each; a mask that is too short reads the key feedback area from the wrong offset.