Showing posts with label DB2. Show all posts
Showing posts with label DB2. Show all posts

Sunday, September 13, 2026

𝗤𝘂𝗶𝗰𝗸𝗹𝘆 𝗘𝘀𝘁𝗶𝗺𝗮𝘁𝗶𝗻𝗴 𝘁𝗵𝗲 𝗦𝗶𝘇𝗲 𝗼𝗳 𝗬𝗼𝘂𝗿 𝗣𝗿𝗼𝗱𝘂𝗰𝘁𝗶𝗼𝗻 𝗗𝗕𝟮 𝗗𝗮𝘁𝗮𝗯𝗮𝘀𝗲𝘀

If all your production DB2 table spaces and index spaces are allocated within a dedicated SMS storage group, determining the approximate size of your production databases becomes a straightforward task.
 
A quick way to estimate the size of your production DB2 databases is by using ISMF (Interactive Storage Management Facility). Navigate to the Storage Group option and examine the storage group dedicated to your production DB2 environment. Pay particular attention to the following metrics:
 
  • Total Space
  • Free Space 

By subtracting the Free Space from the Total Space, you can calculate the used space within the storage group.

Used Space = Total Space − Free Space
 
The resulting value provides a good estimate of the storage currently consumed by your production DB2 databases.

Thursday, July 16, 2026

What Happens When You Run SELECT COUNT(*) on a Large DB2 Table?

To better understand what happens behind the scenes when executing a SELECT COUNT(*) query, I analyzed the two largest tables in our DB2 environment. The goal was to determine whether DB2 counts rows by scanning the table itself or by leveraging one of the available indexes.

Scenario 1: Indexes Larger Than the Table

Table_1 had two indexes, both of which were poorly optimized. A large number of table columns had been included in the indexes, resulting in index sizes that exceeded the size of the base table.

Table_1 Statistics

Metric

Value

Row Count

120,632,075

Average Row Length

95 bytes

Used Pages

3,093,397

Space Utilized

13,631,040 KB

 
Index Statistics
 

Index

Allocated Space (KB)

Leaf Pages

Levels

Avg. Key Length

Index_1

15,730,560

3,655,518

6

101

Index_2

13,633,200

3,165,273

5

84

 
DB2 Optimizer Decision
 
When the following query was executed:
 
SELECT COUNT(*) FROM Table_1 WITH UR;
 
DB2 evaluated the available statistics and determined that scanning the table space was more efficient than scanning either index. Since both indexes were larger than the table itself, the optimizer chose a table scan to perform the row count.
 
Scenario 2: Index Smaller Than the Table
 
Table_2 contained seven indexes. Unlike the first scenario, several of these indexes were significantly smaller than the table space, making them potential candidates for an index-only count operation.
 
Table_2 Statistics

Metric

Value

Row Count

1,006,831,073

Average Row Length

30 bytes

Used Pages

8,078,681

Space Utilized

32,506,560 KB

 
Index Statistics
 

Index

Allocated Space (KB)

Leaf Pages

Levels

Avg. Key Length

Index_1

30,412,080

7,507,065

5

18

Index_2

30,412,080

7,507,065

5

18

Index_3

30,412,080

7,507,065

5

18

Index_4

7,341,840

1,726,625

4

5

Index_5

7,341,840

1,731,545

4

11

Index_6

30,412,080

7,507,065

5

18

Index_7

39,849,840

9,773,348

5

24

 
DB2 Optimizer Decision
 
When the following query was executed:
 
SELECT COUNT(*) FROM Table_2 WITH UR;
 
DB2 analyzed the table and index statistics and selected Index_4 as the access path for the count operation. Because Index_4 was substantially smaller than the table space and contained fewer pages to scan, counting the index entries was more efficient than scanning the entire table.
 
Key Takeaway
 
When executing SELECT COUNT(*), DB2 does not automatically scan the underlying table. Instead, the optimizer evaluates available statistics and chooses the most cost-effective access path.

  • If all indexes are as large as—or larger than—the table, DB2 may perform a table space scan.
  • If a smaller, efficient index exists, DB2 may perform an index scan and count index entries instead.

Friday, July 10, 2026

Coordinating Db2 and MQ Updates Using RRS in a COBOL Batch Program

When a batch COBOL program performs INSERT, UPDATE, or DELETE operations on a Db2 table and also executes MQPUT operations to an IBM MQ queue, the commit/rollback processing becomes more complex.

In such a scenario, issuing a Db2 COMMIT commits only the Db2 changes; it does not commit the MQ messages. Similarly, issuing MQCMIT commits only the MQ operations and has no effect on pending Db2 updates. Each resource manager commits its own work independently but does not coordinate with other resource managers.

This is where Resource Recovery Services (RRS) becomes essential.

RRS acts as a central transaction coordinator for resource managers such as Db2 and IBM MQ. When an application requests a commit or rollback, RRS coordinates all participating resource managers using the standard two-phase commit protocol, ensuring that updates across all resources are committed or rolled back as a single unit of work.

The following sample COBOL program updates both Db2 and MQ resources and uses the RRS services to commit the changes atomically.

Unlike a traditional batch Db2 COBOL program, an application that uses RRS must explicitly establish and terminate the Db2 connection and thread within the program itself.

When we compile the program, we need to add "ATTACH(RRSAF)" option in the DB2 precompiler step. This instructs Db2 to use the RRS Attachment Facility (RRSAF) for transaction coordination.

After doing all the DB2, MQ updates, COBOL program need to invoke RSS API "SRRCMIT" to initiate the two phase COMMIT process.     

The following RSS Adapter/stub modules must be link-edited to the COBOL module:

CSQBRSTB - MQ RRS Adapter available in MQ SCSQLOAD library
DSNRLI   - DB2 RRS Adapter available in Db2 SDSNLOAD library
ATRSCSS  - available in SYS1.CSSLIB library

Since the COBOL program explicitly manages the Db2 connection through RRSAF, it can be executed like a regular Batch COBOL program.

Below is the sample run JCL.

//STEP01 EXEC PGM=DB2MQPGM,                              
//STEPLIB  DD DSN=xxxx.DB2.SDSNEXIT,DISP=SHR          
//         DD DSN=xxxx.DB2.SDSNLOAD,DISP=SHR          
//         DD DSN=xxxx.MQ.SCSQANLE,DISP=SHR            
//         DD DSN=xxxx.MQ.SCSQAUTH,DISP=SHR            
//         DD DSN=USER.LOADLIB,DISP=SHR                  
//*                                                      
//SYSOUT   DD SYSOUT=*                                    

Below is the sample COBOL program that invoke RRS services to commit the changes in both DB2 and MQ.

       IDENTIFICATION DIVISION.
       PROGRAM-ID.    DB2MQPGM.
       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01 RRSAF-FIELDS.
      * DB2 subsystem name for IDENTIFY
           05 SSNM          PIC X(04).
      * Correlation ID for SIGNON
           05 CORRID        PIC X(12).
      * Accounting token for SIGNON
           05 ACCTTKN       PIC X(22).
      * Accounting interval for SIGNON
           05 ACCTINT       PIC X(06).
      * DB2 plan name for CREATE THREAD
           05 PLAN          PIC X(08).
      * Collection ID for CREATE THREAD.
      * IF PLAN contains a plan name, not used.
           05 COLLID        PIC X(18).
      * Controls SIGNON after CREATE THREAD
           05 REUSE         PIC X(08).
      *  Action that application takes based
      *  on return code from RRSAF
           05 CONTROL1      PIC X(08).
      ****************** VARIABLES SET BY DB2 *******************************
      *  DB2 startup ECB
           05 STARTECB      PIC X(04).
      *  DB2 termination ECB
           05 TERMECB       PIC X(04).
      *  Address of environment info block
           05 EIBPTR        PIC X(04).
      *  Address of release info block
           05 RIBPTR        PIC X(04).
      ****************************** CONSTANTS ******************************
      * CONTROL value: Everything OK
           05 CONTINUE1     PIC X(08) VALUE 'CONTINUE'.
      * Name of RRSAF servicS
           05 IDFYFN        PIC X(18) VALUE 'IDENTIFY'.
           05 SGNONFN       PIC X(18) VALUE 'SIGNON'.
           05 CRTHRDFN      PIC X(18) VALUE 'CREATE THREAD'.
           05 TRMTHDFN      PIC X(18) VALUE 'TERMINATE THREAD'.
           05 TMIDFYFN      PIC X(18) VALUE 'TERMINATE IDENTIFY'.
           05 XLATFN        PIC X(18) VALUE 'TRANSLATE'.
           05 RETCODE       PIC X(04).
           05 REASCODE      PIC X(04).

       01  WS-WORK-AREAS.
           05  WS-ERROR-CODE            PIC S9(04)  VALUE ZEROS COMP.
           05  PROCESS-REC-COUNT        PIC S9(4) COMP.

       01 WS-SQLCODE                      PIC ----9.
           EXEC SQL
             INCLUDE SQLCA
           END-EXEC.

        01 OUT-MSG-LEN              PIC S9(9) COMP.

        01 MQ-Q-NAME              PIC X(48)      VALUE SPACES.
        01 MQ-HOBJ                PIC S9(9) COMP VALUE 0.
        01 MQ-OPEN-OPTS           PIC S9(9) COMP VALUE 0.
        01 MQ-CLOSE-OPTS          PIC S9(9) COMP VALUE 0.

        01 MQ-CONSTANTS.
            COPY CMQV.
        01 MQ-OBJ-DESC.
            COPY CMQODV.
        01 MQ-MSG-DESC.
            COPY CMQMDV.
        01 MQ-PUT-MSG-OPTS.
            COPY CMQPMOV.
        01 MQ-GET-MSG-OPTS.
            COPY CMQGMOV.

      * -------------------------------------------------------
      * Queue manager connection name and handle...
      * -------------------------------------------------------
        01 MQ-QM-NAME               PIC X(48)      VALUE SPACES.
        01 MQ-HCONN                 PIC S9(9) COMP-5.
        01 MQ-PROC                  PIC X(08).

      * -------------------------------------------------------
      * Queue manager op return codes and like things...
      * -------------------------------------------------------
        01 MQ-RETURN-STUFF.
            10 MQ-RC                PIC S9(9) COMP VALUE 0.
            10 MQ-RC-N9             PIC 9(9)       VALUE 0.
            10 MQ-RSN               PIC S9(9) COMP VALUE 0.
            10 MQ-RSN-N9            PIC 9(9)       VALUE 0.
            10 MQ-MSG               PIC X(256)     VALUE SPACES.

       PROCEDURE DIVISION.
       0000-MAINLINE.

           PERFORM 1000-INITIALIZATION
              THRU 1000-INITIALIZATION-EXIT.

           PERFORM 2000-PROCESS
              THRU 2000-EXIT
             VARYING PROCESS-REC-COUNT FROM 1 BY 1
             UNTIL PROCESS-REC-COUNT > 100

           PERFORM 3000-TERMINATION
              THRU 3000-TERMINATION-EXIT.

       0000-MAINLINE-EXIT.
           GOBACK.

       1000-INITIALIZATION.

           MOVE 'XXXX'     TO MQ-QM-NAME.
           MOVE 'TEST.MQ'  TO MQ-Q-NAME.

           CALL 'MQCONN' USING
                MQ-QM-NAME
                MQ-HCONN
                MQ-RC
                MQ-RSN

           IF MQ-RC = MQCC-FAILED
              MOVE 'MQCONN'    TO MQ-PROC
              GO TO 999-ERROR
           END-IF.

           MOVE MQOO-OUTPUT            TO MQ-OPEN-OPTS
           ADD  MQOO-FAIL-IF-QUIESCING TO MQ-OPEN-OPTS
           MOVE MQOT-Q    TO MQOD-OBJECTTYPE
           MOVE MQ-Q-NAME TO MQOD-OBJECTNAME

           CALL 'MQOPEN' USING
               MQ-HCONN
               MQ-OBJ-DESC
               MQ-OPEN-OPTS
               MQ-HOBJ
               MQ-RC
               MQ-RSN

           IF MQ-RC = MQCC-FAILED
              MOVE 'MQOPEN'    TO MQ-PROC
              GO TO 999-ERROR
           END-IF.

      ****************************** IDENTIFY **********************
           MOVE 'DB2A' TO SSNM
           CALL  'DSNRLI' USING
                  IDFYFN SSNM RIBPTR EIBPTR TERMECB STARTECB
                  RETCODE REASCODE
           IF RETCODE NOT = LOW-VALUES
              DISPLAY IDFYFN RETCODE REASCODE
              CALL  'DSNRLI' USING XLATFN SQLCA RETCODE REASCODE
              MOVE SQLCODE   TO WS-SQLCODE
              DISPLAY ' IDENTIFY ' WS-SQLCODE SQLERRM
           END-IF
      ***************************** SIGNON *************************
           CALL  'DSNRLI' USING
                  SGNONFN CORRID ACCTTKN ACCTINT
                  RETCODE REASCODE
           IF RETCODE NOT = LOW-VALUES
              DISPLAY SGNONFN RETCODE REASCODE
              CALL  'DSNRLI' USING XLATFN SQLCA RETCODE REASCODE
              MOVE SQLCODE   TO WS-SQLCODE
              DISPLAY 'SIGNON    ' WS-SQLCODE SQLERRM
           END-IF
      *************************** CREATE THREAD ********************
           MOVE 'TESTPLAN' TO PLAN
           CALL  'DSNRLI' USING
                  CRTHRDFN PLAN COLLID REUSE
                  RETCODE REASCODE.
           IF RETCODE NOT = LOW-VALUES
              DISPLAY CRTHRDFN RETCODE REASCODE
              CALL  'DSNRLI' USING XLATFN SQLCA RETCODE REASCODE
              MOVE SQLCODE   TO WS-SQLCODE
              DISPLAY 'CRE THRD  ' WS-SQLCODE SQLERRM
           END-IF.

       1000-INITIALIZATION-EXIT.
           EXIT.

       2000-PROCESS.

           EXEC SQL
               INSERT INTO TEST_TABLE
               ..............
               ..............  
           END-EXEC
 
           IF SQLCODE NOT = ZERO
              MOVE SQLCODE   TO WS-SQLCODE
              DISPLAY ' INSERT FAILED ' WS-SQLCODE
              PERFORM 9000-ABEND THRU 9000-ABEND-EXIT
           END-IF.

           COMPUTE MQPMO-OPTIONS
                 = MQPMO-FAIL-IF-QUIESCING
                 + MQPMO-SYNCPOINT

           MOVE LENGTH OF DATA-TO-BE-INSERTED
              TO OUT-MSG-LEN

           CALL 'MQPUT' USING
                MQ-HCONN
                MQ-HOBJ
                MQ-MSG-DESC
                MQ-PUT-MSG-OPTS
                OUT-MSG-LEN
                DATA-TO-BE-INSERTED
                MQ-RC
                MQ-RSN

           IF MQ-RC = MQCC-FAILED
              MOVE 'MQPUT'     TO MQ-PROC
              GO TO 999-ERROR
           END-IF.

       2000-EXIT.
           EXIT.


       3000-TERMINATION.

           CALL 'SRRCMIT' USING RETCODE
           DISPLAY 'SRRCMIT : ' RETCODE
      *    call 'SRRBACK' USING RETCODE
      *    DISPLAY 'SRRBACK : ' RETCODE

           CALL 'MQCLOSE' USING
               MQ-HCONN
               MQ-HOBJ
               MQ-CLOSE-OPTS
               MQ-RC
               MQ-RSN.

           IF MQ-RC = MQCC-FAILED
              DISPLAY 'MQCLOSE'
              DISPLAY 'MQ-RC: ' MQ-RC
           END-IF.

            CALL 'MQDISC' USING
                 MQ-HCONN
                 MQ-RC
                 MQ-RSN.

           IF MQ-RC = MQCC-FAILED
              DISPLAY 'MQDISC'
              DISPLAY 'MQ-RC: ' MQ-RC
           END-IF.

      ************************ TERMINATE THREAD ***********************
            CALL  'DSNRLI' USING TRMTHDFN
                   RETCODE REASCODE
            IF RETCODE NOT = LOW-VALUES
               DISPLAY TRMTHDFN RETCODE REASCODE
               CALL  'DSNRLI' USING XLATFN SQLCA RETCODE REASCODE
               MOVE SQLCODE   TO WS-SQLCODE
               DISPLAY 'TRM THRD  ' WS-SQLCODE SQLERRM
            END-IF.
      ************************ TERMINATE IDENTIFY *********************
            CALL  'DSNRLI' USING TMIDFYFN
                   RETCODE REASCODE.
            IF RETCODE NOT = LOW-VALUES
               DISPLAY TMIDFYFN RETCODE REASCODE
               CALL  'DSNRLI' USING XLATFN SQLCA RETCODE REASCODE
               MOVE SQLCODE   TO WS-SQLCODE
               DISPLAY 'TRM IDNTY ' WS-SQLCODE SQLERRM
            END-IF.

       3000-TERMINATION-EXIT.
           EXIT.


       9000-ABEND.

           CALL 'ILBOABN0' USING WS-ERROR-CODE.

       9000-ABEND-EXIT.
           EXIT.

       999-ERROR.
           MOVE MQ-RSN    TO MQ-RSN-N9
           DISPLAY 'MQ-PROC: ' MQ-PROC
           DISPLAY 'MQ-RSN : ' MQ-RSN-N9
           GOBACK.

Sunday, June 28, 2026

Uncovering the Hidden Cause: A Db2 -911 Error That Silently Broke Data Consistency

Back in 2009, I was working as a Mainframe Consultant for a leading healthcare insurance company. The client’s system architecture was heavily based on CICS, with around 18 production regions handling healthcare claim adjudication. Each region was responsible for processing claims from specific parts of the United States and ran multiple background tasks simultaneously.

At that time, claim data was primarily stored in VSAM KSDS files, with each CICS region maintaining its own dataset. These records were quite large—around 18 KB each—and contained both the original claim data and the derived or calculated information generated during processing.

Around 2006–2007, the client has introduced Db2 into the claim processing flow. The monolithic VSAM structure was normalized into approximately 12 Db2 tables. These tables were split similarly into two logical groups—one for original claim details and another for derived data. Unlike VSAM, the Db2 tables were shared across all CICS regions, rather than being region-specific.

However, to minimize risk, the organization continued to treat VSAM as the primary data source, with Db2 acting as a shadow repository.

The claim processing flow remained largely unchanged: the system would read the VSAM record at the start, cache it in memory, process it across multiple programs, and finally write the updated data back to VSAM. With Db2 integration, additional SELECT, INSERT, and UPDATE statements were introduced throughout the processing steps to keep Db2 in sync with the cached data.

After deploying these changes to production, application SMEs observed inconsistencies—certain claims had missing or incomplete data in Db2 tables. Interestingly, the issue was not consistent; different tables were affected for different claims. Instead of investigating the root cause, a reconciliation batch job was implemented. This job compared VSAM records against Db2 and corrected discrepancies by inserting or updating missing data.

In 2009, I was assigned to debug a production issue related to claim processing. I set up an Xpediter session and carefully traced the execution of a claim through the system.

During debugging, I encountered a recurring Db2 SQL error: SQLCODE -911, which indicates a rollback due to a deadlock or timeout. I continued the session and noticed that, after processing, certain Db2 tables were missing data for the same claim.

This was a critical observation. The -911 error triggers a rollback, which means any previous INSERT or UPDATE operations in that logical unit of work are undone.

Further analysis revealed that the application had retry logic for handling SQLCODE -911. Whenever this error occurred, the program would retry the same SQL statement up to five times. If any retry succeeded, processing would continue as if nothing had happened.

The problem?

This retry logic was implemented for SELECT statements.

As a result:

  • A -911 error would roll back prior updates toDb2 tables.
  • A subsequent successful retry (on a SELECT) allowed processing to continue.

This led to partial or missing data in Db2 tables.

This flaw had gone unnoticed for nearly two years after Db2 integration.

When I presented my findings to the application SMEs, there was initial skepticism, partly because I was relatively new to the team. However, I substantiated the findings using official Db2 documentation explaining SQLCODE -911.

Eventually, the team acknowledged the root cause. The resolution involved significant changes to remove inappropriate retry logic and ensure proper handling of transactional failures.

This experience reinforced an important lesson:

Retry mechanisms must be carefully designed—especially in transactional systems—otherwise, they can silently introduce data inconsistencies.

Thursday, May 14, 2026

DB2 SQL to find tables used by a program

Below SQL to returns the list of tables used by a latest version of a program 

WITH TEMP(COLLID, NAME, CONTOKEN) AS(                    
     SELECT COLLID, NAME, CONTOKEN                       
     FROM SYSIBM.SYSPACKAGE                              
     WHERE (LOCATION,COLLID,NAME,BINDTIME) IN (          
           SELECT LOCATION,COLLID,NAME,MAX(BINDTIME)     
           FROM SYSIBM.SYSPACKAGE                        
           WHERE NAME = 'program_name'                       
          GROUP BY LOCATION,COLLID,NAME                  
       )                                                 
)                                                        
SELECT SUBSTR(T.NAME,1,8) AS PROGRAM,                    
SUBSTR(BQUALIFIER,1,8) AS QUALIFIER,                     
 SUBSTR(BNAME,1,30) AS TBL_NAME,                         
 BTYPE                                                   
 FROM SYSIBM.SYSPACKDEP,TEMP T                           
WHERE DCOLLID = T.COLLID                                 
 AND  DNAME   =  T.NAME                                  
 AND  DCONTOKEN = T.CONTOKEN                             
 AND BTYPE = 'T'                                         
WITH UR;                                                 

Wednesday, March 15, 2023

How to use COBOL occurs depending on working storage section table in a SQL query

Let us say we have below COBOL working storage section table and we want to match all the employee numbers from this array to a DB2 table.

01 W-EMP-COUNT   PIC S9(04) COMP.
01 W-EMP-LIST.
   05 W-EMP-NUM OCCURS 1 TO 50 TIMES DEPENDING ON W-EMP-COUNT
                 PIC X(05).

Below SQL does exactly that 

WITH TEMP(IDX, T_EMP_NUM) AS 
(SELECT 1, LEFT(:W-EMP-LIST,5)
     FROM SYSIBM.SYSDUMMY1 
   UNION ALL
SELECT IDX+1, SUBSTR(:W-EMP-LIST,((IDX)*5)+1,5)
     FROM TEMP
 WHERE IDX < :W-EMP-COUNT
),
SELECT * FROM EMP_TABLE, TEMP 
    WHERE EMP_NO  = EMP_NUM;

Wednesday, February 16, 2022

COBOL program to process SMF 101 Accounting data

Below COBOL program processes SMF 101 Accounting data. The program was written for DB2 12 version.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SMF101.
       AUTHOR.   
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
            SELECT SMFDATA ASSIGN TO SMFDATA
            ORGANIZATION SEQUENTIAL.
            SELECT RPT-FILE ASSIGN TO RPTFILE
            ORGANIZATION SEQUENTIAL.
       DATA DIVISION.
       FILE SECTION.
       FD SMFDATA
            LABEL RECORDS ARE STANDARD
            RECORDING MODE IS S
            BLOCK CONTAINS 32760 CHARACTERS
            RECORD IS VARYING FROM 18 TO 32756
            DEPENDING ON WS-LEN.
       01 SMFDATA-MIN-RECORD    PIC X(18).
       01 SMFDATA-MAX-RECORD    PIC X(32756).
       FD RPT-FILE
           LABEL RECORDS ARE STANDARD.
       01 RPT-FILE-REC         PIC X(80).
       WORKING-STORAGE SECTION.
       01 WS-REC.
          05 F-STRDATE          PIC 9(5).
          05 FILLER             PIC X VALUE SPACE.
          05 F-STRTIME.
             10 F-STRTIME-HH    PIC 99.
             10 FILLER          PIC X VALUE ':'.
             10 F-STRTIME-MM    PIC 99.
             10 FILLER          PIC X VALUE ':'.
             10 F-STRTIME-SS    PIC 99.
          05 FILLER             PIC X VALUE SPACE.
          05 F-JOBNAME          PIC X(8).
          05 FILLER             PIC X VALUE SPACE.
          05 F-CONNECT          PIC X(8).
          05 FILLER             PIC X VALUE SPACE.
          05 CONN-TYPE          PIC X(10).
          05 FILLER             PIC X VALUE SPACE.
          05 F-QWHCAID          PIC X(8).
          05 FILLER             PIC X VALUE SPACE.
          05 F-PLAN             PIC X(8).
          05 FILLER             PIC X VALUE SPACE.
          05 F-TCB              PIC ZZZZZ9.9(5).
          05 FILLER             PIC X VALUE SPACE.
          05 DB2CPU             PIC ZZZZZ9.9(5).
       01 WS-SMF-RECNO          PIC 9(6) COMP VALUE 0.
       01 BIN4-32768            PIC 9(8) COMP VALUE 32768 SYNC.
       01 SMF00-PNTR USAGE IS POINTER SYNC.
       01 SMF00-ADDRVAL REDEFINES SMF00-PNTR
                                PIC S9(9) COMP.
       01 SMF101RPS-PNTR USAGE IS POINTER SYNC.
       01 SMF101RPS-ADDRVAL REDEFINES SMF101RPS-PNTR
                                PIC S9(9) COMP.
       01 DSNDQWHS-PNTR USAGE IS POINTER SYNC.
       01 DSNDQWHS-ADDRVAL REDEFINES DSNDQWHS-PNTR
                                PIC S9(9) COMP.
       01 DSNDQWAC-PNTR USAGE IS POINTER SYNC.
       01 DSNDQWAC-ADDRVAL REDEFINES DSNDQWAC-PNTR
                                PIC S9(9) COMP.
       01 DSNDQWHC-PNTR USAGE IS POINTER SYNC.
       01 DSNDQWHC-ADDRVAL REDEFINES DSNDQWHC-PNTR
                                PIC S9(9) COMP.
       01 END-OF-FILE-FLAG      PIC X VALUE 'N'.
          88 END-OF-FILE        VALUE 'Y'.
       01 WS-VARS.
          02 PROGRAM-NAME       PIC X(8).
          02 CUTOFF-CPU-TIME    PIC 9V99 VALUE 1.00.
          02 TOT-INDB2-ELAP     PIC 9(15)V99.
          02 TOT-DB2-CPU        PIC 9(9)V9(5) COMP.
          02 TCB-TIME           PIC 9(9)V9(5) COMP.
          02 TEMP-HOURS         PIC 9(9) COMP.
          02 TEMP-MIN           PIC 9(9) COMP.
          02 TEMP-SECS          PIC 9(9) COMP.
          02 WS-CNT             PIC 9(4) COMP.
          02 WS-LEN             PIC 9(9) COMP.
       01 WS-SMF-REC.
          05 WS-CHAR OCCURS 1 TO 32756 DEPENDING ON WS-LEN
                                PIC X(01).
       LINKAGE SECTION.
       01 SMF101RPS.
      ** HEADER FOR TYPE 101 RECORD
           02 SMF101RHD.
             03 SMF101FLG       PIC X(1).
             03 SMF101RTY       PIC X(1).
             03 SMF101TME       PIC 9(9) COMP.
             03 SMF101DTE       PIC 9(7) COMP-3.
             03 SMF101SID       PIC X(4).
             03 SMF101SSI       PIC X(4).
             03 SM101STF        PIC 9(04) COMP.
             03 FILLER          PIC X(4).
      ** SELF-DEFINING SECTION OF TYPE 101 RECORD
           02 DSNDQWA0.
             03 QWA01PSO        PIC 9(9) COMP.
             03 QWA01PSL        PIC 9(4) COMP.
             03 QWA01PSN        PIC 9(4) COMP.
             03 QWA01R1O        PIC 9(9) COMP.
             03 QWA01R1L        PIC 9(4) COMP.
             03 QWA01R1N        PIC 9(4) COMP.
             03 QWA01R2O        PIC 9(9) COMP.
             03 QWA01R2L        PIC 9(4) COMP.
             03 QWA01R2N        PIC 9(4) COMP.
             03 QWA01R3O        PIC 9(9) COMP.
             03 QWA01R3L        PIC 9(4) COMP.
             03 QWA01R3N        PIC 9(4) COMP.
             03 QWA01R4O        PIC 9(9) COMP.
             03 QWA01R4L        PIC 9(4) COMP.
             03 QWA01R4N        PIC 9(4) COMP.
             03 QWA01R5O        PIC 9(9) COMP.
             03 QWA01R5L        PIC 9(4) COMP.
             03 QWA01R5N        PIC 9(4) COMP.
             03 QWA01R6O        PIC 9(9) COMP.
             03 QWA01R6L        PIC 9(4) COMP.
             03 QWA01R6N        PIC 9(4) COMP.
             03 QWA01R7O        PIC 9(9) COMP.
             03 QWA01R7L        PIC 9(4) COMP.
             03 QWA01R7N        PIC 9(4) COMP.
             03 QWA01R8O        PIC 9(9) COMP.
             03 QWA01R8L        PIC 9(4) COMP.
             03 QWA01R8N        PIC 9(4) COMP.
             03 QWA01R9O        PIC 9(9) COMP.
             03 QWA01R9L        PIC 9(4) COMP.
             03 QWA01R9N        PIC 9(4) COMP.
      *
      *****************************************************************
      * PRODUCT DATA SECTION
      * INSTRUMENTATION STANDARD HEADER
      ****************************************************************
      *
       01 DSNDQWHS.
         02 QWHSLEN             PIC 9(4) COMP.
         02 QWHSTYP             PIC X(1).
            88 STANDARD-HEADER         VALUE X'01'.
*******     88 TRACE-HEADER            VALUE X'04'.
*******     88 CPU-HEADER              VALUE X'08'.
*******     88 DISTRIBUTED-HEADER      VALUE X'10'.
*******     88 DATA-SHARING-HEADER     VALUE X'20'.
         02 QWHSRMID            PIC X(1).
         02 QWHSIID             PIC 9(4) COMP.
         02 QWHSNSDA            PIC X(1).
         02 QWHSSRN             PIC X(1).
         02 QWHSACE             PIC 9(9) COMP.
      * SUBSYSTEM NAME
         02 QWHSSSID            PIC X(4).
         02 QWHSSTCK.
            03 QWHSSC1          PIC 9(9) COMP.
            03 QWHSSC2          PIC 9(9) COMP.
         02 QWHSISEQ            PIC 9(9) COMP.
         02 QWHSWSEQ            PIC 9(9) COMP.
         02 QWHSMTN             PIC X(4).
         02 QWHSLOCN            PIC X(16).
         02 QWHSNID             PIC X(8).
         02 QWHSLUNM            PIC X(8).
         02 QWHSLUUV            PIC X(6).
         02 QWHSLUCC            PIC 9(4) COMP.
         02 QWHSFLAG            PIC X.
       01 DSNDQWHC.
      * CORELATION HEADER
         02 QWHCLEN             PIC 9(4) COMP.
         02 QWHCTYP             PIC X.
            88 CORRELATION-HEADER      VALUE X'02'.
         02 FILLER              PIC X.
      * %U AUTHORIZATION ID
      *   Truncated if QWHCAID_Off¬=0
         02 QWHCAID             PIC X(8).
      *CORRELATION VALUE
         02 QWHCCV              PIC X(12).
      *CONNECTION NAME (NOT VALID ON EOM REFLECTS THE MVS HOME ASID
      *CONNECTION NAME
         02 QWHCCN              PIC X(8).
      * PLAN NAME     (BIND NAME)
         02 QWHCPLAN            PIC X(8).
      * %U ORIGINAL OPERATOR ID
      *   Truncated if QWHCOPID_Off¬=0
         02 QWHCOPID            PIC X(8).
      *CONNECTING SYSTEM TYPE CODE
         02 QWHCATYP            PIC 9(9) COMP.
            88 TSO-OR-BATCH                VALUE   1.
            88 DB2-CALL-ATTACH             VALUE   2.
            88 DLI-BATCH                   VALUE   3.
            88 CICS-ATTACH                 VALUE   4.
            88 IMS-ATTACH-BMP              VALUE   5.
            88 IMS-ATTACH-MPP              VALUE   6.
            88 DB2-PRIVATE-PROTOCOL        VALUE   7.
            88 DRDA                        VALUE   8.
            88 IMS-CONTROL-REGION          VALUE   9.
            88 IMS-TRANSACTION-BMP         VALUE  10.
            88 DB2-UTILITIES               VALUE  11.
            88 RRSAF-ATTACH                VALUE  12.
      *********************************************************
      **** ACCOUNTING DATA
      *********************************************************
       01 DSNDQWAC.
          02 QWACBSC            pic x(8).
          02 QWACESC            pic x(8).
          02 QWACBJST           PIC 9(18) COMP-5.
          02 QWACEJST           PIC 9(18) COMP-5.
          02 QWACBSRB           PIC 9(18) COMP-5.
          02 QWACESRB           PIC 9(18) COMP-5.
          02 QWACRINV           PIC 9(9) COMP.
          02 QWACNID            PIC X(16).
          02 QWACCOMM           PIC 9(9) COMP.
          02 QWACABRT           PIC 9(9) COMP.
          02 QWCA1.
             03 QWACASC         PIC 9(18) COMP-5.
             03 QWACAJST        PIC 9(18) COMP-5.
             03 QWACASRB        PIC 9(18) COMP-5.
             03 QWACAWTI        PIC 9(18) COMP-5.
             03 QWACAWTL        PIC 9(18) COMP-5.
             03 QWACARNA        PIC 9(9) COMP.
             03 QWACARNE        PIC 9(9) COMP.
       PROCEDURE DIVISION.
       0000-MAINLINE.
           PERFORM 1000-INITIALIZE
           PERFORM UNTIL END-OF-FILE
              READ SMFDATA
              AT END MOVE 'Y' TO END-OF-FILE-FLAG
              END-READ
              IF NOT END-OF-FILE
                 MOVE SMFDATA-MAX-RECORD (1:WS-LEN)
                   TO WS-SMF-REC(1:WS-LEN)
                 SET ADDRESS OF SMF101RPS
                   TO ADDRESS OF WS-SMF-REC
                 SET SMF101RPS-PNTR
                   TO ADDRESS OF WS-SMF-REC
                 IF SMF101RTY = X'65' AND
                    SM101STF  = ZEROS
                    ADD 1 TO WS-SMF-RECNO
      *** 4 IS SUBTRACTED AS RDW IS NOT INCLUDED IN OUR RECORD
                    COMPUTE DSNDQWHS-ADDRVAL = SMF101RPS-ADDRVAL
                                               + QWA01PSO - 4
                    SET ADDRESS OF DSNDQWHS TO DSNDQWHS-PNTR
                    IF QWHSIID = 03
******** IFCID = 03 - Gen. Accounting data - processed
                       COMPUTE DSNDQWHC-ADDRVAL = DSNDQWHS-ADDRVAL
                                                  + QWHSLEN
                       SET ADDRESS OF DSNDQWHC TO DSNDQWHC-PNTR
                       IF CORRELATION-HEADER
                          PERFORM 2000-TYPE101-PROCESS
                       END-IF
                    END-IF
                 END-IF
              END-IF
           END-PERFORM.
           CLOSE SMFDATA.
           CLOSE RPT-FILE.
           GOBACK.
       1000-INITIALIZE.
           OPEN INPUT SMFDATA.
           OPEN OUTPUT RPT-FILE.
       2000-TYPE101-PROCESS.
           MOVE SMF101DTE     TO F-STRDATE
           PERFORM 2100-CONVERT-TIME
           MOVE TEMP-HOURS    TO F-STRTIME-HH
           MOVE TEMP-MIN      TO F-STRTIME-MM
           MOVE TEMP-SECS     TO F-STRTIME-SS
           MOVE QWHCCN        TO F-CONNECT
           MOVE QWHCCV        TO F-JOBNAME
           MOVE QWHCPLAN      TO F-PLAN
           MOVE QWHCAID       TO F-QWHCAID
           MOVE 0             TO TOT-INDB2-ELAP ,
                                 TOT-DB2-CPU
           COMPUTE DSNDQWAC-ADDRVAL = SMF101RPS-ADDRVAL + QWA01R1O - 4
           SET ADDRESS OF DSNDQWAC TO DSNDQWAC-PNTR
           PERFORM 3000-COMPUTE-TIMES QWA01R1N TIMES
********   COMPUTE TOT-INDB2-ELAP =
********   (TOT-INDB2-ELAP / 4096000000.0) + 0.005
           COMPUTE TOT-DB2-CPU =  TOT-DB2-CPU / 4096000000
********   MOVE TOT-INDB2-ELAP TO DB2ELAP
           MOVE TOT-DB2-CPU    TO DB2CPU
           COMPUTE TCB-TIME = (QWACEJST - QWACBJST)/ 4096000000
           MOVE TCB-TIME       TO F-TCB
           EVALUATE TRUE
              WHEN TSO-OR-BATCH
                   MOVE 'BATCH'            TO CONN-TYPE
              WHEN DB2-CALL-ATTACH
                   MOVE 'DB2CALL'          TO CONN-TYPE
              WHEN DLI-BATCH
                   MOVE 'DLI'              TO CONN-TYPE
              WHEN CICS-ATTACH
                   MOVE 'CICS'             TO CONN-TYPE
              WHEN IMS-ATTACH-BMP
                   MOVE 'IMSBMP'           TO CONN-TYPE
              WHEN IMS-ATTACH-MPP
                   MOVE 'IMSMPP'           TO CONN-TYPE
              WHEN DB2-PRIVATE-PROTOCOL
                   MOVE 'DB2PRIVA'         TO CONN-TYPE
              WHEN DRDA
                   MOVE 'DRDA'             TO CONN-TYPE
              WHEN IMS-CONTROL-REGION
                   MOVE 'IMSCTL'           TO CONN-TYPE
              WHEN IMS-TRANSACTION-BMP
                   MOVE 'IMSTRANBMP'       TO CONN-TYPE
              WHEN DB2-UTILITIES
                   MOVE 'DB2UTIL'          TO CONN-TYPE
              WHEN RRSAF-ATTACH
                   MOVE 'RRSAF'            TO CONN-TYPE
           END-EVALUATE.
           WRITE RPT-FILE-REC FROM WS-REC.
       2100-CONVERT-TIME.
           COMPUTE TEMP-HOURS = SMF101TME / 360000
           COMPUTE TEMP-MIN =
           (SMF101TME - (TEMP-HOURS * 360000)) / 6000
           COMPUTE TEMP-SECS = (SMF101TME - (TEMP-HOURS * 360000) -
           (TEMP-MIN * 6000)) / 100 .
       3000-COMPUTE-TIMES.
*******    COMPUTE TOT-INDB2-ELAP = TOT-INDB2-ELAP + QWACASC
           COMPUTE TOT-DB2-CPU = TOT-DB2-CPU + QWACAJST + QWACASRB
           COMPUTE DSNDQWAC-ADDRVAL = DSNDQWAC-ADDRVAL + QWA01R1L
           SET ADDRESS OF DSNDQWAC TO DSNDQWAC-PNTR.
       3000-EXIT.
           EXIT.