You are on page 1of 39

COBOL and DL/I The first statement in a COBOL program is an ENTRY statement that establishes the address of the

PCBs defined in the PSB. The PCBs, in turn, establish the address of the databases. For this reason, IMS COBOL programs do not include a FILE-CONTROL entry in the Environment Division for any databases. IMS programs are, in many ways, similar to subroutines. Think of IMS programs as subroutines to DL/I, hence the ENTRY statement requirement. ENTRY statements reside in the Procedure Division, as follows: PROCEDURE DIVISION A000-MAIN-PROCESS. ENTRY DLITCBL USING EMPLOYEE-DB-PCB-MASK. DLITCBL is an abbreviation for DL/I to COBOL. Addressability to the PCB is established via the USING parameter of the ENTRY statement (in this case, EMPLOYEE-DB-PCB-MASK). The PCB-Mask EMPLOYEE-DB-PCB-MASK is a PCB-mask. Below is the first statement from the PSB definition given in the Logical Views and Program Specification Blocks section of this chapter. Note that the PCB macro identifies the database. Through this rather circuitous route, the COBOL program establishes a connection to the EMPLOYEE database. PCB TYPE=DB,DBDNAME=EMPLOYEE,PROCOPT=A,KEYLEN=08

In addition to establishing a connection to the database, the PCB-mask serves as a communication area between the application program and DL/I. Specifically, the PCB-mask receives information concerning the status of DL/I calls to the database. A PCB-mask is defined in the Linkage Section of the COBOL program. Below is a form of the PCB-mask that you can use to work with the EMPLOYEE database. While the COBOL program is running, you can use this code to interrogate the information that DL/I inserts in the PCBmask. LINKAGE SECTION. * PCB mask for the database defined in our PSB

01 EMPLOYEE-DB-PCB-MASK. 05 PCB-DBD-NAME 05 PCB-SEG-LEVEL 05 PCB-STATUS-CODE 05 PCB-PROC-OPT 05 PCB-RESV 05 PCB-SEG-NAME 05 PCB-LEN-KEY 05 PCB-SENS-SG 05 PCB-FB-AREA PIC X(08). PIC X(02). PIC X(02). PIC X(04). PIC S9(05) COMP. PIC X(08). PIC S9(05) COMP. PIC S9(05) COMP. PIC X(08).

Table 15.1 lists the fields in the PCB-mask. Table 15.1: PCB-Mask Fields

Field Description Contents in Example

PCB-DBD-NAME Identifies the database to access EMPLOYEE PCB-SEG LEVEL

Identifies the most recent segment level operated on by DL/I 01 when the application program operates on the first level (the Employee segment); 02 when the program operates on the second level (the Education segment) PCB-STATUS-CODE Contains the DL/I status code Spaces, indicating a successful database call; GE, indicating that there are no segments that meet the requirements; or GB, indicating the end of the database was reached during sequential retrieval PCB-PROC-OPT Specifies processing options (defined in the PROCOPT parameter of the PSB) A (All or Any) PCB-RESV Reserved for use by DL/I Not used by COBOL application program PCB-SEG-NAME Contains the name of the most recent segment that DL/I accessed EMPLSEG or EDUCSEG PCB-LEN-KEY Contains the length of the concatenated key of the most recent database call at the lowest-level segment 8 (for a successful call to the EDUCSEG segment) PCB-SENS-SG Contains the number of sensitive segments (SENSEGS) defined in the PSB 2

PCB-FB-AREA Contains the concatenated key Field defined as PIC X(08) because the longest concatenated key we can have is 8 bytes (6 bytes for EMPLSEG plus 2 bytes for EDUSEG)

The third field, the DL/I status code field (PCB-STATUS-CODE), is perhaps the most critical field. You should check this field after every call. In most cases, spaces indicate a successful call. Unlike the length of the other fields in the PCB-mask, which are constant, the length of key field (PCB-LEN-KEY) is database dependent. A database with keys of a different byte length must define a matching size. DL/I Function Calls DL/I is a set of procedural codes and values invoked by means of ordinary subroutine calls coded by an application programmer within the host language. In other words, COBOL (the host language) invokes DL/I by means of ordinary subroutine calls. Following is the general format of a DL/I CALL statement: CALL CBLTDBI USING DL/I-function

PCB-mask SEGMENT-IO-AREA SEGMENT-SEARCH-ARGUMENTS. CBLTDLI stands for COBOL to DL/I. (Remember that the ENTRY statement calls DLITCBL.) CBLTDLI is another interface module to DL/I. DL/I Functions You can think of DL/I functions as commands. You can use commands to retrieve, update, and delete segments. You code DL/I functions (or copy them from a copybook) into the COBOL program because literals are not allowed in a CALL statement. Following is a partial list of DL/I function calls:

01 DLI-FUNCTION-CALLS. 03 FUNC-GU 03 FUNC-GN 03 FUNC-GNP 03 FUNC-GHU 03 FUNC-GHN 03 FUNC-GHNP 03 FUNC-ISRT 03 FUNC-DLET 03 FUNC-REPL PIC X(04) VALUE GU . PIC X(04) VALUE GN . PIC X(04) VALUE GNP . PIC X(04) VALUE GHU . PIC X(04) VALUE GHN . PIC X(04) VALUE GHNP. PIC X(04) VALUE ISRT. PIC X(04) VALUE DLET. PIC X(04) VALUE REPL.

The retrieve functions, also called get functions, start with the letter G. Think of a get function as the database equivalent of a READ statement. The other functions are update and delete functions. Table 15.2 lists the DL/I functions shown above. Table 15.2: Some DL/I Functions

Function Description

GU (Get Unique) Get a unique segment occurrence. A key value is supplied with this function. GN (Get Next) Get the next occurrence of a segment. Corresponds to a sequential read. GNP (Get Next within Parent)

Get the next sequential segment occurrence of a particular parent. GHU (Get Hold Unique) Get and hold a unique occurrence of a segment. Hold means prohibit access to this occurrence while operating on it. GHN (Get Hold Next) Get and hold the next sequential occurrence of a segment. GHNP (Get Hold Next within Parent) Get and hold the next sequential occurrence of a particular parent. ISRT (Insert) Insert a segment occurrence in the database. DLET (Delete) Delete a segment occurrence from the database. REPL (Replace) Replace a segment occurrence in the database.

The SEGMENT-IO-AREA The third parameter in the DL/I CALL statement is SEGMENT-IO-AREA, which defines the record layout of the segments. The SEGMENT-IO-AREA resides in the Working-Storage Section. Get functions return data to the SEGMENT-IO-AREA. Update and delete functions retrieve data from the SEGMENT-IO-AREA. Following is an example of a SEGMENT-IOAREA: WORKING-STORAGE SECTION.

* SEGMENT-IO-AREA: used to hold data passed to and from the database * 01 SEGMENT-IO-AREA. 05 EMPLOYEE-SEGMENT-IO-AREA. 10 EMPLOYEE-NUM 10 LAST-NAME 10 FIRST-NAME 10 EMPLOYEE-SSN PIC X(06) VALUE SPACES. PIC X(10) VALUE SPACES. PIC X(06) VALUE SPACES. PIC X(09) VALUE SPACES.

05 EDUCATION-SEGMENT-IO-AREA. 10 EDUCATION-CODE 10 SCHOOL-NAME 10 SCHOOL-DEGREE Segment Search Arguments Segment search arguments (SSAs), the last parameter in the CALL statement, are optional. You can include them to more precisely control access to the required data segments. SSAs are either unqualified or qualified. Unqualified SSAs identify a segment type. Qualified SSAs, in addition to identifying a segment type, specify a condition. SSAs reside in the Working-Storage Section. Following is an example of a qualified SSA for the Employee segment (EMPLSEG): WORKING-STORAGE SECTION. * Segment search argument for EMPLOYEE database employee segment * 01 EMPLOYEE-SSA. 05 SEGM-NAME 05 PIC X(08) VALUE EMPLSEG. PIC X(02) VALUE SPACES. PIC X(08) VALUE SPACES. PIC X(05) VALUE SPACES.

PIC X(01) VALUE *. PIC X(01) VALUE -.

05 COMMAND-CODE

05 BEGIN-LP

PIC X(01) VALUE (. PIC X(08) VALUE FRKEY.

05 SEGM-FIELD-NAME 05 REL-OPER 05 SEGM-KEY 05 END-RP

PIC X(02) VALUE =. PIC X(06) VALUE SPACES. PIC X(01) VALUE ).

The first field in a qualified SSA is the segment name (SEGM-NAME). The segment name is left-justified and padded with blanks if it has fewer than eight characters. In the ninth position on the line after SEGM-NAME, an asterisk tells DL/I that this is a command-code SSA. In the tenth position on the COMMAND-CODE line is a command-code field. You can turn command-code fields on and off, like switches. A hyphen (-) in the field turns the switch off. When a commandcode field is turned off, the program does not explicitly use the command-code options. The judicious use of command codes can simplify your programs logic. You can code as many command codes as you need, beginning in position ten. Beginning at position ten, DL/I interprets everything as a command code until it encounters a left parenthesis or a space. In the example, the field following the command code (BEGIN-LP) is a left parenthesis, which is followed by a segment field name (SEGM-FIELD-NAME). The segment field name, like the segment name, is left-justified and padded with blanks if it has fewer than eight characters. Also like the segment name, the segment field name must be coded in the DBD. In the example, the field name contains the value FRKEY. Following is the statement from the DBD that defines the field FRKEY, which corresponds to the EMPLOYEENUM (employee number) field. FIELD NAME=(FRKEY,SEQ,U),BYTES=06,START=1,TYPE=C The next field in the SSA is the relational operator field (REL-OPER). Our field is initialized to equal (=). Often the relational operators are coded in a program and moved to the field as needed. Here is a list of the relational operators. 01 RELATIONAL-OPERATORS. 03 REL-GT 03 REL-LT 03 REL-EQ 03 REL-GE PIC X(02) VALUE >. PIC X(02) VALUE <. PIC X(02) VALUE =. PIC X(02) VALUE >=.

03 REL-LE 03 REL-NE

PIC X(02) VALUE <=. PIC X(02) VALUE =.

The relational operators are greater than, less than, equal to, greater than or equal to, less than or equal to, and not equal to. Following the relational operator field is the segment key value field (SEGM-KEY). The segment key value field is a search field. This field is generally coded as a variable to which different values are moved during processing. For example, suppose that you are searching for an employee with the employee number A99999. The SEGM-FIELD-NAME contains FRKEY, which is the same as the EMPLOYEE-NUM. The relational operator field contains =. The following statement moves the search value to the search value field: MOVE A99999 TO SEGM-KEY The next field in the SSA is a right parenthesis (END-RP), which ends the SSA. In this example, the information passed to DL/I looks like this: EMPLSEG*-(FRKEY =A99999) DL/I processes employee segments with EMPLOYEE-NUM equal to A99999, as dictated by the DL/I function.

A Sample IMS Application

Our sample application is an IMS batch program that reads records from an input file and performs retrieve, update, insert, and delete functions on the EMPLOYEE database. Listing 15.1 shows the Identification Division, Environment Division, Data Division, and the parts of the Procedure Division that you need to follow the flow of a record. Notice that the code contains prefixes to the Data Division entries. These prefixes help to navigate through the program and to avoid data-name duplication. Note also that the code contains two SSAs. The first is for the Education segment; the second is for Employee segment. The program uses a GOBACK statement rather than a STOP RUN statement to terminate program execution. When you use GOBACK in an IMS COBOL program, it returns control to DL/I. STOP RUN, on the other hand, does not return control to DL/I, causing unpredictable results. Note This program uses constructs introduced in the COBOL-85 standard. These constructs are the EVALUATE statement, the in-line PERFORM, and explicit delimiters for control structures (for example END-EVALUATE, END-READ, END-PERFORM, and END-IF). The program uses a period (.) as the last statement in Procedure Division paragraphs, so that you need to type only one period per paragraph. The reserved word FILLER is now optional. We have chosen to define record structures without the clutter introduced with FILLER. Listing 15.1: The EMPLOYEE Program IDENTIFICATION DIVISION. PROGRAM-ID. AUTHOR. * ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-370. OBJECT-COMPUTER. IBM-370. EMPLOYEE.

DAVE SHEPPARD AND EDMUND ARRANGA.

INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT 100-INPUT-FILE ASSIGN TO UT-S-INPUT.

DATA DIVISION. FILE SECTION. FD 100-INPUT-FILE RECORDING MODE IS F LABEL RECORDS ARE STANDARD BLOCK CONTAINS 0 RECORDS. 01 100-INPUT-FILE-REC PIC X(70).

**************************************************************** *** WORKING STORAGE SECTION ***

**************************************************************** 01 IMS-FUNCTION-CALLS. 03 FUNC-GU 03 FUNC-GN 03 FUNC-GNP 03 FUNC-GHU 03 FUNC-GHN 03 FUNC-GHNP 03 FUNC-ISRT 03 FUNC-DLET 03 FUNC-REPL * 01 100-ERROR-MESSAGE. 05 PIC X(15) VALUE IMS ERR,STATUS=. PIC X(04) VALUE GU . PIC X(04) VALUE GN . PIC X(04) VALUE GNP . PIC X(04) VALUE GHU . PIC X(04) VALUE GHN . PIC X(04) VALUE GHNP. PIC X(04) VALUE ISRT. PIC X(04) VALUE DLET. PIC X(04) VALUE REPL.

05 100-ERROR-STATUS 05

PIC X(02) VALUE SPACES.

PIC X(04) VALUE ,DB=. PIC X(08) VALUE SPACES.

05 100-ERROR-DB 05

PIC X(09) VALUE ,FB-NAME=. PIC X(08) VALUE SPACES.

05 100-ERROR-FB *

* SSA - SEARCH SEGMENT AUGUMENTS FOR EMPLOYEE DATABASE. * * * 01 200-EMPLOYEE-SSA. 05 200-SEGM-NAME 05 PIC X(08) VALUE EMPLSEG. SSA FOR EMPLOYEE ROOT SEGMENT

PIC X(01) VALUE *. PIC X(01) VALUE -. PIC X(01) VALUE -.

05 200-COMMAND-CODE1 05 200-COMMAND-CODE2 05 200-BEGIN-LP 05 200-SEGM-KEYNM 05 200-REL-OPER 05 200-SEGM-KEY 05 200-END-RP * * * 01 210-EDUCATION-SSA. 05 210-SEGM-NAME 05

PIC X(01) VALUE (. PIC X(08) VALUE FRKEY. PIC X(02) VALUE =. PIC X(06) VALUE SPACES. PIC X(01) VALUE ).

SSA FOR EDUCATION SEGMENT

PIC X(08) VALUE EDUCSEG.

PIC X(01) VALUE *.

05 210-COMMAND-CODE1 05 210-COMMAND-CODE2 05 210-BEGIN-LP 05 210-SEGM-KEYNM 05 210-REL-OPER 05 210-SEGM-KEY 05 210-END-RP *

PIC X(01) VALUE -. PIC X(01) VALUE -.

PIC X(01) VALUE (. PIC X(08) VALUE FDKEY. PIC X(02) VALUE =. PIC X(02) VALUE SPACES. PIC X(01) VALUE ).

* I/O AREA - USED TO HOLD DATA PASSED TO AND FROM THE DATABASE * 01 SEGMENT-IO-AREA. 05 EMPLOYEE-SEGMENT-IO-AREA. 10 EMPLOYEE-NUM 10 LAST-NAME 10 FIRST-NAME 10 EMPLOYEE-SSN PIC X(06) VALUE SPACES. PIC X(10) VALUE SPACES. PIC X(06) VALUE SPACES. PIC X(09) VALUE SPACES.

05 EDUCATION-SEGMENT-IO-AREA. 10 EDUCATION-CODE 10 SCHOOL-NAME 10 SCHOOL-DEGREE * * INPUT FILE HOLD AREA * 01 400-INPUT-FILE-AREA. 05 400-DATABASE-FUNCTION PIC X(08) VALUE SPACES. PIC X(02) VALUE SPACES. PIC X(08) VALUE SPACES. PIC X(05) VALUE SPACES.

05 400-ROOT-FUNCTION 05 400-EMPLOYEE-NUM

PIC X(08) VALUE SPACES. PIC X(06) VALUE SPACES. PIC X(10) VALUE SPACES. PIC X(06) VALUE SPACES.

05 400-EMPLOYEE-LAST-NAME 05 400-EMPLOYEE-FIRST-NAME 05 400-EMPLOYEE-SSN 05 400-EDUC-FUNCTION 05 400-EDUC-CODE 05 400-EDUC-SCHOOL 05 400-EDUC-DEGREE * * 01 500-HOLD-AREA. 05 500-END-OF-FILE 05 500-IMS-ERROR

PIC X(09) VALUE SPACES. PIC X(08) VALUE SPACES. PIC X(02) VALUE SPACES. PIC X(08) VALUE SPACES. PIC X(05) VALUE SPACES.

PIC X(01) VALUE N. PIC X(01) VALUE N.

**************************************************************** *** LINKAGE SECTION ***

**************************************************************** LINKAGE SECTION. * * PCB MASK FOR THE DATABASE DEFINED IN OUR PSB * 01 EMPLOYEE-DB-PCB-MASK. 05 PCB-DBD-NAME 05 PCB-SEG-LEVEL PIC X(08). PIC X(02).

05 PCB-STATUS-CODE 05 PCB-PROC-OPT 05 PCB-RESV 05 PCB-SEG-NAME 05 PCB-LEN-KEY 05 PCB-SENS-SG 05 PCB-FB-AREA *

PIC X(02). PIC X(04). PIC S9(05) COMP. PIC X(08). PIC S9(05) COMP. PIC S9(05) COMP. PIC X(08).

**************************************************************** *** PROCEDURE DIVISION ***

**************************************************************** PROCEDURE DIVISION. A000-MAIN-PROCESS. ENTRY DLITCBL USING EMPLOYEE-DB-PCB-MASK PERFORM A000-INITIALIZE PERFORM B000-PROCESS-RECORD UNTIL 500-END-OF-FILE 500-IMS-ERROR END-PERFORM CLOSE 100-INPUT-FILE GOBACK . A000-INITIALIZE. = Y OR

= Y

OPEN INPUT 100-INPUT-FILE. PERFORM U100-READ-INPUT-FILE. IF 500-END-OF-FILE = Y DISPLAY ERRORINPUT FILE IS EMPTY END-IF . B000-PROCESS-RECORD. EVALUATE 400-DATABASE-FUNCTION WHEN INQUIRY PERFORM C000-INQUIRY-EMPLOYEE WHEN UPDATE PERFORM C100-UPDATE-EMPLOYEE END-EVALUATE PERFORM U100-READ-INPUT-FILE . The remainder of the Procedure Division. * ************************************************************ * READ INPUT FILE

************************************************************ U100-READ-INPUT-FILE. * READ 100-INPUT INTO 400-INPUT-FILE-AREA

AT END MOVE Y TO 500-EOF-OF-FILE END-READ . END PROGRAM. Data for the Sample Application The name of the input file is 400-INPUT-FILE. Following is the input file layout: 01 400-INPUT-FILE-AREA. 05 400-DATABASE-FUNCTION 05 400-ROOT-FUNCTION 05 400-EMPLOYEE-NUM PIC X(08) VALUE SPACES.

PIC X(08) VALUE SPACES. PIC X(06) VALUE SPACES. PIC X(10) VALUE SPACES.

05 400-EMPLOYEE-LAST-NAME

05 400-EMPLOYEE-FIRST-NAME PIC X(06) VALUE SPACES. 05 400-EMPLOYEE-SSN 05 400-EDUC-FUNCTION 05 400-EDUC-CODE 05 400-EDUC-SCHOOL 05 400-EDUC-DEGREE PIC X(09) VALUE SPACES. PIC X(08) VALUE SPACES. PIC X(02) VALUE SPACES. PIC X(08) VALUE SPACES. PIC X(05) VALUE SPACES.

The input data layout is shown in Table 15.3. Table 15.3: Input Data Layout for Sample IMS Application

Variable Name

Position Description

400-DATABASE-FUNCTION Columns 18 The program performs the appropriate paragraph based on the value in the field 400-ROOT-FUNCTION Columns 916 The function is an occurrence of the root segment 400-EMPLOYEE-NUM Columns 1722 A key field (the employees number) 400-EMPLOYEE-LAST-NAME Columns 2332 An employees last name 400-EMPLOYEE-FIRST-NAME Columns 3338 An employees first name 400-EMPLOYEE-SSN Columns 3947 An employees social security number 400-EDUC-FUNCTION

Columns 4855 The function to apply to an employees Education segment 400-EDUC-CODE Columns 5657 A code that uniquely identifies a school 400-EDUC-SCHOOL Columns 5865 A school name 400-EDUC-DEGREE Columns 6670 A degree

Following is the data contained in the input file. Note that the first line is a column marker and is not part of the input file. 12345678901234567892123456789312345678941234567895 INQUIRY E11111 E22222 SMITH JOHN 113121456

UPDATE DELETE

UPDATE REPLACE E33333 JONES JIM 123546788 UPDATE INSERT INSERT 13UCLA E55555 ASH BA AL 647987264

Remember that the EMPLOYEE database consists of the following segments and fields. EMPLSEG Segment

EDUCSEG Segment Employee Number PIC X(06) Education Code PIC X(02) Last Name PIC X(10) School Name PIC X(08) First Name PIC X(06) School Degree PIC X(05) Employee SSN PIC X(09)

The data in the EMPLOYEE database follows. The Employee (EMPLSEG) segment data is followed by any Education (EDUCSEG) segment data for that employee. For instance, Bob Chen has two Education segments following his Employee segment data. E11111CHEN 15TCU BOB 123456789 Employee segment

AA

Education segments

07PURDUE E22222SMITH 08LOYOLA

BA JOHN BS 113121456 Employee segment

Education segment 123546789 Employee segment

E333333JONES JIM 11NYU BS LOU

Education segment 123456781 Employee segment Employee segment

E44444DAVIS E66666BURNS 13UCLA

FRANC 156728933

MS

Education segment 123456783 Employee segment

E77777HIGGIN MARY 18COLGATE 00BAYLOR 19SMU AA BA MS

Education segments

Getting Data from the Database In this section, we trace the first record, an inquiry, through the program. In a nutshell, the program reads the input file to obtain an employee number of E11111, then looks for the employee number in the EMPLOYEE database. If the record is found, the program displays the employee, then looks for and displays any Education segments for the employee. At this point in the processing, the program has made a connection to the EMPLOYEE database via the ENTRY statement. Next, the program performs the standard initialization (A000INITIALIZE) that most COBOL programs use. A000-INITIALIZE opens the input file, performs U100-READ-INPUT-FILE, and reads the first record into 400-INPUT-FILE-AREA. B000-PROCESS-RECORD looks for a value of INQUIRY or UPDATE in the input record. Here is the first record of the input file: INQUIRY E11111

When the program finds the value INQUIRY, it performs the following C000-INQUIRYEMPLOYEE paragraph:

C000-INQUIRY-EMPLOYEE. MOVE 400-EMPLOYEE-NUM TO 200-SEGM-KEY

CALL CBLTDLI USING FUNC-GU EMPLOYEE-DB-PCB-MASK EMPLOYEE-SEGMENT-IO-AREA 200-EMPLOYEE-SSA PERFORM C025-EVALUATE-STATUS-CODE . C025-EVALUATE-STATUS-CODE. EVALUATE PCB-STATUS-CODE WHEN SPACES DISPLAY EMPLOYEE SEGMENT = EMPLOYEE-SEGMENT-IO-AREA PERFORM C050-INQUIRY-EDUCATION-SEGMENT WHEN GE DISPLAY EMPLOYEE NOT FOUND FOR 400-EMPLOYEE-NUM WHEN OTHER PERFORM C075-INQUIRY-ERROR END-EVALUATE . C050-INQUIRY-EDUCATION-SEGMENT. MOVE SPACE TO 210-BEGIN-LP PERFORM UNTIL (PCB-STATUS-CODE = GE OR GB) OR 500-IMS-ERROR = Y

CALL CBLTDLI USING FUNC-GNP EMPLOYEE-DB-PCB-MASK EDUCATION-SEGMENT-IO-AREA 210-EDUCATION-SSA EVALUATE PCB-STATUS-CODE WHEN SPACES DISPLAY EDUCATION SEGMENT = EDUCATION-SEGMENT-IO-AREA WHEN GB WHEN GE DISPLAY INQUIRY COMPLETE WHEN OTHER PERFORM C075-INQUIRY-ERROR END-EVALUATE END-PERFORM . C075-INQUIRY-ERROR. PERFORM MOVE PCB-STATUS-CODE TO 100-ERROR-STATUS MOVE PCB-DBD-NAME TO 100-ERROR-DB

MOVE PCB-SEG-NAME TO 100-ERROR-FB DISPLAY 100-ERROR-MESSAGE MOVE Y TO 500-IMS-ERROR

END-PERFORM . * Getting Data from the Employee Segment The CALL statement is the initial call to DL/I from the C000-INQUIRY-EMPLOYEE paragraph. It specifies four parameters: FUNC-GU, EMPLOYEE-DB-PCB-MASK, EMPLOYEE-SEGMENT-IO-AREA, and 200-EMPLOYEE-SSA. With the function call FUNC-GU (Get Unique), retrieval of the proper segment is based on a key value supplied with the call (in this case, the employee number). The name Get Unique can be misleading, because it implies a single answer. However, GU calls can retrieve non-unique occurrences. In our example, employee numbers are unique, so there is only one segment occurrence with an employee number of E11111. If a database contains non-unique key data, the FUNC-GU call would return the first occurrence that satisfies the parameters supplied in the SSA. Subsequent calls to the database would use GN (Get Next) or GNP (Get Next within Parent) to return the remaining qualifying segments. The name of the mask is EMPLOYEE-DB-PCB-MASK. Remember that DL/I uses this area to communicate with the program. Of most interest here is the PCB-STATUS-CODE field. The code checks PCB-STATUS-CODE for spaces and GE. Spaces mean a segment was found; GE means there are no qualifying segments. Both values are considered successful calls. Any other value returned from a FUNC-GU call is an error. The SEGMENT-IO-AREA for this call is EMPLOYEE-SEGMENT-IO-AREA. Get functions return data to the IO area. When the DL/I call finds the employee number E11111, it retrieves the entire Employee segment and places it in the EMPLOYEE-SEGMENT-IO-AREA. The statement DISPLAY EMPLOYEE SEGMENT = EMPLOYEE-SEGMENT-IO-AREA displays the employee number, employee last name, employee first name, and employee social security number. The display for E11111 is as follows: EMPLOYEE SEGMENT = E11111CHEN BOB 123456789 The SSA is 200-EMPLOYEE-SSA. The field 200-SEGM-NAME in the 200-EMPLOYEE-SSA record contains EMPLSEG, the data segment that we want to access. Before issuing the call, the program moves the employee number to 200-SEGM-KEY, which supplies FUNC-GU with a specific search key. In a nutshell, the call to DL/I provides an employee number, a data segment type, a return area to place the record, and a return area to place information about the status of the call.

Getting Data from the Education Segment Employee E11111 is Bob Chen. He has two Education segments, which the program is about to retrieve. The code has already performed the first DISPLAY in the C025-EVALUATE-STATUSCODE, as shown below: C025-EVALUATE-STATUS-CODE. EVALUATE PCB-STATUS-CODE WHEN SPACES DISPLAY EMPLOYEE SEGMENT = EMPLOYEE-SEGMENT-IO-AREA PERFORM C050-INQUIRY-EDUCATION-SEGMENT WHEN GE DISPLAY EMPLOYEE NOT FOUND FOR 400-EMPLOYEE-NUM WHEN OTHER PERFORM C075-INQUIRY-ERROR END-EVALUATE Next, the code performs the C050-INQUIRY-EDUCATION-SEGMENT, as shown below. Note the first statement, MOVE SPACE TO 210-BEGIN-LP, which changes a qualified SSA to an unqualified SSA. C050-INQUIRY-EDUCATION-SEGMENT. MOVE SPACE TO 210-BEGIN-LP PERFORM UNTIL (PCB-STATUS-CODE = GE OR GB) OR 500-IMS-ERROR = Y CALL CBLTDLI USING FUNC-GNP EMPLOYEE-DB-PCB-MASK

EDUCATION-SEGMENT-IO-AREA 210-EDUCATION-SSA The first call to the database specified a qualified SSA. Employee number E11111 was moved to the 200-SEGM-KEY field of the 200-EMPLOYEE-SSA record to create a qualified SSA. Now we want to retrieve all of the Education segments associated with Bob Chen, but we dont know if there are any. We need to use an unqualified SSA, since we cannot supply a key value to direct DL/I to a specific segment. Following is the Education SSA that the program uses to retrieve Education segments for Bob Chen. The boldface line is of most interest to us: 01 210-EDUCATION-SSA. 05 210-SEGM-NAME 05 PIC X(08) VALUE EDUCSEG.

PIC X(01) VALUE *. PIC X(01) VALUE -. PIC X(01) VALUE -.

05 210-COMMAND-CODE1 05 210-COMMAND-CODE2 05 210-BEGIN-LP 05 210-SEGM-KEYNM 05 210-REL-OPER 05 210-SEGM-KEY 05 210-END-RP

PIC X(01) VALUE (. PIC X(08) VALUE FDKEY. PIC X(02) VALUE =. PIC X(02) VALUE SPACES. PIC X(01) VALUE ).

The statement MOVE SPACE TO 210-BEGIN-LP makes this an unqualified SSA, because DL/I ignores everything after it encounters a space in the SSA. Now the only information that the SSA supplies to DL/I is the type of data segment (EDUCSEG). The next statement in the C050-INQUIRY-EDUCATION-SEGMENT paragraph is: PERFORM UNTIL (PCB-STATUS-CODE = GE OR GB) OR 500-IMS-ERROR = Y

This statement tells DL/I to keep retrieving Education segments for Bob Chen until GE (there are no Education segments for Bob Chen) or GB (the program reached the end of the database during sequential retrieval) or 500-IMS-ERROR = Y. In the call to the Employee segment, the code checks PCB-STATUS-CODE only for spaces and GE. In the call to the Education segment, on the other hand, we force DL/I to keep returning data until there is no more data to return, when PCB-STATUS-CODE will equal GB. If we checked PCB-STATUS-CODE after DL/I returns the Education segments for Bob Chen, the value would be spaces. We perform a sequential retrieval of any and all Education segment occurrences for Bob Chen by specifying the DL/I function as GNP (Get Next within Parent) in the first parameter of the DL/I call. The parent is the Employee segment that we just retrieved. Here is the call: CALL CBLTDLI USING FUNC-GNP EMPLOYEE-DB-PCB-MASK EDUCATION-SEGMENT-IO-AREA 210-EDUCATION-SSA As in the call to the Employee segment, we supply the EMPLOYEE-DB-PCB-MASK. This time we supply the EDUCATION-SEGMENT-IO-AREA, where Education segment data will be returned by DL/I. The next statement in the C050-INQUIRY-EDUCATION-SEGMENT paragraph is an EVALUATE statement that interrogates the PCB-STATUS-CODE: C025-EVALUATE-STATUS-CODE. EVALUATE PCB-STATUS-CODE WHEN SPACES DISPLAY EMPLOYEE SEGMENT = EMPLOYEE-SEGMENT-IO-AREA PERFORM C050-INQUIRY-EDUCATION-SEGMENT WHEN GE DISPLAY EMPLOYEE NOT FOUND FOR 400-EMPLOYEE-NUM WHEN OTHER

PERFORM C075-INQUIRY-ERROR END-EVALUATE The program displays Bob Chens two Education segments, followed by an INQUIRY COMPLETE message, as follows: EDUCATION SEGMENT = 15TCU EDUCATION SEGMENT = 07PURDUE INQUIRY COMPLETE The final paragraph in the DL/I inquiry call is C075-INQUIRY-ERROR: C075-INQUIRY-ERROR. PERFORM MOVE PCB-STATUS-CODE TO 100-ERROR-STATUS MOVE PCB-DBD-NAME TO 100-ERROR-DB AA BA

MOVE PCB-SEG-NAME TO 100-ERROR-FB DISPLAY 100-ERROR-MESSAGE MOVE Y END-PERFORM The C075-INQUIRY-ERROR paragraph captures messages returned by DL/I to the EMPLOYEE-DB-PCB-MASK area to help determine the cause of any abnormal program terminations. The fields that the paragraph captures are PCB-STATUS-CODE (the status code), PCB-DBD-NAME (the name of the database), and PCB-SEG-NAME (the name of the segment accessed when an error occurred). You can determine the cause of most errors in processing using these three data points. Two common system errors are AO, which is an I/O error caused by VSAM, and AI, which signifies a data management error. User errors include AC, which means an incorrect use of SSAs; AJ, which means you probably coded a [ rather than a ( in an SSA; and AK, which generally indicates a misspelled segment name in an SSA. TO 500-IMS-ERROR

Deleting Data The next record in the input file appears below. The first field is the 400-DATABASEFUNCTION. The second field is the 400-ROOT-FUNCTION. UPDATE DELETE E22222 SMITH JOHN 113121456

The branch that the processing takes in the B000-PROCESS-RECORD paragraph is in boldface type, followed by the subsequent path (paragraphs) taken by the processing. B000-PROCESS-RECORD. EVALUATE 400-DATABASE-FUNCTION WHEN INQUIRY PERFORM C000-INQUIRY-EMPLOYEE WHEN UPDATE PERFORM C100-UPDATE-EMPLOYEE END-EVALUATE PERFORM U100-READ-INPUT-FILE . C100-UPDATE-EMPLOYEE. MOVE 400-EMPLOYEE-NUM TO 200-SEGM-KEY CALL CBLTDLI USING FUNC-GHU EMPLOYEE-DB-PCB-MASK EMPLOYEE-SEGMENT-IO-AREA 200-EMPLOYEE-SSA EVALUATE PCB-STATUS-CODE

WHEN SPACES EVALUATE 400-ROOT-FUNCTION WHEN DELETE PERFORM D100-DELETE-EMPLOYEE-SEGMENT WHEN REPLACE PERFORM D200-REPLACE-EMPLOYEE-SEGMENT WHEN OTHER DISPLAY INVALID 400-ROOT-FUNCTION END-EVALUATE WHEN GE DISPLAY EMPLOYEE NOT FOUND EVALUATE 400-ROOT-FUNCTION WHEN INSERT PERFORM D300-INSERT-EMPLOYEE-SEGMENT WHEN SPACES DISPLAY INVALID 400-ROOT-FUNCTION END-EVALUATE WHEN OTHER PERFORM C075-INQUIRY-ERROR END-EVALUATE . * DELETE EMPLOYEE SEGMENT D100-DELETE-EMPLOYEE-ROOT-SEGMENT.

CALL CBLTDLI USING FUNC-DLET EMPLOYEE-DB-PCB-MASK EMPLOYEE-SEGMENT-IO-AREA EVALUATE PCB-STATUS-CODE WHEN SPACES DISPLAY EMPLOYEE ROOT SEGMENT DELETED WHEN OTHER PERFORM C075-INQUIRY-ERROR END-EVALUATE . As before, the processing moves the employee number to the SSA before calling DL/I. The DL/I function in this call is GHU (Get Hold Unique). We want to hold the segment we get to prevent anyone else from accessing it. The three remaining parametersthe EMPLOYEE-DB-PCBMASK, the EMPLOYEE-SEGMENT-IO-AREA, and the 200-EMPLOYEE-SSAfunction as they did in the call that retrieves Chens record, except that the value of the employee number (search argument) in the SSA is different: MOVE 400-EMPLOYEE-NUM TO 200-SEGM-KEY

CALL CBLTDLI USING FUNC- GHU EMPLOYEE-DB-PCB-MASK EMPLOYEE-SEGMENT-IO-AREA 200-EMPLOYEE-SSA A nested EVALUATE statement appears after the call. The outer nest tests for success in finding the employee (PCB-STATUS-CODE contains spaces). The program finds the segment and performs paragraph D100-DELETE-EMPLOYEE-ROOT-SEGMENT: D100-DELETE-EMPLOYEE-ROOT-SEGMENT.

CALL CBLTDLI USING FUNC-DLET EMPLOYEE-DB-PCB-MASK EMPLOYEE-SEGMENT-IO-AREA Note that the parameter list is missing the 200-EMPLOYEE-SSA parameter. SSAs are not used on delete or replace calls. The Get Hold family of callsGH, GHU, GHN, and GHNPinforms IMS to expect a delete or replace call. As a consequence, IMS keeps track of the segment for you. The function call is FUNC-DLET (a delete). After ensuring that the delete succeeded (PCBSTATUS-CODE contains spaces), John Smith, employee number E22222, no longer appears in the EMPLOYEE database. The program displays the following message: EMPLOYEE ROOT SEGMENT DELETED In addition to deleting John Smiths Employee segment, the program deletes all of his Education segments. When a parent segment is deleted from the database, the child segments are also deleted. Replacing Data The next operation involves replacing (IBMs term for updating) data. The record in the input file appears below. The program replaces the social security number (the last field in the record). Remember that the first field is the 400-DATABASE-FUNCTION and the second field is the 400-ROOT-FUNCTION. UPDATE REPLACE E33333 JONES JIM 123546788

The processing performs the following two paragraphs, which are very similar to those it performs when deleting a segment. Processing logic follows the boldface line. B000-PROCESS-RECORD. EVALUATE 400-DATABASE-FUNCTION WHEN INQUIRY PERFORM C000-INQUIRY-EMPLOYEE WHEN UPDATE

PERFORM C100-UPDATE-EMPLOYEE END-EVALUATE PERFORM U100-READ-INPUT-FILE . C100-UPDATE-EMPLOYEE. MOVE 400-EMPLOYEE-NUM TO 200-SEGM-KEY CALL CBLTDLI USING FUNC-GHU EMPLOYEE-DB-PCB-MASK EMPLOYEE-SEGMENT-IO-AREA 200-EMPLOYEE-SSA EVALUATE PCB-STATUS-CODE WHEN SPACES EVALUATE 400-ROOT-FUNCTION WHEN DELETE PERFORM D100-DELETE-EMPLOYEE-SEGMENT WHEN REPLACE PERFORM D200-REPLACE-EMPLOYEE-SEGMENT WHEN OTHER DISPLAY INVALID 400-ROOT-FUNCTION CONTINUE END-EVALUATE WHEN GE DISPLAY EMPLOYEE NOT FOUND

EVALUATE 400-ROOT-FUNCTION WHEN INSERT PERFORM D300-INSERT-EMPLOYEE-SEGMENT WHEN SPACES DISPLAY INVALID 400-ROOT-FUNCTION END-EVALUATE WHEN OTHER PERFORM C075-INQUIRY-ERROR END-EVALUATE Up to this point, the processing follows the same logic that it follows to delete a segment. The processing uses the GHU function to prevent anyone else from accessing a segment while it is being operated on. Following is the D200-REPLACE-EMPLOYEE-SEGMENT paragraph: D200-REPLACE-EMPLOYEE-SEGMENT. PERFORM MOVE 400-EMPLOYEE-LAST-NAME TO LAST-NAME

MOVE 400-EMPLOYEE-FIRST-NAME TO FIRST-NAME MOVE 400-EMPLOYEE-SSN END-PERFORM CALL CBLTDLI USING FUNC-REPL EMPLOYEE-DB-PCB-MASK EMPLOYEE-SEGMENT-IO-AREA TO EMPLOYEE-SSN

EVALUATE PCB-STATUS-CODE WHEN SPACES DISPLAY EMPLOYEE ROOT SEGMENT REPLACED WHEN OTHER PERFORM C075-INQUIRY-ERROR END-EVALUATE

Remember that DL/I places data in the EMPLOYEE-SEGMENT-IO-AREA when getting a segment, and that DL/I retrieves data from the area when updating a segment. The PERFORM statement moves the data from the input file to LAST-NAME, FIRST-NAME, and EMPLOYEESSN fields in the EMPLOYEE-SEGMENT-IO-AREA record. The only field we want to update is the social security number field, but since DL/I replaces all the data in the Employee segment, we must place data in all the fields. 400-EMPLOYEE-NUM has been moved to 200-SEGM-KEY in the C100-UPDATE-EMPLOYEE paragraph. One field DL/I cannot replace is the employee number field, since it is a key field. If we changed E33333s employee number, the segment would need to be deleted and a new segment inserted. The CALL statement uses FUNC-REPL (Replace). Note that an SSA is not supplied with the call. A successful call returns spaces to PCB-STATUS-CODE, and the following message is displayed: EMPLOYEE ROOT SEGMENT REPLACED Inserting Data The final operation involves inserting data segments. The program inserts an Employee segment and an Education segment. In preparation for the call, the processing moves employee data to the fields of the EMPLOYEE-SEGMENT-IO-AREA. Note that the program moves spaces to 200BEGIN-LP, which unqualifies the SSA, 200-EMPLOYEE-SSA. Inserting a Parent Segment

Following is the input record. A new Employee data segment occurrence after insertion contains the employee number E55555, the employee name Al Ash, and the social security number 647987264. UPDATE INSERT E55555 ASH AL 647987264 INSERT 13UCLA BA Following is the paragraph that inserts the Employee segment: D300-INSERT-EMPLOYEE-SEGMENT. PERFORM MOVE 400-EMPLOYEE-NUM TO EMPLOYEE-NUM

MOVE 400-EMPLOYEE-LAST-NAME TO LAST-NAME MOVE 400-EMPLOYEE-FIRST-NAME TO FIRST-NAME MOVE 400-EMPLOYEE-SSN MOVE SPACES END-PERFORM CALL CBLTDLI USING FUNC-ISRT TO EMPLOYEE-SSN

TO 200-BEGIN-LP

EMPLOYEE-DB-PCB-MASK EMPLOYEE-SEGMENT-IO-AREA 200-EMPLOYEE-SSA EVALUATE PCB-STATUS-CODE WHEN SPACES DISPLAY EMPLOYEE SEGMENT INSERTED WHEN OTHER PERFORM C075-INQUIRY-ERROR END-EVALUATE EVALUATE 400-EDUC-FUNCTION

WHEN INSERT PERFORM D300-INSERT-EDUCATION-SEGMENT WHEN OTHER CONTINUE END-EVALUATE . The insert operation specifies the function FUNC-ISRT (Insert). The EMPLOYEE-DB-PCBMASK contains the name of the database to operate on. Remember that DL/I places the database name in the first field of the EMPLOYEE-DB-PCB-MASK. The EMPLOYEE-SEGMENT-IOAREA record contains the data to insert in the segment. 200-EMPLOYEE-SSA contains the type of segment to insert. After successfully inserting the segment, the program displays the following message: EMPLOYEE SEGMENT INSERTED The last EVALUATE statement in the paragraph above directs control to D300-INSERTEDUCATION-SEGMENT. Inserting a Child Segment Unlike inserting the Employee segment (the root segment), the program must direct the Education segment occurrence insertion to a specific parent. We accomplish this by supplying the function call with two SSAs. The first SSA finds the Employee segment (the parent segment); the second SSA supplies the inserted segment type. The first SSA, 200-EMPLOYEE-SSA, must be qualified by moving a left parenthesis to 200BEGIN-LP and by moving 400-EMPLOYEE-NUM to 200-SEGM-KEY. The second SSA, 210EMPLOYEE-SSA, must be unqualified by moving spaces to 210-BEGIN-LP. The following paragraph contains these moves: D300-INSERT-EDUCATION-SEGMENT. PERFORM

MOVE 400-EMPLOYEE-NUM MOVE 400-EDUC-CODE MOVE 400-EDUC-SCHOOL MOVE 400-EDUC-DEGREE MOVE ( MOVE SPACES END-PERFORM

TO 200-SEGM-KEY TO EDUCATION-CODE TO SCHOOL-NAME TO SCHOOL-DEGREE

TO 200-BEGIN-LP TO 210-BEGIN-LP

CALL CBLTDLI USING FUNC-ISRT EMPLOYEE-DB-PCB-MASK EDUCATION-SEGMENT-IO-AREA 200-EMPLOYEE-SSA 210-EMPLOYEE-SSA EVALUATE PCB-STATUS-CODE WHEN SPACES DISPLAY EDUCATION SEGMENT INSERTED WHEN II DISPLAY EDUCATION SEGMENT ALREADY EXISTS WHEN OTHER PERFORM C075-INQUIRY-ERROR END-EVALUATE . The DL/I call is FUNC-ISRT, an insert. 200-EMPLOYEE-SSA directs DL/I to the correct parent, while 210-EMPLOYEE-SSA provides DL/I with the correct segment type occurrence to add. As always, we check the status code to ensure a successful operation. Upon success, the program displays the following message:

EDUCATION SEGMENT INSERTED

You might also like