Merging Two Sequential Files

Contents

Merging Two Sequential Files. 1

Introduction. 1

Creating a Merge Process. 1

Merge Logic. 1

Comparing Merge Keys. 1

How PROCESS … MERGE works. 1

MERGE with SORT. 1

Sequential Updates – Merge with Copy. 1

Creating FILEOUT. 1

Preventing Output – Important Concepts. 1

Preventing the Insertion of New Records. 1

Sequence Checking. 1

Copy Stats and Merge Programs. 1

Introduction

With [Merge] the Logic/Batch Program dialog will create a program that will merge two sequential files.   It is possible to update the first file by creating a copy of it with updates from the second input file.   Both files must be in ascending sequence.

 

File Merging is very similar to Easytrieve Synchronized File Processing, and you may be approaching this topic from the perspective of an EZT conversion.  If so, you should read this page together with the Help page Easytrieve Logic, particularly the two sections on Synchronized File Processing.   There are significant differences in the approach taken by MANASYS compared to the Easytrieve approach. 

Creating a Merge Process

Start with Logic/Batch Program and enter the first input file name(FILE1).  Then click button [Merge], and a panel appears to fill in the details for a sequential merge.  Click the Skeys buttons to select key fields from each of the files being merged.   You can select any number of sequence fields for File1, you must select the same number of fields for File2.

 

Now, click [Finish] and the form will be checked and, if valid, a Jazz program created.  With Merge, additional checks include that both File1 and File2 can be read sequentially, and that their corresponding sequence keys can be compared.  Detail rules are given below, but simply, comparisons such as “IF KEY1A = KEY1B” must be valid.  This is not true if either is a group, or one is a character and the other is a number.  You may not check ORDER, WHERE or Validate Definition.

Merge Logic

From the dialog above, MANASYS will generate a program with a PROCESS statement like this: -

PROCESS File1 MERGE File2 SKEYS (FILE1.KEY1A,FILE2.KEY1B);

This creates logic as follows: -

Read initial records from both files

Loop until both files finished

… (e.g., logic from PRINT)

IF File1 <= File2

    Read next File2

ELSE

    Read next File1

END IF

END Loop

·            The first file, FILE1, is considered to be a master file, and should have only one record for each key value.  If there are duplicate records (i.e. same key value) in the master file, then any updates will be applied to the first record, and others will be unchanged.

·            The second file is the transaction file. It may contain any number of records for any particular key value, and may include key values that are not represented on the input master file.

·            The SKEYS option specifies the collating condition, as above. 
     SKEYS (FILE1.KEY1A,FILE2.KEY1B)

·            The logic critically depends on the master file and transaction file being presented to the program in ascending key sequence.  Key values at the beginning of files must be the lowest of all records, and at end of file are considered to be higher than any possible record. Logic generated by MANASYS allows records to have key values of 0, LOW-VALUES and HIGHVALUES, and the smallest and largest possible values that the key field(s) can contain.  If you know that an input file is in the wrong sequence, check the SORT option.   If you are almost 100% confident that they are in the correct sequence but want to check this, check the Check option.  You can specify these options for either or both input files.

Comparing Merge Keys

The pseudocode logic above

IF File1 <= File2

is actually a comparison of the corresponding SKEY values, in this case
            IF FILE1.KEY1A <= FILE2.KEY1B

Here there is only one pair of SKEY values, but there may be several.  For example, in another program IN1 (Master file) was merged with IN1Tran (transactions) based on three pairs of SKEY values: -

PROCESS in1 SORT MERGE IN1Tran SORT SKEYS (IN1.Region,IN1.District,IN1.Name,IN1Tran.Region,IN1Tran.District,IN1Tran.Name)…

The IF logic required by the PROCESS MERGE loop becomes complex with many key pairs, so a special values JZ.$CMerge and JZ.$CMergeOut are available. $CMerge has value 0 if the SKEY values are equal, negative if FILE1 is less than FILE2, and positive if FILE1 is greater than FILE2. 

$CMergeOut is used when the PROCESS MERGEincludes a COPY option. It is similar to $CMerge except that it compares FILEOUT with FILE2

You will see $CMerge printed in the examples below, and used in the conditions that you write to handle update logic. Normally you’ll only compare JZ.$CMerge with 0, but where there are multiple key pairs, as in the PROCESS statement above, you can find which field determines the comparison from the value returned by JZ.$CMerge. The value will be +1 or -1 if the first SKEY pair (IN1.Region,IN1Tran.Region) differs, +2 or -2 if they are the same but the second pair (IN1.District,IN1Tran.District) differ, and so on for as many key pairs as are used.

 

How PROCESS … MERGE works.

Like any PROCESS statement,

PROCESS FILE1 MERGE FILE2 SKEYS (FILE1.KEY1A, FILE2.KEY1B);

defines an I/O loop in which a record is read and processed, but when the PROCESS statement names two files, the loop iteration may read from either file. Only one record is read per iteration, so the program EITHER reads the next File1 record OR the next File2 record.   FILE1 is read if FILE1.KEY1A < FILE2.KEY1B, so FILE2 is read if FILE1.KEY1A >= FILE2.KEY1B.

 

The logic is best understood with an example.   FILE1 and FILE2 have been defined, and test data created, like this: -

DEFINE FILE1 FB DATA(

    KEY1A PIC '999' RANGE (1:20),

    BALANCE MONEY(7,2),

    NbrA SMALLINT)

    DSNAME 'JAZZUSER.Files.File1';

DEFINE FILE2 FB DATA(

    KEY1B PIC '999' RANGE (1:20),

    PAYMENT MONEY(7,2),

    NbrB SMALLINT)

    DSNAME 'JAZZUSER.Files.File2';

0KEY1A *--BALANCE-* *NbrA-*
0  002  $1,236.56         1
   004  $1,238.56         2
   005  $1,239.56         3
   007  $1,241.56         4
   008  $1,242.56         5
   010  $1,244.56         6
   011  $1,245.56         7
   013  $1,247.56         8
   015  $1,249.56         9
   017  $1,251.56        10

0KEY1B *--PAYMENT-* *NbrB-*

0  002    $234.56CR       1

   002  $1,000.00         2

   005    $500.00         3

   005    $270.44         4

   011  $1,245.56CR       5

   012  $2,468.35         6

   014  $1,000.00         7

   014  $2,500.00         8

   017    $500.00         9

   017    $500.00        10

 

This simple program merges these two files: -

PROGRAM Batch BATCH;

COPY FILE1;

COPY FILE2;

PROCESS FILE1 MERGE FILE2 SKEYS(FILE1.KEY1A,FILE2.KEY1B) COUNT JZ2.IX1 SID(21);

    PRINT (JZ2.IX1,', ',FILE1.*,', ', FILE2.*,JZ.$CMerge) ;

END PROCESS MERGE;

 

Initially the program reads the first record from both files, then the PROCESS loop is executed until both files have finished. Each iteration of the loop reads a record from either FILE1 or FILE2, so that there are 20 iterations.  The FILE2 record is read when it’s sequence key is less than or equal to the FILE1 sequence key, i.e. FILE2.KEY1B <= FILE1.KEY1A, or $CMerge >= 0.  Here are the results from the PRINT statement

1Printed at 19 Feb 2023, 12:22:15            RepNbr1            Page   1

0*-IX1-*  KEY1A *--BALANCE-* *NbrA-*  KEY1B *--PAYMENT-* *NbrB-* $CMerge

0      1,   002  $1,236.56         1,   002    $234.56CR       1       0

       2,   002  $1,236.56         1,   002  $1,000.00         2       0

       3,   002  $1,236.56         1,   005    $500.00         3      -1

       4,   004  $1,238.56         2,   005    $500.00         3      -1

       5,   005  $1,239.56         3,   005    $500.00         3       0

       6,   005  $1,239.56         3,   005    $270.44         4       0

       7,   005  $1,239.56         3,   011  $1,245.56CR       5      -1

       8,   007  $1,241.56         4,   011  $1,245.56CR       5      -1

       9,   008  $1,242.56         5,   011  $1,245.56CR       5      -1

      10,   010  $1,244.56         6,   011  $1,245.56CR       5      -1

      11,   011  $1,245.56         7,   011  $1,245.56CR       5       0

      12,   011  $1,245.56         7,   012  $2,468.35         6      -1

      13,   013  $1,247.56         8,   012  $2,468.35         6       1

      14,   013  $1,247.56         8,   014  $1,000.00         7      -1

      15,   015  $1,249.56         9,   014  $1,000.00         7       1

      16,   015  $1,249.56         9,   014  $2,500.00         8       1

      17,   015  $1,249.56         9,   017    $500.00         9      -1

      18,   017  $1,251.56        10,   017    $500.00         9       0

      19,   017  $1,251.56        10,   017    $500.00        10       0

      20,   017  $1,251.56        10,   999    $500.00        10      -1

 * * * END OF RepNbr1 * * *

Notice that the last FILE2 record has been given a key of 999, but there is no such input record. The loop executes until both input files have finished: here the last records have key 017 so on the penultimate loop iteration both FILE1 and FILE2 are positioned on their last record.   With equal keys FILE2 is read, causing FILE2-ENDFILE to be set true and FILE2.KEY1B to be set to the highest possible value.  For a PIC '999' variable this is 999.  The loop is executed for the last time with FILE1.KEY1A = 017 and FILE2.KEY1B = 999, so FILE1 is read.  Now both files have finished, and the PROCESS loop terminates.

MERGE with SORT

It is critical that the input files are presented in the correct sequence.  In the example above,

PROCESS FILE1 MERGE FILE2 SKEYS (FILE1.KEY1A, FILE2.KEY1B) COUNT JZ.IX1;

FILE1 must be in ascending order of FILE1.KEY1A, and FILE2 in ascending order of FILE2.KEY1B.  FILE1R and FILE2R are copies of FILE1 and FILE2 sorted into random order, and so results will be incorrect with

PROCESS FILE1R MERGE FILE2R SKEYS (FILE1R.KEY1A, FILE2R.KEY1B) COUNT JZ.IX1;

However, if you’ve checked their SORT options the dialog adds SORT, as here

PROCESS FILE1R SORT MERGE FILE2R SORT SKEYS (FILE1R.KEY1A, FILE2R.KEY1B) COUNT JZ.IX1;

If you checked the Check option, SEQCHECK will be inserted instead of SORT (you can’t check both).  SORT / SEQCHECK must immediately follow the relevant file names, FILE1R and/or FILE2R, they are invalid anywhere else in this statement.

When a PROCESS statement like that above is Checked for the first time, extra definition(s) are added like this: -

    DEFINE IFILE1R LIKE FILE1R MERGESORT;

    DEFINE IFILE2R LIKE FILE2R MERGESORT;

PROCESS FILE1R SORT MERGE FILE2R SORT SKEYS (FILE1.KEY1A, FILE2.KEY1B) COUNT JZ.IX1;

    #263 S Definition inserted for IFILE1R. Click CHECK again

    #263 S Definition inserted for IFILE2R. Click CHECK again

Click [Check] again and this becomes

DEFINE IFILE1R LIKE FILE1R MERGESORT;

#492 W DSNAME FOR FILE1R changed to &&FILE1R

#492 I DSNAME 'JAZZUSER.Files.File1R'

DEFINE IFILE2R LIKE FILE2R MERGESORT;

#492 W DSNAME FOR FILE2R changed to &&FILE2R

#492 I DSNAME 'JAZZUSER.Files.File2R'

PROCESS FILE1R SORT MERGE FILE2R SORT SKEYS (FILE1.KEY1A, FILE2.KEY1B) COUNT JZ.IX1;

Because of SORT, before PROCESS the input files are read and sorted, for example with
004000     SORT SORTWORK ON ASCENDING KEY KEY1A OF JZ-SORTWORK USING    Batch4

004010         IFILE1R GIVING FILE1R.                                   Batch4

004020     OPEN INPUT FILE1R.                                           Batch4

The #492 messages tell us that IFILE1R uses FILE1R’s DSNAME.  FILE1R is written by the sort with DSNAME &&FILE1R, and read back by the following program.  Here is the JCL that will be generated for this program: -

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

//GO      EXEC PGM=BATCHR,TIME=(0,10)

//SYSOUT   DD SYSOUT=*

//PRTERR   DD SYSOUT=*

//SNAP     DD SYSOUT=*   USED BY JZSTXIT

//* Inserted DD statements based on program

//FILE1R   DD DSNAME=&&FILE1R,DISP=(NEW,PASS)

//FILE2R   DD DSNAME=&&FILE2R,DISP=(NEW,PASS)

//IFILE1R  DD DSNAME=JAZZUSER.FILES.FILE1R,DISP=SHR

//IFILE2R  DD DSNAME=JAZZUSER.FILES.FILE2R,DISP=SHR

//REPNBR1  DD SYSOUT=*

Sequential Updates – Merge with Copy

Sequential files are updated by creating a new copy of File1, which is based on the records read from File1 with changes made by the processing logic.  To create a program with this logic, name an output file in the Copy To Textbox.  When you clicked [MERGE], [ü] LIKE Input was be automatically checked and disabled.  Because you’ve named an output file MANASYS will insert a definition of your output file into your Jazz program, like this.

DEFINE FILE1OUT LIKE FILE1;

The output file (FILEOUT) will have exactly the same file type and record layout as the input (FILE1), the only difference will be that the DSNAME of FILEOUT will be different to that of FILE1.

 

 

Because we’ve given a name for an output file, FILEOUT, logic will be included to copy FILE1 to FILEOUT.  Where the transaction file (FILE2) has a new sequence key (for example 012) that is not in the master file (FILE1), a new record is created in FILEOUT.  The output record is initialized by: -

·            The sequence field (KEY1A) will be set to the values from the FILE2 record.

·            Other fields will be initialised according to their default values in the FILE1 definition (normally zeros and blanks).

 

The record can then be updated by your logic between PROCESS FILE1 MERGE … and END PROCESS MERGE.   As before, it’s easier to understand with an example: this program will update FILE1 from FILE2, writing the updated records to FILEOUT: -

PROGRAM Batch BATCH;

COPY FILE1;

DEFINE FILEOUT LIKE FILE1;

#492 I DSNAME 'JAZZUSER.FILES.FILEOUT'

COPY FILE2;

PROCESS FILE1 MERGE FILE2 SKEYS(FILE1.KEY1A,FILE2.KEY1B) COUNT JZ2.IX1 COPY FILEOUT  SID(21);

    IF FILEOUT.KEY1A = FILE2.KEY1B;

        FILEOUT.BALANCE += File2.Payment;

    END IF;

    PRINT (JZ2.IX1,', ',FILE1.*,', ', FILE2.*,', ',FILEOUT.*, JZ.$CMerge) ;

END PROCESS MERGE COPY FILEOUT;

 

From the PROCESS statement to END PROCESS, and including any routines that are performed from within the PROCESS loop, the FILE1, FILE2, and FILEOUT records exist and can be referenced.  The FILEOUT record will be written at END PROCESS MERGE COPY FILEOUT; when the logic recognizes that a new FILEOUT record is needed.

 

Note that the condition above compares the OUTPUT record with FILE2.  This makes the logic above correct when a FILE2 record does not match with an existing FILE1 record, or if there are several FILE2 records matching the output record.   There is a special value, $CMergeOut, which you can use like $CMerge: -

    IF JZ.$CMergeOut=0;

This is particularly useful when there are several key pairs.

 

Here are the records produced from this program using the test data above: -

KEY1A *--BALANCE-* *NbrA-*

  002  $2,002.00         1

  004  $1,238.56         2

  005  $2,010.00         3

  007  $1,241.56         4

  008  $1,242.56         5

  010  $1,244.56         6

  011      $0.00         7

  012  $2,468.35         0

  013  $1,247.56         8

  014  $3,500.00         0

  015  $1,249.56         9

  017  $2,251.56        10

 

And here is the printout produced from the program’s PRINT statement: -

1Printed at 19 Feb 2023, 13:07:08                          RepNbr1                          Page   1

0*-IX1-*  KEY1A *--BALANCE-* *NbrA-*  KEY1B *--PAYMENT-* *NbrB-*  KEY1A *--BALANCE-* *NbrA-* $CMerge

0      1,   002  $1,236.56         1,   002    $234.56CR       1,   002  $1,002.00         1       0

       2,   002  $1,236.56         1,   002  $1,000.00         2,   002  $2,002.00         1       0

       3,   002  $1,236.56         1,   005    $500.00         3,   002  $2,002.00         1      -1

       4,   004  $1,238.56         2,   005    $500.00         3,   004  $1,238.56         2      -1

       5,   005  $1,239.56         3,   005    $500.00         3,   005  $1,739.56         3       0

       6,   005  $1,239.56         3,   005    $270.44         4,   005  $2,010.00         3       0

       7,   005  $1,239.56         3,   011  $1,245.56CR       5,   005  $2,010.00         3      -1

       8,   007  $1,241.56         4,   011  $1,245.56CR       5,   007  $1,241.56         4      -1

       9,   008  $1,242.56         5,   011  $1,245.56CR       5,   008  $1,242.56         5      -1

      10,   010  $1,244.56         6,   011  $1,245.56CR       5,   010  $1,244.56         6      -1

      11,   011  $1,245.56         7,   011  $1,245.56CR       5,   011      $0.00         7       0

      12,   011  $1,245.56         7,   012  $2,468.35         6,   011      $0.00         7      -1

      13,   013  $1,247.56         8,   012  $2,468.35         6,   013  $1,247.56         8       1

      14,   013  $1,247.56         8,   014  $1,000.00         7,   013  $1,247.56         8      -1

      15,   015  $1,249.56         9,   014  $1,000.00         7,   015  $1,249.56         9       1

      16,   015  $1,249.56         9,   014  $2,500.00         8,   015  $1,249.56         9       1

      17,   015  $1,249.56         9,   017    $500.00         9,   015  $1,249.56         9      -1

      18,   017  $1,251.56        10,   017    $500.00         9,   017  $1,751.56        10       0

      19,   017  $1,251.56        10,   017    $500.00        10,   017  $2,251.56        10       0

      20,   017  $1,251.56        10,   999    $500.00        10,   017  $2,251.56        10      -1

 * * * END OF RepNbr1 * * *

 

The program above shows the key features of a PROCESS … MERGE … COPY program: -

1.    The output file is defined with LIKE

DEFINE FILEOUT LIKE FILE1;

#492 I DSNAME 'JAZZUSER.Files.FILEOUT'

This means that its layout is exactly the same as FILE1: as you can see from the printout it has the same field names, each with the same format.  The only thing that is different is the DSNAME:  Message #492 tells us how this has been changed.

2.    For the entire program the FILE1, FILE2, and FILEOUT records exist and can be referenced, but their values are not defined before
      PROCESS FILE1 ;

At this point the first record from FILE1 and FILE2 will have been read, and the FILEOUT record will be empty (initial values).

3.      At END PROCESS MERGE COPY FILEOUT; the loop logic reads the next record from either FILE1 or FILE2, and then determines whether to write a record to FILEOUT.  If a record is written, the next FILEOUT record is created in memory. 
      If File1 <= File2 it is initialized as a copy of the FILE1 record
      Else it is initialized from default values and it’s key (FILEOUT.KEY1A) is set from File2’s key(FILE2.KEY1B).

4.    Within the PROCESS loop you can refer to fields from either of the input files and the output file, and also JZ.$CMerge for comparisons. The FILEOUT record is the next record to be written, so that the logic

    IF JZ.$CMergeOut = 0;  [equivalent to IF Fileout.KEY1A = FILE2.KEY1B;]

        FILEOUT.BALANCE += File2.Payment;

    END IF;

adds the payment to the output balance.

Creating FILEOUT

When you [Process] the Jazz program, MANASYS creates COBOL and JCL.  If you’re creating FILEOUT for the first time, then you must exit the JCL that has been generated, changing

            //FILEOUT  DD DSNAME=JAZZUSER.FILES.FILEOUT,DISP=SHR

to

            //FILEOUT  DD DSNAME=JAZZUSER.FILES.FILEOUT,DISP=(NEW,CATLG)

If you’re using Micro Focus Enterprise Developer, do this before you submit the run JCL.  If you’re using zOS then right-click [Process] and click [JCL], then edit the JCL before submitting the job to compile and run your program.

If FILEOUT exists then you can leave the default JCL with DISP=SHR unless FILEOUT is different to the previously-catalogued data set.

Preventing Output – Important Concepts

If you’re used to writing similar programs with COBOL or Easytrieve then you’ll be expecting to have to code a WRITE FileOut statement somewhere, but MANASYS generates this for you at the right place so you don’t have to.  This is fine if you are happy with the default logic rules of MANASYS, which will write updated records for each master file (FILE1) record after it’s been updated, and will write new records if a transaction does not match with any master file record.  This may not be what you want.  In this case you must prevent the record from being written.

 

If you don’t want a record to be written, write

Copy-wanted = false;

 where it will be executed.  [Check] will change this to

JZ.COPY-WANTED = false;

preventing a record from being written at the end of the PROCESS loop.  For example, suppose the transaction file had a field Function, and you wanted to “Delete” records matched with transactions where this had value 'D'.  You could write logic like this: -

PROCESS FILE1 MERGE FILE2 SKEYS (FILE1.KEY1A, FILE2.KEY1B) COPY FILEOUT COUNT(IX);

    IF JZ.$CMergeOut = 0;  

        FILEOUT.BALANCE += FILE2.PAYMENT;

        IF File2.Function = 'D';

            JZ.COPY-WANTED = false;

        END IF;

    END IF;

    PRINT (JZ.IX, FILE1.*, FILE2.*, FILEOUT.*) ;

END PROCESS MERGE COPY FILEOUT;

This will prevent END PROCESS from writing the FILEOUT record.

 

JZ.COPY-WANTED remains set False until FILEOUT.KEY1A changes and END PROCESS tries to write a record.  Suppose that we wrote

PROCESS FILE1 MERGE FILE2 SKEYS (FILE1.KEY1A, FILE2.KEY1B) COPY FILEOUT COUNT(IX);

    IF JZ.$CMergeOut = 0;  

        FILEOUT.BALANCE += FILE2.PAYMENT;

        IF FILEOUT.BALANCE = 0;

            JZ.COPY-WANTED = false;

        END IF;

    END IF;

    PRINT (JZ.IX, FILE1.*, FILE2.*, FILEOUT.*) ;

END PROCESS MERGE COPY FILEOUT;

 

With the test data used so far, this would cause the output record

  011      $0.00         7

to be omitted.   But since there might be several transactions for this key value, in a general case the results might be incorrect.   Imagine that record 5 of FILE2 were followed by another transaction for key value 011, resetting FILEOUT.BALANCE to a non-zero value.   The record would still be deleted (not copied).  If situations like this are possible, the logic should be 

PROCESS FILE1 MERGE FILE2 SKEYS (FILE1.KEY1A, FILE2.KEY1B) COPY FILEOUT COUNT(IX);

    IF JZ.$CMergeOut = 0;  

        FILEOUT.BALANCE += FILE2.PAYMENT;

        IF FILEOUT.BALANCE = 0;

            JZ.COPY-WANTED = false;

        ELSE;

            JZ.COPY-WANTED = true;

        END IF;

    END IF;

    PRINT (JZ.IX, FILE1.*, FILE2.*, FILEOUT.*) ;

END PROCESS MERGE COPY FILEOUT;

Preventing the Insertion of New Records

By default, MERGECOPY logic will insert new records into the output file if the transaction record has an unmatched key.  To prevent this happening, set Copy-Wanted to False if the File1 key is greater than the File2 key.   The transaction file (File2) is read in preference to the master file (File1), i.e. END PROCESS MERGE logic is
            If File2 <= File1

                Read File2

            ELSE

                Read File1

This means that unmatched File2 records will result in the PROCESS loop being executed with File2’s key is greater than File1’s key. 

DEFINE W DATA(X CHAR(1));

PROCESS FILE1 MERGE FILE2 ON FILE1.KEY1A=FILE2.KEY1B COPY FILEOUT COUNT JZ.IX1;

    IF JZ.$CMergeOut = 0;  

        FILEOUT.BALANCE += FIle2.Payment;

        IF JZ.$CMerge > 0;

            JZ.COPY-WANTED = false;

        END IF;

    END IF;

    W.X = JZ.COPY-WANTED;

    #319 W Actual Code is assigned

    PRINT (JZ.IX1, FILE1.*, FILE2.*, FILEOUT.*, W.X) ;

END PROCESS MERGE COPY FILEOUT;

To illustrate this, the value of Copy-Wanted is moved to a printable field, W.X, so that the last field shows Y or N corresponding to True or False values. 

 

Printout from this is

0*-IX1-* KEY1A *--BALANCE-* *NbrA-* KEY1B *--PAYMENT-* *NbrB-* KEY1A *--BALANCE-* *NbrA-* X

0      1   002  $1,236.56         1   002    $234.56CR       1   002  $1,002.00         1 Y

       2   002  $1,236.56         1   002  $1,000.00         2   002  $2,002.00         1 Y

       3   002  $1,236.56         1   005    $500.00         3   002  $2,002.00         1 Y

       4   004  $1,238.56         2   005    $500.00         3   004  $1,238.56         2 Y

       5   005  $1,239.56         3   005    $500.00         3   005  $1,739.56         3 Y

       6   005  $1,239.56         3   005    $270.44         4   005  $2,010.00         3 Y

       7   005  $1,239.56         3   011  $1,245.56CR       5   005  $2,010.00         3 Y

       8   007  $1,241.56         4   011  $1,245.56CR       5   007  $1,241.56         4 Y

       9   008  $1,242.56         5   011  $1,245.56CR       5   008  $1,242.56         5 Y

      10   010  $1,244.56         6   011  $1,245.56CR       5   010  $1,244.56         6 Y

      11   011  $1,245.56         7   011  $1,245.56CR       5   011      $0.00         7 Y

      12   011  $1,245.56         7   012  $2,468.35         6   011      $0.00         7 Y

      13   013  $1,247.56         8   012  $2,468.35         6   012  $2,468.35         0 N

      14   013  $1,247.56         8   014  $1,000.00         7   013  $1,247.56         8 Y

      15   015  $1,249.56         9   014  $1,000.00         7   014  $1,000.00         0 N

      16   015  $1,249.56         9   014  $2,500.00         8   014  $3,500.00         0 N

      17   015  $1,249.56         9   017    $500.00         9   015  $1,249.56         9 Y

      18   017  $1,251.56        10   017    $500.00         9   017  $1,751.56        10 Y

      19   017  $1,251.56        10   017    $500.00        10   017  $2,251.56        10 Y

      20   017  $1,251.56        10   999    $500.00        10   017  $2,251.56        10 Y

FILEOUT does not contain records for key values 12 or 14.

 

Sequence Checking

Merge logic, particularly when producing a new copy file, depends critically on the input sequence.  Errors will occur if either file is out of sequence, and the results of any update are undetermined if there are duplicate key values in FILE1.   You can check [ü]Check  and/or [ü] Chk when the program is generated: -

 

These cause SEQCHECK to be inserted into the PROCESS statement, and definitions inserted into the program to enable sequence checking: -

PROGRAM Batch1 BATCH;

COPY FILE1;

DEFINE FILEOUT LIKE FILE1;

#492 I DSNAME 'JAZZUSER.FILES.FILEOUT'

COPY FILE2;

DEFINE FILE1-SEQCHECK DATA(

    KEY1A LIKE FILE1.KEY1A);

DEFINE FILE2-SEQCHECK DATA(

    KEY1B LIKE FILE2.KEY1B);

PROCESS FILE1 SEQCHECK MERGE FILE2 SEQCHECK SKEYS (FILE1.KEY1A,FILE2.KEY1B) COPY FILEOUT;

END PROCESS MERGE COPY FILEOUT;

 

SEQCHECK causes logic to be included so that the input sequence is checked.  If the file is out of sequence then a message is displayed on SYSOUT and the program is aborted. 

Copy Stats and Merge Programs

When [ü] Copy Stats is checked and a Merge program is generated, three input counters are generated.   Here is the program generated from the dialog above: -

PROGRAM Batch1 BATCH;

* You may need to edit these statements

COPY FILE1;

DEFINE FILEOUT LIKE FILE1;

#492 I DSNAME 'JAZZUSER.Files.FILEOUT'

DEFINE Copy-Stats DATA(

*  Add any fields to be summed.  For especially large files ensure fields have enough digits

    Input-Count INTEGER,

    FILE1-Input-Count INTEGER,

    FILE2-Input-Count INTEGER,

    Output-Count INTEGER);

COPY FILE2;

PROCESS FILE1 MERGE FILE2 SKEYS (FILE1.KEY1A,FILE2.KEY1B) COPY FILEOUT COUNT Copy-Stats.Input-Count;

    PRINT (FILE1.*, FILE2.*) ;

END PROCESS MERGE COPY FILEOUT COUNT Copy-Stats.Output-Count;

PRINT (Copy-Stats.*) FIELDTABLE;

 

When run with the test data above, the report from the final PRINT (Copy-Stats.*) FIELDTABLE; shows: -

 *        Field Name        *  PR-LTH  VALUE       

 Copy-Stats.Input-Count      :     14:            20

 Copy-Stats.FILE1-Input-Count:     14:            10

 Copy-Stats.FILE2-Input-Count:     14:            10

 Copy-Stats.Output-Count     :     14:            12