Precompilation Process
Summary
SQL (Structured Query Language) is used to retrieve the data from the database (DB2).
In order to retrieve the data from DB2 from the application program, SQL queries are required to be coded in the program. The SQL queries should code between EXEC SQL and END-EXEC to identify quickly and get separated from the application program language.
Suppose the SQL queries are not coded between EXEC SQL and END-EXEC. In that case, the COBOL compiler tries to recognize them as COBOL statements and throws the compilation error because they are not.
The compilation process of application language(COBOL, PL/I, etc.,) and DB2 (SQL queries) is called as Precompilation Process.
The compilation process of COBOL + DB2 Program (Precompilation process) -
The compilation process of the COBOL + DB2 program is different from the simple COBOL program compilation.
If the program has DB2 statements, then we should add the precompiler step to the compilation JCL. i.e., the Precompilation JCL = Precompile step + COBOL Compile JCL
.
Diagram -
PRECOMPILER -
- Precompiler is mainly responsible for dividing the COBOL, DB2 statements separately.
- Precompiler takes the COBOL + DB2 source code as an input and separates the COBOL, DB2 statements to the two different libraries (COBOL Loadlib and DBRM).
- Precompiler is responsible for checking the syntax errors of DB2 statements before placing them in DBRM (DataBase Request Module).
- Precompiler doesn't check the syntax errors of COBOL statements or any other programming language(PL/I etc.) statements.
- The precompiler is used to generate timestamp tokens for each (COBOL and DB2) as specified in the diagram and these are validated while BINDing the program.
DBRM (DataBase Request Module) -
- DBRM is DataBase Request Module where syntax-free (syntax verified) SQL statements are stored.
- DBRM library is a user-defined PDS and syntax-free SQL statements stores with the program name.
BIND -
BIND is the process to find the optimized access path to retrieve the data from the DB2 for the SQLs coded in the program.
BIND takes DBRM as input and generates the optimized access path with the help of an optimizer that considers the below factors.
- Table size
- Number of columns retrieving
- Number of rows retrieving
- The availability of primary key
- The availability of Foreign key
- And many more.
The Utility used for BIND is IKJEFT01. BIND is used to specify isolation levels.
BIND process also checks some of the syntax errors of DB2 statements. For Example - Whenever we use the GROUP BY and ORDER BY clause, we get a BIND error if we can't specify the column in SELECT.
Package -
- The package is an intermediate component between the DBRM and PLAN.
- The package contains an optimized access path (OAP) that is generated at the BIND step.
- The package is a non-executable component.
- The package can contain one or more DBRMs.
- The package's main advantage is that the rebound is not required when any change in the sub-program. Compiling subprogram alone is only sufficient.
Plan -
- The plan also contains an optimized access path (OAP); however, it is an executable component.
- The plan used to execute the program.
- The plan has the best access path to retrieve the data from the database using the SQLs coded in the program.
RUNTIME SUPERVISOR mainly responsible for to check the what are the time stamps for COBOL & DB2
Precompilation JCL -
Precompilation JCL Code -
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
***************************** Top of Data ******************************
//MTH001P JOB MSGLEVEL=(1,1),NOTIFY=&SYSUID
//********************************************************************
//* COBOL + DB2 PRECOMPILE AND LINKEDIT *
//********************************************************************
//* Precompile the IBM COBOL program *
//********************************************************************
//PCSTEP EXEC PGM=DSNHPC,
// PARM='HOST(IBMCOB),XREF,SOURCE,FLAG(I),APOST'
//STEPLIB DD DISP=SHR,DSN=MTHA10.DBAG.SDSNEXIT
// DD DISP=SHR,DSN=MTHA10.SDSNLOAD
//SYSCIN DD DSN=&&DSNHOUT,DISP=(MOD,PASS),UNIT=SYSDA,
// SPACE=(800,(500,500))
//SYSIN DD DSN=MTH.COBDB2.SRCLIB(TESTPROG),DISP=SHR
//SYSLIB DD DSN=MTH.COBDB2.DCLGEN,DISP=SHR
// DD DSN=MTH.COBDB2.COPYLIB,DISP=SHR
//DBRMLIB DD DSN=MTH.COBDB2.DBRMLIB(TESTPROG),DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSTERM DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSUT1 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT2 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//********************************************************************
//* Compile the IBM COBOL program if the precompile *
//* return code is 4 or less. *
//********************************************************************
//COB EXEC PGM=IGYCRCTL,
// PARM=('SIZE(4000K),BUFSIZE(32760),LIST,LIB,MAP,OBJECT',
// 'DATA(31),XREF,RENT'),
// COND=(4,LT,PCSTEP)
//STEPLIB DD DSNAME=IGY420.SIGYCOMP,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSTERM DD SYSOUT=*
//SYSLIN DD DSN=&&LOADSET,DISP=(MOD,PASS),UNIT=SYSDA,
// SPACE=(800,(500,500))
//SYSLIB DD DSN=MTH.COBDB2.COPYLIB,DISP=SHR
//SYSIN DD DSN=&&DSNHOUT,DISP=(OLD,DELETE)
//SYSUT1 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT2 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT3 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT4 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT5 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT6 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT7 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//********************************************************************
//* Linkedit if the precompile and compile *
//* return codes are 4 or less. *
//********************************************************************
//LKED EXEC PGM=IEWL,PARM='MAP,XREF',
// COND=((4,LT,PCSTEP),(4,LT,COB))
//SYSLIB DD DISP=SHR,DSN=CEE.SCEELKED
// DD DISP=SHR,DSN=MTHA10.SDSNLOAD
// DD DISP=SHR,DSN=ISP.SISPLOAD
// DD DISP=SHR,DSN=GDDM.SADMMOD
// DD DISP=SHR,DSN=MTH.COBDB2.LOADLIB
//SYSLIN DD DSN=&&LOADSET,DISP=(OLD,DELETE)
// DD DDNAME=SYSIN
//SYSLMOD DD DSN=MTH.COBDB2.LOADLIB(TESTPROG),DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD SPACE=(1024,(50,50)),UNIT=SYSDA
//SYSIN DD DUMMY
**************************** Bottom of Data ****************************
Precompilation Ways -
In the real-time environment, the precompilation process takes place in two ways -
- Using Version Control tools like Endeavor, Changeman, etc.
- Using a personal compilation JCL
The main difference between these two types of processes is the Bind Step.
Using Version Control tools -
If compiling a COBOL +DB2 program using a version control tool, the JCL also has the Bind step at the end to bind the program to the mainframe region PLAN.
i.e., Compilation JCL = Precompilation JCL + Bind Step
.
Using a personal compilation JCL -
If compiling a COBOL + DB2 program using JCL, the developer should bind the program separately after the compilation process is completed using compilation JCL.
i.e., Compilation JCL = Precompilation JCL
.
BIND process should complete separately using another bind JCL. Refer to the BIND process described in a separate topic.
Practical Example -
Scenario - Below example describes how the COBOL + DB2 program precompiled using JCL.
Input - EMPLOYEE_DETAILS table
Program Code - To retrieve employee with id 5.
COBOL + DB2 Program Code -
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
***************************** Top of Data ******************************
IDENTIFICATION DIVISION.
PROGRAM-ID. SELECT1.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
EXEC SQL
INCLUDE SQLCA
END-EXEC.
EXEC SQL
INCLUDE EMPLDET
END-EXEC.
01 WS-EMPID PIC S9(9) USAGE COMP.
PROCEDURE DIVISION.
MOVE 5 TO WS-EMPID.
EXEC SQL
SELECT EMP_ID,
EMP_NAME,
DESIGNATION,
MANAGER_ID,
DATE_OF_HIRE,
SALARY,
DEPT_ID
INTO :EMP-ID,
:EMP-NAME,
:DESIGNATION,
:MANAGER-ID,
:DATE-OF-HIRE,
:SALARY,
:DEPT-ID
FROM EMPLOYEE_DETAILS
WHERE EMP_ID = :WS-EMPID
END-EXEC.
IF SQLCODE = 0
DISPLAY EMP-ID,"|",EMP-NAME,"|",DESIGNATION,"|",
MANAGER-ID,"|",DATE-OF-HIRE,"|",SALARY,"|",DEPT-ID
ELSE
IF SQLCODE = 100
DISPLAY "EMPLOYEE DETAILS NOT FOUND"
ELSE
DISPLAY "DB2 ERROR"
END-IF
END-IF.
STOP RUN.
**************************** Bottom of Data ****************************
Precompile JCL Code -
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
***************************** Top of Data ******************************
//MATEGJP JOB MSGLEVEL=(1,1),NOTIFY=&SYSUID
//********************************************************************
//* COBOL + DB2 PRECOMPILE AND LINKEDIT *
//********************************************************************
//PCSTEP EXEC PGM=DSNHPC,
// PARM='HOST(IBMCOB),XREF,SOURCE,FLAG(I),APOST'
//STEPLIB DD DISP=SHR,DSN=DSNA10.DBAG.SDSNEXIT
// DD DISP=SHR,DSN=DSNA10.SDSNLOAD
//SYSCIN DD DSN=&&DSNHOUT,DISP=(MOD,PASS),UNIT=SYSDA,
// SPACE=(800,(500,500))
//SYSIN DD DSN=MATEGJ.COBDB2.SRCLIB(SELECT1),DISP=SHR
//SYSLIB DD DSN=MATEGJ.COBDB2.DCLGEN,DISP=SHR
// DD DSN=MATEGJ.COBDB2.COPYLIB,DISP=SHR
//DBRMLIB DD DSN=MATEGJ.COBDB2.DBRMLIB(SELECT1),DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSTERM DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSUT1 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT2 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//********************************************************************
//* Compile the IBM COBOL program if the precompile *
//* return code is 4 or less. *
//********************************************************************
//COB EXEC PGM=IGYCRCTL,
// PARM=('SIZE(4000K),BUFSIZE(32760),LIST,LIB,MAP,OBJECT',
// 'DATA(31),XREF,RENT'),
// COND=(4,LT,PCSTEP)
//STEPLIB DD DSNAME=IGY420.SIGYCOMP,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSTERM DD SYSOUT=*
//SYSLIN DD DSN=&&LOADSET,DISP=(MOD,PASS),UNIT=SYSDA,
// SPACE=(800,(500,500))
//SYSLIB DD DSN=MATEGJ.COBDB2.COPYLIB,DISP=SHR
//SYSIN DD DSN=&&DSNHOUT,DISP=(OLD,DELETE)
//SYSUT1 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT2 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT3 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT4 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT5 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT6 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//SYSUT7 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//********************************************************************
//* Linkedit if the precompile and compile *
//* return codes are 4 or less. *
//********************************************************************
//LKED EXEC PGM=IEWL,PARM='MAP,XREF',
// COND=((4,LT,PCSTEP),(4,LT,COB))
//SYSLIB DD DISP=SHR,DSN=CEE.SCEELKED
// DD DISP=SHR,DSN=DSNA10.SDSNLOAD
// DD DISP=SHR,DSN=ISP.SISPLOAD
// DD DISP=SHR,DSN=GDDM.SADMMOD
// DD DISP=SHR,DSN=MATEGJ.COBDB2.LOADLIB
//SYSLIN DD DSN=&&LOADSET,DISP=(OLD,DELETE)
// DD DDNAME=SYSIN
//SYSLMOD DD DSN=MATEGJ.COBDB2.LOADLIB(SELECT1),DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD SPACE=(1024,(50,50)),UNIT=SYSDA
//SYSIN DD DUMMY
**************************** Bottom of Data ****************************
JOB Result - MAXCC
JOB Result - Precompile Step
JOB Result - Precompile Step Final Report