Create VSAM Cluster from Jazz Definition

 

Create VSAM Cluster from Jazz Definition. 1

Step 1.  Selecting a Jazz Data Definition and Defining the Basic Cluster 1

Defining Cluster Parameters. 2

Step 2.  Loading Initial Records. 3

Creating a Jazz Copy Program.. 4

Flexibility of This Method. 7

Step 3.  Creating Alternate Indexes. 8

 

This form is invoked from the menu [JazzGen] Data/VSAM.  It is used to create a VSAM cluster from a VSAM file definition such as CustF.jzc.  Options allow you to delete and recreate a previous cluster, and to create alternate indexes.

Step 1.  Selecting a Jazz Data Definition and Defining the Basic Cluster

At first the form looks like this: -

 

Browse to the data definition in your Jazz CopyDefs folder.   The object you select must be in this folder, and have type .jzc.  It must be correctly defined with type VSAM, a field identified with property KEY, and it must have a defined DSNAME.  For my zOS example I used a record definition “Orderx.jzc”, defined like this: -

COPY Custf;

COPY Parts ;

DEFINE Orderx VSAM DATA(

    OrdNbr DECIMAL(7) DPIC '9999999' KEY HEADING 'Order Number',

    OrdCustId LIKE custf.account DKEY 'ibmuser.vsam.Orderx1',

    ordDate CHAR(12),

    OrdPart LIKE parts.partnbr DKEY 'ibmuser.vsam.Orderx2' EXISTS Parts.Partnbr,

    OrdQty SMALLINT,

    OrdDiscount DECIMAL (6,4) HEADING 'Order Discount',

    OrdStatus CHAR(10))

    DSNAME 'ibmuser.vsam.Orderx';

Test Environment = IDE

If you’re using this function with Test Environment = IDE (Jazz Configuration, Language tab), for example you’re using Micro Focus COBOL with Visual Studio, then there are minor differences in the appearance of this form.  The [Submit] button has the name of your project instead of “Submit” as its caption, and there are other differences that are noted below.   For my IDE example, I used definition

DEFINE OUTFLE VSAM DATA(

    OUTNbr CHAR(3) PIC '999' KEY,

    Rec CHAR(26) )

    DSNAME 'JazzUsr.VSAM.OUTFLE';

 

Defining Cluster Parameters

On selecting the record definition further controls appear: -

 

Check one of the functions: -

·         Cluster.  Use this if the cluster doesn’t already exist.

·         ReCreate Cluster.  Use this if you wish to delete the cluster (including all its data) and start again.  Note that if you want to retain the data you must have saved it to another file before you do this.

·         AIX.  Use this to create the alternate indexes and paths, and build the indexes.  It is necessary to have at least one record in the file before the AIX’s are created, so in cases like Orderx with DKEY or UKEY fields creating the VSAM cluster definition is a two step process.

 

For Step1 you will choose Cluster unless you’re repeating the step.  Choose ReCreate if you are.

 

Give the number of records for the primary and secondary extents.  When you enter the 1ry extent Jazz will set the 2ry extent to 10% of this, but you can overtype this with another value if you wish.

Creating a cluster: z/OS

If Test Environment = z/OS, you must give the volume name(s) for the VSAM data.  Ask your systems programmer.   For Test Environment = IDE this is optional.

 

With Test Environment = z/OS, normally you’ll leave Save JCL and Save Old Jobs unchecked to avoid clutter on your PC: -

·         If Save JCL is checked then after the job has been submitted the JCL is NOT deleted from your LocalJCL folder.

·         If Save Old Jobs is checked then previous jobs are NOT deleted when this latest one is returned. 

These controls don’t appear with Test Environment = IDE

 

Now click [JCL].   Note: sometimes this button will have caption [Review] and clicking it will display the output of the previous job. Close the display and click it again (it will have changed back to [JCL]).

 

With Test Environment = z/OS the button will change to [Review] and the [Submit] button will be activated.  You can review the job and edit it if you wish.  With values like this: -

 

 

clicking [JCL] produced this job: -

//IBMUSERJ JOB  ,CLASS=A,MSGCLASS=H,NOTIFY=&SYSUID,COND=(8,LT)

//JZVSAM1   EXEC PGM=IDCAMS   Manage VSAM Data Sets

//SYSPRINT DD SYSOUT=*

//SYSIN    DD *

 DELETE IBMUSER.VSAM.ORDERX CLUSTER

/*

//JZVSAM2   EXEC PGM=IDCAMS   Manage VSAM Data Sets

//SYSPRINT DD SYSOUT=*

//SYSIN    DD *

 DEFINE CLUSTER (NAME (IBMUSER.VSAM.ORDERX) -

     RECORDS(1000 100) VOLUMES(VPWRKA) -

     RECORDSIZE(42 42) KEYS(4 0) INDEXED)

/*

 

Click [Submit] The VSAM form is closed and Jazz submits a job to create or re-create the cluster. 

Creating a Cluster:IDE

With Test Environment = IDE, edit values for the number of 1ry and 2ry records, and click [JCL].  The VSAM form closes and you’re returned to the Jazz workbench.  The [project] button (labelled [Job Results] for zOS) will be highlighted. Click this to open the COBOL project where you add the JCL to your project.  It will have the name of the file, e.g. OUTFLE.jcl, and will look like this: -

//JAZZUSER JOB ,CLASS=A,MSGCLASS=A

//JZVSAM2   EXEC PGM=IDCAMS   Manage VSAM Data Sets

//SYSPRINT DD SYSOUT=*

//SYSIN    DD *

 DEFINE CLUSTER (NAME (JAZZUSR.VSAM.OUTFLE) -

     RECORDS(300 30) -

     RECORDSIZE(29 29) KEYS(3 0) INDEXED)

/*

 

Once added to the project, you will see it in Solution Explorer, and be able to edit it if you wish.  To submit it, right-click it in Solution Explorer and click the option “Submit JCL”.  The job will run, and its output will be displayed on printer SYSPRINT: -

      Micro Focus  MFJAMS Utility Version ED6.0_PU6

      Copyright (C) Micro Focus 1997-2020. All rights reserved.

                                                              

                 DEFINE CLUSTER (NAME (JAZZUSR.VSAM.OUTFLE) -

                     RECORDS(300 30) -                        

                     RECORDSIZE(29 29) KEYS(3 0) INDEXED)     

 JCLAM0113I(00) - ENTRYNAME DEFINED [JAZZUSR.VSAM.OUTFLE]

Step 2.  Loading Initial Records

Once created as an empty cluster, the VSAM file must be used as a sequential output file until it has at least one record.  Records must be loaded in ascending order of the primary key.   This must be done before you can do any type of READ and UPDATE logic, including the creation of alternate indexes. 

 

If you have an initial file that has exactly the correct record format and sequence then you may choose to load your initial records using the IDCAMS REPRO command.  You can do this with Jazz by repeating the step above, and then editing the JCL to replace the IDCAMS control statements with a suitable REPRO.  Don’t forget to remove the DELETE step if you generated one!

 

Or you can write your initial data from another file, with whatever changes you want, using Jazz.  It’s very easy.

Creating a Jazz Copy Program

Choose the option [JazzGen]/Logic/New Batch Program, and set up a suitable program with the Copy To option.  I have just created the cluster Orderx (IBMUSER.VSAM.ORDERX) based on the Jazz definition above.  I have another file Orders that has the data that I want to copy into Orderx as its initial records.  I create a program as follows: -

 


·         The program name could be almost anything except Orders or Orderx.

·         By naming the input file as Orders, basically the program is based on PROCESS Orders. 

·         Since I know that Orders is a VSAM file already sorted into order of OrdNbr, the primary key of both Orders and Orderx, I leave [  ] ORDER unchecked.  If the input could not have been guaranteed to have been in the correct order than I would have checked [  ] ORDER to sort the input into the sequence that was needed.

·         Similarly I want all records, so I don’t check [  ] WHERE

·         By checking [P] PRINT I’ll print some data for every record

·         In “Copy To” I name Orderx.

 

This will generate a program basically like this (plus some extra logic to report the number of records read and written): -

PROGRAM GenOrdr BATCH;

COPY orders;

COPY orderx;

PROCESS orders INDEX Copy-Stats.Input-Count;

    PRINT (Orders.?) ;

    orderx.*=orders.*;

    WRITE orderx;

END PROCESS orders;

 

A Select Data dialog appears to resolve Orders.? in the PRINT statement, and then this program appears: -

 

Normally we’d click [Process] and this program would be generated and run, producing a report and an output file.  However with Orderx defined as above the program won’t run.  The reason is that Orderx is defined with two DKEY fields.  Normally Orderx requires three DD statements, and so Jazz generates JCL like this: -

//IBMUSERL JOB  ,CLASS=A,MSGCLASS=H,NOTIFY=&SYSUID,COND=(8,LT)

//*** COMPILE BATCH PROGRAM or SUBPROGRAM

//  SET MEMBER=GENORDR

//  SET SOURCE=IBMUSER.MANAJAZZ.SRCLIB

//  SET COPYLIB=IBMUSER.MANAJAZZ.CPYLIB

//COMPILE EXEC IGYWCL

//COBOL.SYSIN    DD DSN=IBMUSER.MANAJAZZ.SRCLIB(GENORDR),DISP=SHR

//COBOL.SYSLIB   DD DSN=IBMUSER.MANAJAZZ.CPYLIB,DISP=SHR

//LKED.SYSLIB DD

//        DD

//        DD DSN=IBMUSER.MANAJAZZ.LOADLIB,DISP=SHR

//LKED.SYSLMOD   DD DSN=IBMUSER.MANAJAZZ.LOADLIB(GENORDR),

//  UNIT=,SPACE=,DISP=SHR

//*** Run (recently compiled) BATCH PROGRAM

//GO      EXEC PGM=GENORDR

//STEPLIB  DD DSN=IBMUSER.MANAJAZZ.LOADLIB,DISP=SHR

//SYSOUT   DD SYSOUT=*

//SYSUDUMP DD SYSOUT=*

//SORTLIB  DD DSN=SYS1.SORTLIB,DISP=SHR

//SORTWK01 DD UNIT=SYSDA,SPACE=(CYL,(20,5))

//* Inserted DD statements based on program

//CUSTF    DD DSNAME=IBMUSER.VSAM.CUSTF,DISP=SHR

//CUSTF1   DD DSNAME=IBMUSER.VSAM.CUSTF1,DISP=SHR

//PARTS    DD DSNAME=IBMUSER.VSAM.PARTS,DISP=SHR

//PARTS1   DD DSNAME=IBMUSER.VSAM.PARTS1,DISP=SHR

//ORDERS   DD DSNAME=IBMUSER.VSAM.ORDERS,DISP=SHR

//ORDERS1  DD DSNAME=IBMUSER.VSAM.ORDERS1,DISP=SHR

//ORDERS2  DD DSNAME=IBMUSER.VSAM.ORDERS2,DISP=SHR

//ORDERX   DD DSNAME=IBMUSER.VSAM.ORDERX,DISP=SHR

//ORDERX1  DD DSNAME=IBMUSER.VSAM.ORDERX1,DISP=SHR

//ORDERX2  DD DSNAME=IBMUSER.VSAM.ORDERX2,DISP=SHR

//REPORT1  DD SYSOUT=*

 

That would normally be correct, but at this stage it’s incorrect because we haven’t yet generated the alternate indexes, and there are no datasets with names IBMUSER.VSAM.ORDERX1 and IBMUSER.VSAM.ORDERX2.  We remove the unwanted JCL statements: -

1.    Right-click [Process]

2.    Click [JCL]

3.    Click [Review JCL] and edit to remove the two unwanted DD statements.

4.    Click [Submit]

Now the job runs correctly, producing this report: -

Printed at 14 Feb 2017, 17:56:31              Report1             Page   1

 

Order Number Account Number *--ordDate-* *--OrdPart---* *OrdQty *OrdStatus

 

     0000000         000044 12 Jan 2001             443       1 Initial01

     0000001         000044 12 Jan 2002             170       9 Initial02

     0000002         000044 12 Jan 2003             296       7 Initial03

     0000003         000044 12 Jan 2004             200       8 Initial04

     0000004         000044 12 Jan 2005             496       0 Initial05

     0000005         000021 12 Jan 2006             362       4 Initial06

     0000006         000021 12 Jan 2007             260       8 Initial07

     0000007         000021 12 Jan 2008             489       3 Initial08

     0000008         000021 12 Jan 2009             290       1 Initial09

     0000009         000021 12 Jan 2010             712       3 Initial10

     0000010         000021 12 Jan 2011             970       1 Initial11

     0000011         000021 12 Jan 2012             831       6 Initial12

     0000012         000021 12 Jan 2013             290      10 Initial13

     0000013         000021 12 Jan 2014             435       8 Initial14

     0000014         000021 12 Jan 2015             222       5 Initial15

     0000015         000021 12 Jan 2016             577       5 Initial16

     0000016         000021 12 Jan 2017             951       5 Initial17

     0000017         000021 12 Jan 2018             113       7 Initial18

     0000018         000021 12 Jan 2019             617      10 Initial19

     0000019         000021 12 Jan 2020             856      10 Initial20

     0000020         000021 12 Jan 2021             442       1 Initial21

     0000021         000021 12 Jan 2022             317       6 Initial22

     0000022         000021 12 Jan 2023             587       4 Initial23

     0000023         000021 12 Jan 2024             264       7 Initial24

     0000024         000021 12 Jan 2025             267       9 Initial25

     0000025         000021 12 Jan 2026             901       4 Initial26

     0000026         000021 12 Jan 2027             302       1 Initial27

     0000027         000021 12 Jan 2028             639      10 Initial28

     0000028         000021 12 Jan 2029              18       2 Initial29

     0000029         000021 12 Jan 2030             426       6 Initial30

     0000030         000021 12 Jan 2031             457       2 Initial31

     0000031         000021 12 Jan 2032             114       3 Initial32

     0000032         000021 12 Jan 2033             112       5 Initial33

     0000033         000021 12 Jan 2034              36       2 Initial34

     0000034         000021 12 Jan 2035              39       5 Initial35

     0000035         000021 12 Jan 2036             554       4 Initial36

     0000036         000021 12 Jan 2037             936       3 Initial37

     0000037         000024 12 Jan 2038             377       1 Initial38

     0000038         000024 12 Jan 2039             605       5 Initial39

     0000039         000024 12 Jan 2040              49       1 Initial40

     0000040         000024 12 Jan 2041             507       1 Initial41

     0000041         000024                           4       0          

 

*     Field Name      *  LENGTH  VALUE                                   

Copy-Stats.Input-Count :     14*            42                            

Copy-Stats.Output-Count:     14*            42     

Flexibility of This Method

The big advantages of this method are its simplicity and flexibility.  In this case it was particularly easy because I had another file, Orders, with the same field names (although Orderx had only a subset of these fields), and the generic assignment, orderx.*=orders.*; was all that was needed.  However I could easily have written different logic: -

·         If the input file were not already in the correct order (or if I weren’t sure), I’d only have needed to add an ORDER clause to the PROCESS statement to ensure that the data was correctly sequenced.  The input file doesn’t have to be VSAM: any file that can be read sequentially would have done.

·         I don’t care if the fields have the same format: orderx.*=orders.* is only concerned with the field names and their compatibility.  There would have been no problem if Orders.Account were one format of number and Orderx.Account were another.  The generic assignment only moves fields with the same name – rather like MOVE CORRESPONDING in COBOL and BY NAME assignment in PL/I.

·         If field names were different then I’d have replaced orderx.*=orders.*; with several individual assignment statements.  If some names were the same and some were different I’d follow the generic assignment with individual assignments.

·         I could easily have set output fields to calculated or constant values.  This is particularly convenient when creating a test file.

·         In the case above the input and output records were the same, so it doesn’t matter if you print data from the input or output records.  If you’ve changed the data then you should change the PRINT to print data from the output file just before it’s written.

·         Conditional logic such as WHERE or IF can be used to skip some records, or to terminate after writing N records.

·         By adding GET statements the output record could contain data from related records.  Conversely it is easy to write a program that will “normalise” a file by writing data from repeating groups into a separate file.   You’d write a FOR loop within the PROCESS loop to write the “child” file from the repeating section.

·         The above logic counts the input and output record, and with PRINT (Copy-Stats.*) FIELDTABLE; a very basic control report giving the count of records read and written is produced.  Simply by adding more fields to the Copy-Stats definition and accumulating data into these fields the control report could include the total of any numeric field.

Step 3.  Creating Alternate Indexes

Now that we’ve put some data into Orderx we can complete its definition by defining the alternate indexes.  You won’t need to do this if your file does not have any DKEY or UKEY fields.

 

Return to the VSAM function, setting the same values as before except that this time we choose option [P] AIX: -

 

This generates this job: -

//IBMUSERN JOB  ,CLASS=A,MSGCLASS=H,NOTIFY=&SYSUID,COND=(8,LT)

//JZVSAM3   EXEC PGM=IDCAMS   Manage VSAM Data Sets

//SYSPRINT DD SYSOUT=*

//SYSIN    DD *

 /* AIX ON FIELD ORDERX.ORDCUSTID */

 DEFINE AIX (NAME(IBMUSER.VSAM.ORDERX1.AIX) -

     RELATE(IBMUSER.VSAM.ORDERX) -

     RECORDS(1000 100) VOLUMES(VPWRKA) -

     KEYS(6 4) NONUNIQUEKEY UPGRADE REUSE)

 DEFINE PATH(NAME(IBMUSER.VSAM.ORDERX1) -

     PATHENTRY(IBMUSER.VSAM.ORDERX1.AIX) UPDATE)

 BLDINDEX INDATASET(IBMUSER.VSAM.ORDERX) -

     OUTDATASET(IBMUSER.VSAM.ORDERX1.AIX)

 /* AIX ON FIELD ORDERX.ORDPART */

 DEFINE AIX (NAME(IBMUSER.VSAM.ORDERX2.AIX) -

     RELATE(IBMUSER.VSAM.ORDERX) -

     RECORDS(1000 100) VOLUMES(VPWRKA) -

     KEYS(4 22) NONUNIQUEKEY UPGRADE REUSE)

 DEFINE PATH(NAME(IBMUSER.VSAM.ORDERX2) -

     PATHENTRY(IBMUSER.VSAM.ORDERX2.AIX) UPDATE)

 BLDINDEX INDATASET(IBMUSER.VSAM.ORDERX) -

     OUTDATASET(IBMUSER.VSAM.ORDERX2.AIX)

/*

 

This created the alternate indexes and paths and built the indexes for Orderx.

 

If your file contains any UKEY indexes then the AIX will be created with UNIQUEKEY.  In this case there is a potential error with this job stream if the data that you’ve loaded into the cluster in Step1 has non-unique values of this UKEY field.