Files always are processed with certain assumptions. Certain conditions are taken for granted. For example, when you execute a program that reads records from a database file, the system feeds the program the first member of the file, no matter how many members are in the file.
These assumptions may not reflect what you want to do, however. In some cases you could change the file with one of the CHG XXX F commands, but doing so would change the file for all jobs on the system and, unless you change the file back, the file stays changed forever.
The alternative is to override the file. A file override is a temporary and local-ized change in the file. When you override a file, the change you are making is taken into account only by the job you are running. The file itself is not changed. Other jobs that are running are not affected.
A number of OVRXXX F commands exist; practically one for each type of file. For example, an OVRDSPF command overrides a display file, and OVRPRTF overrides a printer file. There is no OVRPF or OVRLF for physical files and logical files, however. They are combined into the Override with Database File (OVRDBF) command.
Each override file command has a different set of parameters because each type of file has different requirements and attributes that can be overridden. For example, although it makes sense to override a database file so that member ABC is used instead of the first member, it would not make sense to perform an identical override to a display file because display files have no members. Therefore, the OVRDBF file has a MBR parameter, but the OVRDSPF does not.
File overrides typically begin when you execute the appropriate OVR XXX F com-mand and end when the program (or request level) ends. For example, if you run a CL program that performs an OVRDBF command, the override stays in effect until the CL program ends. Note that it remains in effect in any program the CL program may call.
If program A overrides file X and then calls program B, file X is still overridden throughout the execution of B. When control returns to A, the file is still overrid-den. When program A ends, the file is no longer overridden.
Another way to end an override is by executing the Delete Override (DLTOVR) command. This command deletes all overrides you have performed on a file, or on all files.
Overrides also accumulate from one program level to the next. For instance, program A overrides database file INVENTORY so that member CHICAGO is processed:
OVRDBF FILE(INVENTORY) MBR(CHICAGO)
Program A now calls program B, which overrides the same file to block sequential reads in chunks of 100 records:
For ILE programs the behavior of overrides is different, and this is discussed at length in ILE programming guides. The override scope can also be set to *JOB, which leaves the override in effect until the end of the job, as opposed to the end of the program.
OVRDBF FILE(INVENTORY) SEQONLY(*YES 100)
By then, file INVENTORY has two overrides in effect: MBR(CHICAGO) and SEQONLY(*YES 100). Both overrides have accumulated. If you want the second override to replace the first, rather than accumulate, you need to add the secure(*YES) parameter to the second OVRDBF.
Overriding files is a tricky business. File overrides don't always work as you might anticipate. Here are some things to watch out for:
If the same program issues two OVRXXX F commands to the same file, the second override replaces the first one. For example, if you override a printer file (OVRPRTF) first with LPI(4) and then with CPI(15), CPI(15) is the result.
If program A calls program B and both programs override the same attribute of the same file, the override issued by program B is ignored. For example, if program A overrides a printer file with LPI(4) and program B overrides it with LPI(8), the result is LPI(4). Both programs are overriding the same attribute (LPI). If you want to make sure that pro-gram B's override applies, add SECURE(*YES) to the override command.
If program A calls program B and both programs override different attributes of the same file, the overrides accumulate. If you want to isolate B's overrides instead of accumulating the overrides of both programs, add SECURE(*YES).
If program A calls program B, and A overrides a file, program B cannot use the Delete Override (DLTOVR) command to remove the overrides because B did not issue them.
The OVRDBF command has quite a few parameters. The following lists some of them and their uses.
TOFILE. If you have a program that uses file ACCOUNT, but you want the program to process file ACCTG, override the file as follows:
OVRDBF FILE(ACCOUNT) TOFILE(ACCTG)
The TOFILE parameter contains the real name of the file you will be processing. The FILE parameter is the name with which the program knows the file. The TOFILE parameter can also be used to point to a particular library, so that the system doesn't use the library list to locate the file. This can be handy in situations where the same file exists in two or more libraries, and you want to process one of them but aren't sure if it is the first one in the library list. Code the following override:
OVRDBF FILE(ACCOUNT) TOFILE(ARLIB/ACCOUNT)
This command ensures that the program processes the ACCOUNT file located in library ARLIB and no other.
MBR. Normally, the system processes the first member in a file, no matter how many members are in the file. If you want to process any member other than the first, you must override the file. Name the member you want to process in the MBR parameter, as follows:
OVRDBF FILE(ACCOUNT) MBR(SANDIEGO)
You can even specify MBR(*ALL) if you want your program to process all records in all the files. If you use such a file in RPG, the LR indicator will not turn on until all records in all members have been read.
POSITION. This parameter lets you set the file pointer in a particular posi-tion, ready for a read operation. For example, *FIRST positions the file pointer at the first record. *RRN and a record number place the pointer at that record. Further, you can use several key values to position the file pointer using keys such as *KEYAE for "key after or equal" to a particular value. This parameter is especially useful when reading a database file in a CL program. With the POSITION parameter, a CL program can read a file randomly by record number, or randomly or sequentially by key.
SHARE. Lets you share the open data path (ODP) of a database file. See the preceding section for a description of file sharing.
SEQONLY. If your programs are going to read a file sequentially only, you can improve performance by blocking the records in chunks of a certain number of records, such as SEQONLY(*YES 500). With a file overridden this way, the first read operation in the program brings 500 records into the input buffer. The following 499 reads pull the records from the buffer which, being in memory, is much faster than a disk I/O.
Knowing how many records to block can be tricky. As a general rule, block your records so that each block is close to (but not over) 128 KB (131,072 bytes). For example, suppose you are going to process a file sequentially, and its record length is 300 bytes. Divide 131,072 by 300 to get an optimum block size of 436 records. You would, therefore, use SEQONLY(*YES 436).