Published on System iNetwork (http://systeminetwork.com)
OPNQRYF and Random Access
By tzura
Created Jun 26 2006 - 07:00

By:
Scott Klement [1]

Q: In my CL program, I have an OPNQRYF command that I use to select certain records from a file. I know how to read the entire list of selected records in my RPG program, but how can I access them randomly, for example with a CHAIN?

A: You can access the results of an OPNQRYF randomly from RPG. The tricky part is that the file's keys need to match the external definition pulled into your RPG program when it was compiled.

When the keylist on the OPNQRYF matches that of the file, there's not much to it. You do an OPNQRYF in the CL, then chain to it from RPG. For example, suppose you have a file defined with the following DDS:

     A                                      UNIQUE
     A          R CUSTMASF
     A            CUSTNO         4S 0
     A            NAME          30A
     A            ADDRESS       30A
     A            CITY          13A
     A            STATE          2A
     A            ZIPCODE        5S 0
     A            STATUS         1A
     A          K CUSTNO

If you want to access a subset of this file by customer number, it's quite simple to do so using OPNQRYF and RPG. First, you need the CL program that runs the OPNQRYF command. In this case, I have it subset all active records from the customer master file, as follows:

PGM

    OVRDBF FILE(CUSTMAS) SHARE(*YES)

    OPNQRYF FILE((CUSTMAS))  QRYSLT('STATUS = "A"') +
            KEYFLD((CUSTNO))

    CALL RPGPGM

    CLOF CUSTMAS
    DLTOVR CUSTMAS
ENDPGM

The RPG program can access this file as it typically would. If it tries to chain to a record in which the status code isn't set to "A", the chain doesn't find the record. For example:

     FCUSTMAS   IF   E           K DISK
     D Key             s                   like(CustNo)

      /free

          Key = 1234;
          chain Key CUSTMAS;
          if %found;
              . . . record was found and therefore must
                    be an active record . . .
          endif;

      /end-free

When I compile this program, it picks up the external definition of the CUSTMAS file. One of the attributes that it picks up is the keys for the file. In this case, the external key that it picks up is CUSTNO, because that's what the file is defined with. Because this same key is the one listed on the OPNQRYF statement, it works with OPNQRYF as well.

Sometimes, however, you want to use KEYFLD on OPNQRYF to change the keys that you access so that they're different from the actual file. When you do this, you have a problem because the external definition that the program picks up isn't the same as the one that OPNQRYF presents to it at runtime.

The solution is to create a "dummy" file. This is an empty file that contains the right record format and key list but has no data.

For example, let's say I want to chain to my CUSTMAS file by zip code. To do that, I create a dummy file named CUSTZIP, and it uses the following DDS:

     A          R CUSTMASF
     A            CUSTNO         4S 0
     A            NAME          30A
     A            ADDRESS       30A
     A            CITY          13A
     A            STATE          2A
     A            ZIPCODE        5S 0
     A            STATUS         1A
     A          K ZIPCODE

I compile this file as just an empty file with a different name from that of my CUSTMAS file. For example:

CRTPF FILE(CUSTZIP) SRCFILE(xxx/QDDSSRC)

When I write my RPG program, I use CUSTZIP on the F-spec. That way, the RPG compiler pulls its external definition and key information from the CUSTZIP file.

     FCUSTZIP   IF   E           K DISK
     D Key             s                   like(ZipCode)

      /free

          Key = 90120;
          chain Key CUSTZIP;
          if %found;
 . . . hurray! Zip code found! 
          endif;

      /end-free

In the CL program that calls this RPG program, I tell it to override the CUSTZIP file to the actual CUSTMAS file, and I run the query on that. In the query, I specify the zip code as the key field. For example:

PGM

    OVRDBF FILE(CUSTZIP) TOFILE(CUSTMAS) SHARE(*YES)

    OPNQRYF FILE((CUSTMAS)) FORMAT(CUSTZIP) +
            QRYSLT('STATUS = "A"') KEYFLD((ZIPCODE))

    CALL RPGPGM

    CLOF CUSTMAS
    DLTOVR CUSTMAS
ENDPGM

This way, the format in the RPG program and in the OPNQRYF match, and random access works properly.

© 2010 Penton Media, Inc.

Source URL: http://systeminetwork.com/article/opnqryf-and-random-access

Links:
[1] http://systeminetwork.com/author/scott-klement