OVRDBF
(Override with Database File) is a CL command on IBM i that lets you change how a program opens a file without changing or recompiling the program.
It’s one of the most powerful tools in IBM i operations and testing.
๐ง What is OVRDBF?
When an RPG/COBOL/CL program opens a file (either at runtime or implicitly when the program starts), IBM i looks for any file override in effect.
If you use OVRDBF
, you can redirect that file to:
-
A different physical/logical file
-
A different library
-
A different member
-
With different attributes (e.g., shared ODP, LVLCHK, SEQONLY, etc.)
Overrides stay active until the file is closed, the job ends, or you delete them (DLTOVR
).
โ
Common Uses of OVRDBF
Use Case | Example |
---|---|
Redirect file to another library | Test program against TESTLIB/ORDERS instead of PRODLIB/ORDERS |
Read specific member | OVRDBF FILE(SALESF) TOFILE(SALESF) MBR(JAN2024) |
Disable level check | OVRDBF FILE(CUSTF) LVLCHK(*NO) (bypass record format mismatch) |
Performance tuning | OVRDBF FILE(SALESF) SEQONLY(*YES 100) (read-ahead optimization) |
Share ODPs across programs | OVRDBF FILE(ORDERS) SHARE(*YES) |
SQL redirection | Forces SQL embedded programs to use test files without recompilation |
๐ Syntax
OVRDBF FILE(file-name) TOFILE(library/file)
MBR(member)
LVLCHK(*YES | *NO)
SHARE(*YES | *NO)
SEQONLY(*YES nnn | *NO)
OVRSCOPE(*JOB | *ACTGRP | *CALLLVL)
๐งพ Examples
1. Redirect to another library
OVRDBF FILE(CUSTFILE) TOFILE(TESTLIB/CUSTFILE)
CALL PGM(MYLIB/ORDRPGM)
DLTOVR FILE(CUSTFILE)
2. Read a specific member
OVRDBF FILE(SALESF) TOFILE(SALESF) MBR(FEB2025)
CALL PGM(MYLIB/SALESPGM)
3. Disable level check (careful!)
OVRDBF FILE(CUSTF) LVLCHK(*NO)
CALL PGM(MYLIB/CUSTPGM)
4. Performance optimization (sequential read ahead)
OVRDBF FILE(ORDERS) SEQONLY(*YES 200)
CALL PGM(MYLIB/REPORTPGM)
5. Share ODP across programs in same activation group
OVRDBF FILE(ORDERS) SHARE(*YES)
CALL PGM(MYLIB/PGM1)
CALL PGM(MYLIB/PGM2) /* continues reading ORDERS */
โ ๏ธ Things to Know
-
Scope (
OVRSCOPE
)-
*JOB
→ override applies to whole job until deleted -
*CALLLVL
→ applies only until current call stack level ends (common default) -
*ACTGRP
→ persists within activation group
-
-
*LVLCHK(NO) bypasses record format checks — only use in emergencies/testing.
-
Always
DLTOVR
after use to avoid polluting the job environment.
โ When to Use OVRDBF vs. Recompile
-
Use OVRDBF when testing with different data, bypassing errors, or redirecting files temporarily.
-
Recompile when the change is permanent (new file, new format, etc.).
Awesome—here’s a clean, multi-member file + OVRDBF pattern so the same program can run over different months without recompiling.
1) Create a multi-member PF (once)
CRTPF FILE(MYLIB/SALESF) SRCFILE(MYLIB/QDDSSRC) /* DDS with R SALESREC ... */
ADDPFM FILE(MYLIB/SALESF) MBR(JAN2025)
ADDPFM FILE(MYLIB/SALESF) MBR(FEB2025)
ADDPFM FILE(MYLIB/SALESF) MBR(MAR2025)
/* Load or copy data into each member as needed */
CPYF FROMFILE(PRODLIB/SALESJAN) TOFILE(MYLIB/SALESF) TOMBR(JAN2025) MBROPT(*REPLACE)
2) Your RPG program (unchanged)
// SALESRPT.RPGLE
ctl-opt dftactgrp(*no) actgrp(*caller);
dcl-f SALESF usage(*input) keyed; // NO member hardcoded
dcl-s tot packed(15:2);
dou %eof(SALESF);
read SALESF;
if not %eof(SALESF);
tot += AMOUNT;
endif;
enddo;
dsply ('Total = ' + %char(tot));
*inlr = *on; return;
Program just reads
SALESF
. Which member it uses will be decided by OVRDBF.
3) CL wrapper that picks the month (member) at run time
/* RUNSALESRPT - call with a member name (e.g., JAN2025) */
PGM PARM(&MBR)
DCL &MBR *CHAR 10
/* Scope: only for this call level */
OVRDBF FILE(SALESF) TOFILE(MYLIB/SALESF) MBR(&MBR) OVRSCOPE(*CALLLVL)
/* Optional tuning if reading sequentially */
OVRDBF FILE(SALESF) SEQONLY(*YES 200)
CALL PGM(MYLIB/SALESRPT)
/* Clean up */
DLTOVR FILE(SALESF)
ENDPGM
Usage:
CALL RUNSALESRPT PARM('JAN2025')
CALL RUNSALESRPT PARM('FEB2025')
4) Batch: loop months without code changes
PGM
DCL &LIST *CHAR 60 VALUE('JAN2025 FEB2025 MAR2025')
DCL &MBR *CHAR 10
DCL &POSN *DEC (5 0) VALUE(1)
LOOP:
CHGVAR &MBR %SST(&LIST &POSN 7)
IF (&MBR *EQ ' ') THEN(GOTO END)
OVRDBF FILE(SALESF) TOFILE(MYLIB/SALESF) MBR(&MBR) OVRSCOPE(*CALLLVL)
CALL PGM(MYLIB/SALESRPT)
DLTOVR FILE(SALESF)
CHGVAR &POSN (&POSN + 8)
GOTO LOOP
END:
ENDPGM
5) Notes that save headaches
-
Scope:
OVRSCOPE(*CALLLVL)
is safest; it disappears when the program returns. Use*JOB
only if you truly need it job-wide. -
Keyed/sequential: With keyed reads, remember the ODP/cursor can be shared if you set
SHARE(*YES)
and run programs in the same activation group. -
SEQONLY:
SEQONLY(*YES n)
speeds pure sequential reads (read-ahead). -
LVLCHK(*NO)
: only for emergencies. Prefer recompiles over bypassing level check. -
SQL programs: Embedded SQL respects the override at open time; you don’t need SQL changes. (Member is driven by the OS file open, which the override controls.)
-
Clean exit: End RPG with
*inlr = *on; return;
so the file closes and the ODP resets for the next run.