0

I have a program that is reading through a file(FILE1). For every record in FILE1 it gets the field 'A' and it searches through FILE2 to find a record with a matching value of field 'B'. When A = B some fields from both files are read out. The program is currently working with code like below. However, the problem is I am opening and closing FILE2 in a loop, multiple times. I've tried this without opening the file inside the loop but if I do that I get repeated records as FILE2 is being read in from where the previous search left off. Is there any way I can point to the beginning of File2 every time I read a new record from FILE1? The code is below:

READ FILE(FILE1) INTO (IN_LAYOUT);
    DO WHILE (MORE_RECS1);
       OPEN FILE(FILE2);
       READ FILE(FILE2) INTO (IN_LAYOUT2);
       MORE_RECS2 = '1'B;
              DO WHILE (MORE_RECS2);
                 IF (A = B) THEN
                  DO;
                     VAL = VAL2;
                     WRITE FILE (OUFILE) FROM (OUT_LAYOUT);
                     S_MORE_RECS2 = '0'B;
                     CLOSE FILE(FILE2);
                  END; /* ENDIF */
                  ELSE READ FILE(FILE2) INTO (IN_LAYOUT2);
              END; /* INNER DOWHILE */
       READ FILE(FILE1) INTO (IN_LAYOUT);
    END; 
cschneid
  • 10,237
  • 1
  • 28
  • 39
randomG765
  • 63
  • 1
  • 13
  • Have you tried opening the file outside of the loop? – jrmullen Sep 16 '16 at 13:40
  • Yes, but the problem then is that when I find the record I need in file2 and write the record I need to break out of the loop to read the next record in from file1. Then when I begin reading through file2 again I'm not starting from the beginning of the file. I'm starting from wherever the last read ended. File2 often has 40,000 records. – randomG765 Sep 16 '16 at 13:57
  • Try to avoid ever considering that again. The amount of overhead for repeated opens/closes is huge. Remember, client pays for resources. They are not going to be happy if you just suck them up. JOINKEYS is a possibility, depending on what else is really in the program. Or a two-file match (of sorted data). Or try to store one file entirely in the program. Or try to make the data accessible by key. Anything but multiple opens/closes/reads. Even if you could avoid the opens/closes, you stil have the read overhead. Ouch. – Bill Woodger Sep 16 '16 at 15:54

2 Answers2

2

This looks like a match-merge. Try first sorting the files by the keys you're matching on.

At least some mainframe sort utilities have this match-merge functionality built in, Syncsort for example has the JOIN operator. I'm certain DFSORT also has this capability.

cschneid
  • 10,237
  • 1
  • 28
  • 39
  • Yes, DFSORT has JOINKEYS. – Bill Woodger Sep 16 '16 at 16:03
  • Thanks, I've just tried using a cartesian join but I'm still having problems. E.g. There's about 20 records in the first file, and about 40,000 in the second. So if I sort the files so that they're in the same order, the records are still thousands of places apart in the second file. Also, in the first file, I might have a key occur 5 times that only occurs once in the second file, so I'll need to find that one record in the second file 5 separate times. I'm not sure this can be done through SORT logic. – randomG765 Sep 19 '16 at 09:08
  • @JackDonovan if for some reason you _want_ to write code to do this you need to sort both files by the keys on which you match in your logic. Then all the records in the second file will be adjacent and not thousands of places apart. But your SORT utility can do the match-merge for you. – cschneid Sep 19 '16 at 13:31
1

In this case @cschneid answer is the best solution. For for completeness there are other solutions available:

  1. Sort the 2 input files on the key and do the merge in your program
  2. Load File2 into a VSAM file and do a index lookup

Sort Merge processing

If you sort the 2 input files on the keys you can do:

DO WHILE (MORE_RECS1 and MORE_RECS2);
   if (key_file1 < key_file2) then do;
      READ FILE(FILE1) INTO (IN_LAYOUT);
   end; else if (key_file1 > key_file2) then do;
      READ FILE(FILE2) INTO (IN_LAYOUT2);
   end; else do;
      VAL = VAL2;
      WRITE FILE (OUFILE) FROM (OUT_LAYOUT);
      READ FILE(FILE1) INTO (IN_LAYOUT);
   end;
end;

Using this makes sense when the logic is to complicated for Sort (e.g. you need to DB lookups

Load File2 into a VSAM file

Another alternative is to load File2 into a VSAM file and do a keyed read. This can be useful to avoid doing expensive DB lookups multiple times (particularly with IMS which is less flexible than DB2).

In most cases the Sort-Merge processing above will be faster than VSAM lookup.

Bruce Martin
  • 10,358
  • 1
  • 27
  • 38