Most programmers I've spoken with use QTEMP whenever they need a temporary work file in an application. Why not, after all? QTEMP is meant to be used for temporary stuff anyway. The big advantage of using QTEMP is that it's unique to each job and it's gone as soon as the job ends.
Using QTEMP has one slight disadvantage, however. It requires you to create the file each time you need it. If your work files are flat (without field definitions) and intended to be used as program-described files, that's no hardship. In the AS/400 world, however, most programmers would rather work with externally described files.
This means that you'd have to keep the source DDS for your work files somewhere (and it can't be QTEMP!). If a programmer realizes that those source members have no corresponding objects, the programmer may believe the source code to be obsolete and remove it from the system. Next time you attempt to create the work file in QTEMP, the program fails.
There's a good alternative: create your work files in one of your production libraries (preferably the same library you use for the programs and actual database files), and leave them there, permanently. The work file can have a rich field definition provided by complicated DDS, including references to permanent database files, edit codes, the works. You can even create logical files (even join files) on top of your work files!
This we may call a permanent work file. Because they're not in QTEMP, any job can access them--and this presents a problem since two or more jobs could have a legitimate need to write records to the same work file. How do you tell apart the data from the two jobs? The answer is, fortunately, quite simple: use a different member for each job's data.
It's not hard to do. Your permanent work file must be created with MAXMBRS(*NOMAX) to allow multiple members. Then each time a job needs to write to the file, add a member with the ADDPFM command. When the job is near completion, remove the member with the RMVM command.
Since each member must have a different name, you can name the member as 'JOBnnnnnn' where nnnnnn is the six-character job number--which you can retrieve with the RTVJOBA command, specifying NBR(&JOBNBR). Last, but not least, you must remember to override the permanent work file with the OVRDBF command so that all programs that follow reference the member just added.
It sounds complicated--and it is--but it works more efficiently than using QTEMP. To simplify the task, you can use the Add Work File Member (ADDWRKFMBR) command and the Remove Work File Member (RMVWRKFMBR) command listed in1a and 1b. 1c shows CL program WRKF001CL.
It sounds complicated--and it is--but it works more efficiently than using QTEMP. To simplify the task, you can use the Add Work File Member (ADDWRKFMBR) command and the Remove Work File Member (RMVWRKFMBR) command listed in Figures 1a and 1b. Figure 1c shows CL program WRKF001CL.
Here's an example of how to use it:
ADDWRKFMBR FILE(workfile) OVERRIDE(*YES) CALL PGM(PGM1) CALL PGM(PGM2) RMVWRKFMBR FILE(workfile)
The ADDWRKFMBR command has an optional parameter, RTNMBR, in which you can enter a 10-character CL variable. If used, ADDWRKFMBR returns to the CL variable the name of the member it just added.
TechTalk: Using Permanent Work Files
Figure 1A Command ADDWRKFMBR
ADDWRKFMBR: CMD PROMPT('Add Work File Member') PARM KWD(FILE) TYPE(Q1) MIN(1) PROMPT('Work file + name') PARM KWD(OVERRIDE) TYPE(*CHAR) LEN(4) RSTD(*YES) + DFT(*YES) VALUES(*YES *NO) + PROMPT('Override to new member') PARM KWD(RTNMBR) TYPE(*CHAR) LEN(10) RTNVAL(*YES) + PMTCTL(*PMTRQS) PROMPT('CL var for new + member (10)') PARM KWD(ACTION) TYPE(*CHAR) LEN(4) CONSTANT(*ADD) Q1: QUAL TYPE(*NAME) LEN(10) MIN(1) QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) + SPCVAL((*LIBL) (*CURLIB)) PROMPT('Library')
TechTalk: Using Permanent Work Files
Figure 1B Command RMVWRKFMBR
RMVWRKFMBR: CMD PROMPT('Remove Work File Member') PARM KWD(FILE) TYPE(Q1) MIN(1) PROMPT('Work file + name') PARM KWD(OVERRIDE) TYPE(*ZEROELEM) PARM KWD(RTNMBR) TYPE(*ZEROELEM) PARM KWD(ACTION) TYPE(*CHAR) LEN(4) CONSTANT(*RMV) Q1: QUAL TYPE(*NAME) LEN(10) MIN(1) QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) + SPCVAL((*LIBL) (*CURLIB)) PROMPT('Library')
TechTalk: Using Permanent Work Files
Figure 1C CL program WRKF001CL
WRKF001CL: + PGM PARM(&QFILE &OVERRIDE &RTNMBR &ACTION) DCL VAR(&ACTION) TYPE(*CHAR) LEN(4) DCL VAR(&FILE) TYPE(*CHAR) LEN(10) DCL VAR(&JOBNBR) TYPE(*CHAR) LEN(6) DCL VAR(&LIB) TYPE(*CHAR) LEN(10) DCL VAR(&MBRNAME) TYPE(*CHAR) LEN(10) DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(80) DCL VAR(&MSGF) TYPE(*CHAR) LEN(10) DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10) DCL VAR(&MSGID) TYPE(*CHAR) LEN(7) DCL VAR(&OVERRIDE) TYPE(*CHAR) LEN(4) DCL VAR(&QFILE) TYPE(*CHAR) LEN(20) DCL VAR(&RTNMBR) TYPE(*CHAR) LEN(10) MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(SNDERRMSG)) /* Determine name of member */ CHGVAR VAR(&FILE) VALUE(%SST(&QFILE 1 10)) CHGVAR VAR(&LIB) VALUE(%SST(&QFILE 11 10)) RTVJOBA NBR(&JOBNBR) CHGVAR VAR(&MBRNAME) VALUE('JOB' *CAT &JOBNBR) CHGVAR VAR(&RTNMBR) VALUE(&MBRNAME) MONMSG MSGID(MCH3601) /* Add or remove member as needed */ IF COND(&ACTION *EQ '*ADD') THEN(ADDPFM FILE(&LIB/&FILE) + MBR(&MBRNAME)) ELSE CMD(RMVM FILE(&LIB/&FILE) MBR(&MBRNAME)) /* Override if necessary */ IF COND(&OVERRIDE *EQ '*YES') THEN(OVRDBF FILE(&FILE) + TOFILE(&LIB/&FILE) MBR(&MBRNAME)) GOTO CMDLBL(ENDPGM) /* Send error message */ SNDERRMSG: + RCVMSG MSGTYPE(*EXCP) MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + MSGFLIB(&MSGFLIB) SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) MSGDTA(&MSGDTA) + MSGTYPE(*ESCAPE) /* End program */ ENDPGM: + ENDPGM
LATEST COMMENTS
MC Press Online