Mainframes 360
The one stop destination for System Z professionals

Sunday, December 26, 2010

Inserting data into an IMS Database

Q. Give me a rough sketch of this COBOL-IMS Program.
I have coded a COBOL-Program to initially load(insert) data into an IMS Database. Broadly speaking, this COBOL-Program reads a Transaction from a Line-Sequential File, and loads it into the Inventory IMS Database. This process is repeated over and over again, until all the transactions from the Line-Sequential File have been read, and you've reached the End-Of-File.

Here's the Structure-Chart for this COBOL Program. A short overview of the modules of this COBOL-Program is given below.

I have broken down this COBOL-Program into 3 Modules – 300-HOUSEKEEPING(Yellow), 500-MAINLINE-PROCESSING(Pink) and 700-CLEANUP(Blue). The Housekeeping Module essentially performs any preparatory tasks such as, Opening the File etc. The Cleanup Module on the other hand, performs termination tasks such as, closing the file, displaying Program-Statistics, just before the program is about to end. 

The heart of the Program is 500-MAINLINE-PROCESSING Module. Read a Transaction, insert into the Database, read the next transaction, put in the database and this cycle of reading-and-inserting continues, till all the transactions have been processed.
Q. Could you show me the Program-Header?
The Name of this COBOL-IMS Program is IMSPGM01. The Program-Header has Comments which describe the Program-Name, the functionality of the program. This COBOL Program gets the data-input from the
Line-Sequential INPUT-FILE (Symbolic Name is INDD). Line 28 in the Program-Listing, is the SELECT Statement, which assigns the COBOL File INPUT-FILE to the Symbolic File-Name INDD.

Q. What is the Record-Layout of the Input-File? What's the data in the Input File?
The Input-File contains the Data, to be Inserted into the IMS Database. The COBOL-format or Record-Layout of the Data Input-File, is stored in a separate Copybook INVINPUT. I have shown the various fields of the Input-File Record below.


The Line-Sequential Input File has 132-Byte records. Let me show you a rough sketch(though not the exact representation) of the data-contents of the Input-File, so you would be in a position to compare the File-Record vis-à-vis its Record Layout.

I have used the symbol '|' as a Separator between fields, for the sake of understanding. Every record has a 1-Byte Transaction code, which tells if its Vendor Data(V), Item-Data(I) or Stock-Location Data(S). Then follows the actual Data-Area which is 131-Bytes large.

Let's take a look at Vendor records in Blue. 001 is the Vendor-Code, 'INDUS CHEMICALS' is the name of the vendor. Peter’s Road Royapettah, Chennai, TN and 600001 make up the address, city, state and zip-code. 4464004332 and 8097415095 make up the Contact Field.

There are four Items in this file in Red. 0011 is the item number, 'Sodium Palmitate' is the item description, 15500.00 and 4600.00 make up the item-price and unit-cost fields.

There are six Stock-Location records in this file in Green. DEL is the location, 1500 is the quantity-on-hand, 300 is re-order point and 450 is the quantity on order. 16-02-04 is the re-order date.

For those of you, who'd be setting up the Mainframe File at Home, here’s a Hex-dump of the Mainframe File – the actual data contents of the Mainframe Input File.

Let me now bring things into perspective. I have created a new blank Inventory-Database with the following Segments – Vendor Segment, Item Segment and Stock-Location Segment. A Vendor may supply many Items. An Item may be stocked at many locations.

When you load Data into an IMS Database, you must load the records in Sequential(Hierarchical) Order. Basically, my COBOL-Program will read the data from the Inventory-File and LOAD it Sequentially into the IMS-Database, shown above. After Loading, the resulting IMS-Database will have records like this -

Q. What is there in the FILE Section of the COBOL-IMS Program?
The FILE SECTION of my COBOL Program, describes the Record-Layout of the Input-File. The Record-Layout(COBOL Structure) of my Input-File is maintained in a separate Mainframe Copybook INVINPUT under the Library SYSADM.DEMO.COPYLIB. I just COPY INVINPUT, in my COBOL Program, it'll be expanded(substituted) at compile-time.

Q. What does the Working-Storage Area of a COBOL-IMS Program look like?
I am going to follow a standard Working-Storage Layout for all of my COBOL-IMS Programs. The picture below explains, how I have organised my Working Storage Layout. 

Q. What are the Flag and switches in this COBOL Program?
Flags and Switches : I use the END-OF-FILE Switch to raise an alarm, when all the transactions in the Input-File have been read. Its initial value is set to 'N' – the label NOT-AT-END. After the last record is read, the switch is turned ON, its value is set to 'Y'. 

Q. What about the DLI Function Codes?
The DLI Function is the operation to be performed on the IMS Database. Since, I am going to Insert New Data in the Inventory Database, I shall use the ISRT Function.

Q. What about the Segment Input-Output Area?
The Segment IO-Area is a COBOL Storage Area, a buffer for sending and receiving data from IMS DB Software. In this COBOL Program, I shall first store the data in the Segment IO-Area, and then issue an ISRT Call. Consequently, the data from the Segment IO-Area gets inserted into the Inventory Database.


The IO-Area should be big enough to accommodate Vendor Data, or Item Data or Stock Data. Out of the tree, the data of 1 vendor takes largest space  - 131 Bytes, so I have declared my IO-Area to be a PIC X(131).
Q. What about the Application Database SSA's?
SSA(Segment Search Arguments) is used to specify the Segment-Type. For example, if I had to insert Vendor Data, the SSA would be set to 'VENDRSEG '. Likewise, if I want to insert Items Data, I'd have to set the SSA to 'ITEMSSEG ', and to insert Stock Data, the SSA would have to be 'STLOCSEG '. I have declared the SSA as a 9-Bytes COBOL Field.

Q. What about the Counters in this COBOL Program?
I would like take counts of the number of input transactions read, no. of records inserted into database, and the no. of records that error-ed out.

Q. What is there in the LINKAGE Section of this Program?
After issuing an IMS Call, the IMS DB Software stores a 2-Digit Status Code, indicating the success or failure of the Database Operation in the PCB Control-Blocks in Memory. The corresponding COBOL Definition(Fields) for these PCB Control-Blocks is called the PCB Mask. The PCB Mask COBOL Fields are declared under the Linkage Section of a COBOL-IMS Program.

Here's the PCB Mask COBOL Fields. I have stored them in a separate Mainframe Copy-Book INVENPCB, under the Library SYSADM.DEMO.COPYLIB.

What I did is, I just coded COPY INVENPCB, in my COBOL Program, so the above PCB Mask COBOL Fields get copied to my COBOL Program at Compile-Time.

Q. Roughly, what does the PROCEDURE DIVISION of this COBOL Program look like?
The PROCEDURE DIVISION is broadly broken down into three activities – Initialization, Processing and Cleanup. The Lines 76 through 77 of the COBOL Source-Code PERFORM the 300-HOUSEKEEPING Para, that does startup things like, Opening Files, and prepares for the processing ahead. The lines 79 through 80, PERFORM the 500-MAINLINE-PROCESSING Paragraph. The function of the MAINLINE-PROCESSING Paragraph is, to read the data from the Input-File, and Insert this data into the Database. After all the data has been inserted, the Lines 83 through 84 PERFORM the 700-CLEANUP Routine, that does termination tasks, like closing any files.

Q. What does the Housekeeping Routine do?
The 300-HOUSEKEEPING Routine essentially OPENs the COBOL File INPUT-FILE. Once the file is OPEN, you can read the data-records from the File. 

Q. What does the Mainline Processing Routine do?
The 500-MAINLINE-PROCESSING Routine is broken down into three steps : (A) Read a Data-Record from the Input-File (B) Preparing the Data to be Loaded into the IMS Database(C) Insert the Data Record into the IMS Database.

Q. What does the 530-READ-DATA Routine do?
The 530-READ-DATA executes the COBOL READ instruction. The READ...END-READ Block reads one record from the INPUT-FILE. The AT END special condition holds TRUE, when all the transactions from the INPUT-FILE have been processed, and the End of the Sequential File has been detected. No further processing is needed. The Line 115 in the COBOL Source Code SETs my AT-END flag to TRUE, thereby turning ON the END-OF-FILE-SWITCH = 'Y'. The GO TO Statement in COBOL causes the control to jump to 500-MAINLINE-PROCESSING-EXIT Point, and exit out.

Q. What does the 550-PREPARE-LOAD-DATA Routine do?
When one Record is Read from the INPUT-FILE, it gets stored in the 01-Level Group Data-Item INPUT-RECORD. Essentially, the INPUT-RECORD in the file has a 1-Byte TRANSACTION-CODE Prefix , followed by a 131-Bytes DATA-AREA, which consists of the actual data to be inserted.

The below schematic gives you a Split-View of any data-record, when it fetched from the INPUT-FILE into the INPUT-RECORD Cobol Area, in the COBOL Program. Like when the first record is read, 'V' is stored in the TRANSACTION-CODE Field, and '001 INDUS CHEMICALS ...' is stored in the DATA-AREA.

Essentially, we are interested to Load, whatever contents are present in the DATA-AREA into the IMS Database. Thus, I have coded a MOVE from DATA-AREA to the SEGMENT-IO-AREA, in the COBOL Program.


Moreover, you also need to supply an Unqualified-SSA on the ISRT Call. This will tell IMS, what's the data you are trying to Insert? Is it Vendor-Data, Item-Data or Stock-location Data? Observe that, in the INPUT-RECORD, the TRANSACTION-CODE field contains either V, I or S. In the COBOL Code, I'll check this field. A transaction-code 'V' implies Vendor-Data, 'I' implies Item-Data and 'S' implies Stock Location Data. I have coded a MOVE statement, to store the appropriate Segment-Type to the Unqualified-SSA.

Now, we are all set to Insert the Data in the IMS Database.
Q. How does the 560-ISRT-INVDB Routine look like?
The 560-ISRT-INVDB Routine issues an ISRT Call on the Inventory Database. The data stored in SEGMENT-IO-AREA will be inserted into the Database. The Segment-Type is indicated by the Unqualified SSA.


After execution, IMS DB Software communicates back important information, such as a two-digit Status code representing the Success or Failure of the Operation, the Key-Value of Data last inserted, the Key-Length etc in the PCB Control Blocks in Memory. You can see these details in the COBOL Program through the INVENTORY-PCB-MASK. By examining the contents of the INVENTORY-PCB-MASK in the COBOL Program, you can decide what messages to print, if an error occurs.

The IF-ELSE Block tests Success or Failure of the ISRT Call. When the ISRT Call is successful, the IMS DB Software sets SPACES, in hexadecimal format X'4040', as the Status Code. If the ISRT Call fails, IMS DB Software sets a Non-Blank Status Code.
Q. What does the 700-CLEANUP Routine do?
The 700-CLEANUP Routine is called, during termination of the COBOL Program, to close the INPUT-FILE after all the transactions have been processed.


Saturday, December 18, 2010

Preparing a COBOL-IMS Program

Q. What's the Skeleton of a COBOL-IMS Program?
To write a COBOL-IMS Program and win the battle, you must be armed with two heavy-duty tools – ENTRY and GOBACK Statements in COBOL. In the IMS Environment, it’s the IMS/DB Software that is the supreme Commander-in-Chief. The IMS/DB Software will call your COBOL Program. Your COBOL Program is a sub-program to the IMS/DB Software. The control is transferred to the COBOL Program. ENTRY statement indicates the ENTRY-Point into the COBOL-Program, the position from where the COBOL Program begins to run. The COBOL Program runs, processes data, and generates Output Results. As soon as the GOBACK Statement is encountered, the COBOL Program completes, the control is returned(GOes) BACK to the IMS/DB Software, and the IMS/DB Software again takes over.

This is what any COBOL-IMS Program would have – the ENTRY and GOBACK Statements.


First, IMS/DB Software loads the DBD(database structure information) and the PCB Control-Blocks into Memory. It then sends down the address of the DBD and the PCB Control Blocks to your COBOL Program, and then runs your COBOL Program. These PCB Control-Blocks reside outside the COBOL-Program. Then how does the COBOL Program get access to them, see what's inside these Control Blocks? What you do is, you provide a definition of the PCB in the LINKAGE SECTION of the COBOL Program. The LINKAGE SECTION Definition of the PCB is called PCB-Mask. Via These masks in the COBOL Program, you can access the actual PCB's in Storage. You should list these masks on the ENTRY Statement.

The above picture shows, how I've coded the ENTRY Statement. It specifies 'DLITCBL' as its entry point. And the USING Clause lists the names of the masks in the LINKAGE SECTION.
Q. How do you issue an IMS/DB CALL?
Whenever you would like to perform any operation in IMS, say read the data, update the data etc. you issue a CALL to the IMS/DB Software. This is how you code IMS/DB CALLs. 


You issue an IMS/DB CALL, by coding CALL 'CBLTDLI'. You supply additional parameters on the CALL. I shall broadly describe them here - 

1)The DLI function 
It is the first Input-Parameter to the IMS/DB Software. The DLI-Function indicates to IMS, the operation to be performed on the data, and is a 4-Bytes Code. To add new data to the Database 'ISRT'(Insert) DLI-Function is used. To update data,  'REPL'(Replace) DLI-Function, to erase data, the 'DLET' (Delete) DLI-Function and so on, are used. 


2)The PCB-Mask 
The second parameter on the IMS/DB CALL is the PCB-Mask. PCB-Mask is a common shared communication-area between IMS/DB Software and the COBOL Program. IMS/DB Software returns-back(communicates) important information to the COBOL Program through the PCB Mask.  

After an IMS/DB CALL Executes, how do you know, what's the result of the IMS/DB CALL? Was it successful, or did it fail? After every IMS CALL, the IMS/DB Software sets a 2-Digit Status code, to indicate the success or failure of the operation. The Status Code '  '(SPACES) indicates the IMS CALL was successful. A non-Blank status code like 'GE', indicates that the IMS CALL failed due to some reason. IMS/DB Software stores the two-digit status code in the PCB-Mask.

Here's the picture of the PCB-Mask sent-back to the COBOL Program, after the IMS/DB CALL Executes. As you can see IMS/DB has stored important details in the PCB-Mask. The Status-Code Field is Blank(Spaces), this means the CALL was successful.


Initially before the IMS/DB CALL, the PCB-Mask is Empty. You send the PCB-Mask to the IMS/DB Software. After the IMS/DB CALL executes, IMS/DB Software stores details such as Status-Code etc. in the PCB-Mask.

3)The Segment Input-Output Area
After execution of the IMS/DB CALL, the data-result retrieved from IMS-Database needs to received and stored in some COBOL working-storage field, for processing. While inserting, the data to added to IMS-Database needs to be first stored in some COBOL-Variable, from where it will be sent to IMS. The Segment I-O Area is this Input-Output COBOL-Variable, used for either receiving the Data, when reading from the IMS Database or to send the data, when writing to IMS Database. 

I have coded an IMS/DB CALL to ISRT(Insert) Items-Data into the IMS-Database.
Look, how I have stored the Item-data(00011 SODIUM PALMITATE ...) that I want to insert into the Database in the COBOL-Variable SEGMENT-IO-AREA(a 131-Byte Field).


4)Optional SSA's(Segment-search Arguments).
Optionally, you may supply additional Segment Search Arguments(SSA's).

As you know, an IMS/DB Database is made of several segments e.g. VENDRSEG, ITEMSSEG and STLOCSEG, and every segment has several instances. While fetching data from the IMS database, suppose you would like to filter-out the data. You would like to retrieve only Vendors Data(VENDRSEG). Or you want to fetch only ITEMSSEG(Items) Data. SSA's are used to search or filter data. While inserting, SSA's tell what data are you adding - Vendor Data, Items Data or Stock-Location Data. SSA's are in a way similar to the WHERE Clause of SQL. In the above picture, see how I have specified the SSA('ITEMSSEG ') to indicate, that it is Items-Data, that I am inserting.
Q. What are the different DLI Functions that you can perform on an IMS Database?
Every IMS/DB CALL performs an operation or function on the Database. The DLI Function is the first parameter you code on an IMS/DB CALL. Here is a list of the important DLI Functions, you would use in time to come.


Let me first describe the GU(Get Unique) and GN(Get Next) Functions. The 
GU(Get Unique) Function is used for Random-Retrieval of Data. Say for example, you want to know what is the price for  particular Item Code 00012. You can directly jump to this Item Segment Occurrence by doing a GU. It is like the Standard COBOL READ Statement for Random access.

The GN(Get Next) function is used for the Sequential-Retrieval of Data. Say for example, you would like to traverse through the entire database. You can browse the segment occurrences in sequential(Hierarchical) order one-by-one by executing GN CALLs. It is like the Standard COBOL READ Statement for Sequential Access.

The GNP(Get Next in Parent) function is used to retrieve segment-occurrences sequentially, but under a pre-established Parent. First, you fix the Parent Segment Occurrence. Then you can retrieve all the segment-occurrences under it one-by-one by executing GNP CALLs.

The other three function-codes contain 'H' or Hold. The GHU(Get Hold Unique), the GHN(Get Hold Next) and GHNP(Get Hold Next in Parent) functions are the counterparts of GN, GU and GNP CALLs, which are used to express intent of update. Suppose you are going to update a segment occurrence. First you should retrieve it using a GHN, GHU or GHNP CALL. When you retrieve segment-occurrences with the intent of updating them, you use the Hold CALLs.

The ISRT(Insert) Function, REPL(Replace) Function and DLET(Delete) Function are used to add new Segment Occurrence, update a Segment-Occurrence, or deleting Segment-Occurrence from the Database.
Q. Why code the PCB Mask? Also, how to code the PCB Mask in COBOL?
The second parameter that you supply on the IMS/DB CALL, is the PCB-Mask. The PCB-Mask is the Linkage-Section Definition of the PCB Control-Block. The PCB-Mask has a number of uses.

1. Let's say, a Program accesses three different databases db-1 db-2 and db-3. The Program's PSB would therefore contain three PCB-Macro Statements : pcb-1, pcb-2 and pcb-3, one for each database. Suppose you write an GN(Get Next) CALL Like this -


Since, you have coded PCB-2 on the GN(Get Next) CALL, it implies that the next segment-occurrence in Sequential(Hierarchical) order would be fetched from db-2. Thus, the PCB that you supply on the IMS/DB Call, tells you the database on which the CALL is executed.

2. There are other uses of the PCB-Mask : it is the link between your COBOL Program and the IMS/DB Software. The IMS/DB Software stores a 2-digit status code in the PCB-Mask, to indicate the success or failure of the IMS/DB CALL.

Take a look below, on how to write the COBOL Code for the PCB-Mask. Remember, this goes into the LINKAGE SECTION. It’s a good idea to maintain a separate Mainframe File(Copy-Book) for the PCB-Mask. I have created a Copy-book INVENPCB – that contains the COBOL Code for the Inventory Database PCB. I shall use this PCB Mask, during all IMS/DB CALLs that I execute on the Inventory Database.


Let me reiterate the fact, that after executing the IMS/DB CALL, IMS/DB Software stores important information in the PCB-Mask. These details are :
Database Name : The first field in the PCB-Mask is the name of the Database, that is being processed. It is an 8-Byte Alphanumeric Field. Imagine, executing the GN(Get Next) CALL on the Inventory Database. After execution of the CALL, the Field IPCB-DBD-NAME will contain the value 'INVDBD' – the name of the database(DBD).
Segment-Level : The next field in the PCB-Mask is the hierarchical Level-no of the Segment Occurrence Processed. This is a 2-Byte Alphanumeric Field. After execution of a CALL, stores the Level-Number of the Segment Occurrence processed. For example, if a VENDRSEG(Vendor Data) occurrence is processed, 00 is stored, if a ITEMSSEG(Items Data) occurrence is processed, 01 is stored, and if a STLOCSEG(Stock Data) occurrence is processed, 02 is stored in IPCB-SEGMENT-LEVEL Field.
Status Code : The third field in the PCB-Mask is the Two-Digit Status Code. After a successful call, IMS Software stores the Status-Code in this field. If the CALL is successful, IMS stores SPACES in the Status Code Field.
Processing Options : The fourth field in the PCB-Mask is Processing-Options, a 4-Byte Alphanumeric Field. This field indicates the privileges the program has, what processing is it allowed to do on the Database. The Field Value is populated from the Program's PSB. The next field in the PCB-Mask is a 4-Byte Filler. Defined as S9(05) COMP, it is reserved for IMS Software.
Segment Name : The next field in the PCB-Mask is the Segment-Name, an 8-Byte Alpha-numeric Field. After a successful CALL, IMS Stores the name of the segment-type last processed in this field. For example, upon executing GN CALL, Items Data is retrieved, then 'ITEMSSEG' value will be stored in IPCB-SEGMENT-NAME.
Key-Length : The next field is the Key-Length, a 4-Byte Field. After a successful ISRT or
Get CALL, IMS Software stores the Concatenated-Key of the Segment-Occurrence processed in the Key Feedback-Area. The Length of this Key, is placed in this 4-Byte Field.
Key-Feedback Area : The Key-Feedback Area is a variable-length Field. The Programmer must define the Key-Feedback field large enough to hold any Concatenated-Key, of the Segment processed. The Concatenated-Key of the Segment-Occurrence, is the concatenation of the Key-Value of all the Segment-Occurrences, along the Hierarchical path, starting from the Root-Segment leading to the Segment-Processed.
Q. What's the importance of Segment Input-Output Area in IMS? What should be the size of the Input-Output Area?
The third Parameter that you must supply on the IMS/DB CALL, is the Segment Input-Output Area. It is the COBOL-Variable or Data-Warehouse, used to hold and store the Segment-data received from IMS, or for keeping data that needs to be sent and inserted into IMS. 

The size of this COBOL Variable should be large enough to accommodate the Segment-Data. How to judge(decide) the size of Input-Output Area?

The Inventory-Database is made of three Segments – VENDRSEG(Vendor Data), ITEMSSEG(Item Data) and STLOCSEG(Stock Location Data). Here's a snapshot, of the COBOL-Definition of the VENDRSEG(Vendor Segment). It is 131-Bytes large. The data for one Vendor Segment-Occurrence is of Length 131-Bytes.


The COBOL-Definition of the ITEMSSEG(Item Segment) is shown in the Picture below. The data for one Item Segment-Occurrence is of Length 48-Bytes.


The COBOL-Definition of the STLOCSEG(Stock Location Segment) is shown in the Picture below. The data for one Stock-Location Segment-Occurrence is of Length 21-Bytes.


By comparison, the Largest Segment is the Vendor-Segment. Generally, the thumb-rule followed is, the size of the Segment I-O Area should be equal to the size of the largest Segment(in this case it is the VENDRSEG(Vendor) Segment). Look how, I have coded the SEGMENT-IO-AREA in my COBOL-Program as a 131-Byte Alphanumeric Field.


To many people who are thrown to work at a mainframe computer on their first job, they feel lost. Mainframe people seem to speak a completely different language and that doesn't make life easy. What's more, the books and manuals are incredibly hard to comprehend.

"What on earth is a Mainframe?" is an absolute beginner's guide to mainframe computers. We'll introduce you to the hardware and peripherals. We'll talk about the operating system, the software installed on a mainframe. We'll also talk about the different people who work on a mainframe. In a nutshell, we'll de-mystify the mainframe.

Readers based in India, can buy the e-book for Rs. 50 only or the print book. International readers based in the US and other countries can click here to purchase the e-book.