Troubleshooting
Problem
This document provides source for an example program that checks each physical file or table of a library for damaged rows or records.
Also see TechNote Recovering Records from Damaged Files and Index Check Tool for checking access path issues.
Resolving The Problem
This document provides source for an example program that checks each physical file or table of a library for damaged rows or records. Assistance with this sample program is beyond the scope of Support Line service.
The Check Damage on Physical Files (CHKPF) command allows you to check each physical file or table of a library for rows or records that cannot be read by the operating system. The command runs over a specific library or all libraries on the system. The command checks only the physical files and report errors. It does not perform any recovery action.
CHKPF only checks the record level structures. It doesn't check the integrity of field level data. CHKPF will determine if the DENT byte for a record is a valid value or not. If not then the record will be flagged damaged. But there can be instances of the DENT byte value being valid however due to data shifting or other problems, the actual data located within fields my not be valid for the specific data type anymore. CHKPF cannot determine these instances where the field data is no longer valid for the data type. Only by mapping this data back into the same data types would it cause data mapping errors. Since the CHKPF does not write the data back into a similar file, this level of damage is not detected. There are no IBM tools to determine this level of damage. No errors, VLOGs, or tools would indicate. Only by customer or someone familiar with the data manually looking through the data could errors like this be noticed.
So to be clear, CHKPF will not detect field level damage where the data may no longer be valid for the data type of the field. It also will not detect any corruption of data in fields such that the data value is still valid for the field, but no longer the same as what it was prior to the damage.
The command will not look for damage in other file systems (for example, /QDLS, or /QNTS or /QOPT) nor will it scan for damage to other object types. This source provided here is a more robust version of the example provided in APAR II10690. Use SNDPTFORD to get the cover letter for II10690.
The CHKPF command uses the system cross-reference file (QADBXREF in library QSYS) to determine the physical files to be checked for each library. If the system cross-reference file is damaged, this command does not run. The Reclaim Database Cross Reference files (RCLDBXREF *FIX) or Reclaim Storage (RCLSTG SELECT(*DBXREF)) command must be run to correct the system cross-reference files prior to running the CHKPF command.
The CHKPF command can be run in batch or interactively. Physical files that are found to have unreadable rows are identified by a message sent to the user profile message queue of the user profile running or submitting the CHKPF command. Physical files that are identified with unreadable records should be reviewed individually prior to performing any damage recovery. Refer to the Backup and Recovery Guide for the appropriate recovery technique.
Creating the CHKPF Command
To create the CHKPF command, do the following:
Running CHKPF creates a spooled file for each file tested. If no errors are found, the spooled file is empty. The joblog can also report message CPC2957 - No records copied. This means that the records are not damaged. If the damage is at the file level, the joblog shows the message CPD3244 - File nnnnnn in Library mmmmmm is damaged. If a library does not have any files in it, no messages will be issued.
The Check Damage on Physical Files (CHKPF) command allows you to check each physical file or table of a library for rows or records that cannot be read by the operating system. The command runs over a specific library or all libraries on the system. The command checks only the physical files and report errors. It does not perform any recovery action.
CHKPF only checks the record level structures. It doesn't check the integrity of field level data. CHKPF will determine if the DENT byte for a record is a valid value or not. If not then the record will be flagged damaged. But there can be instances of the DENT byte value being valid however due to data shifting or other problems, the actual data located within fields my not be valid for the specific data type anymore. CHKPF cannot determine these instances where the field data is no longer valid for the data type. Only by mapping this data back into the same data types would it cause data mapping errors. Since the CHKPF does not write the data back into a similar file, this level of damage is not detected. There are no IBM tools to determine this level of damage. No errors, VLOGs, or tools would indicate. Only by customer or someone familiar with the data manually looking through the data could errors like this be noticed.
So to be clear, CHKPF will not detect field level damage where the data may no longer be valid for the data type of the field. It also will not detect any corruption of data in fields such that the data value is still valid for the field, but no longer the same as what it was prior to the damage.
The command will not look for damage in other file systems (for example, /QDLS, or /QNTS or /QOPT) nor will it scan for damage to other object types. This source provided here is a more robust version of the example provided in APAR II10690. Use SNDPTFORD to get the cover letter for II10690.
| Caution: This program may not be included in programs for resale. The source is provided as is. IBM offers a consulting agreement to assist with implementing this program, or contact your software service provider for assistance. |
The CHKPF command uses the system cross-reference file (QADBXREF in library QSYS) to determine the physical files to be checked for each library. If the system cross-reference file is damaged, this command does not run. The Reclaim Database Cross Reference files (RCLDBXREF *FIX) or Reclaim Storage (RCLSTG SELECT(*DBXREF)) command must be run to correct the system cross-reference files prior to running the CHKPF command.
The CHKPF command can be run in batch or interactively. Physical files that are found to have unreadable rows are identified by a message sent to the user profile message queue of the user profile running or submitting the CHKPF command. Physical files that are identified with unreadable records should be reviewed individually prior to performing any damage recovery. Refer to the Backup and Recovery Guide for the appropriate recovery technique.
Creating the CHKPF Command
To create the CHKPF command, do the following:
| 1. | Create a source member of type TXT (CRTSRCPF) called CHKPF in source file QTXTSRC of library QGPL. Update the source member with the following statement: CREATE TABLE QGPL/CHKPF (DBXLIB CHAR (10) NOT NULL WITH DEFAULT, DBXFIL CHAR (10) NOT NULL WITH DEFAULT) |
| 2. | Create table CHKPF in library QGPL by running the SQL statement entered into source member CHKPF: RUNSQLSTM SRCFILE(QGPL/QTXTSRC) SRCMBR(CHKPF) COMMIT(*NONE) |
| 3. | Create a source member of type CLP called CHKPF in source file QCLSRC of library QGPL. Update the source member with the following statements: If you have the QMGTOOLS (MustGather Tools) library on your IBM i (see this TechNote for information on QMGTOOLS) you may already have this source. Here's how to check a) ADDLIBLE QMGTOOLS b) GO MG c) 12. Display build date - if you have a "Build date and version" of 26Mar2016 or later, continue to (d) d) WRKMBRPDM QMGTOOLS/QMGDBSQL Else, here's the source you can copy and paste |
/* THE CHKPF COMMAND WILL USE CPYF TO READ EVERY RECORD OF EVERY */
/* PHYSICAL FILE OR TABLE OF A LIBRARY OR ALL LIBRARIES ON THE */
/* SYSTEM. UPON COMPLETION ANY PF'S WITH DATA ERRORS WILL BE */
/* IDENTIFIED. THESE PF'S SHOULD BE REVIEWED FOR POSSIBLE INVALID */
/* DATA CONTENTS OR DAMAGE. */
PGM PARM(&LIBRARY)
DCL VAR(&LIBRARY) TYPE(*CHAR) LEN(10)
DCL VAR(&MSGTXT) TYPE(*CHAR) LEN(512)
DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
DCL VAR(&MSGKEY) TYPE(*CHAR) LEN(4) VALUE('9999')
DCL VAR(&MSGTXT1) TYPE(*CHAR) LEN(256)
DCL VAR(&PFCNT) TYPE(*DEC) LEN(9 0)
DCL VAR(&PFCNTA) TYPE(*CHAR) LEN(9)
DCL VAR(&PFERR) TYPE(*DEC) LEN(9 0)
DCL VAR(&PFERRA) TYPE(*CHAR) LEN(9)
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
/* FILE CHKPF MUST BE CREATED PRIOR TO COMPILING THIS CL PROGRAM. */
DCLF FILE(CHKPF)
/* MESSAGES OF FAILING FILES ARE SENT TO THE JOB'S USER PROFILE. */
RTVJOBA USER(&USER)
/* VALIDATE THE LIBRARY NAME. */
IF COND(&LIBRARY *NE '*ALL') THEN(DO)
CHKOBJ OBJ(&LIBRARY) OBJTYPE(*LIB)
MONMSG MSGID(CPF0000) EXEC(DO)
CHGVAR VAR(&MSGTXT) VALUE('Library ' *CAT &LIBRARY +
*BCAT 'not found or not available.')
SNDPGMMSG MSG(&MSGTXT) TOPGMQ(*PRV) TOMSGQ(*TOPGMQ) +
MSGTYPE(*COMP)
GOTO CMDLBL(ENDOFPGM)
ENDDO
ENDDO
/* OPEN THE SYSTEM CROSS REFERENCE FILE FOR PROCESSING OF PF'S. */
OVRDBF FILE(QADBXREF)
IF COND(&LIBRARY *EQ '*ALL') THEN(DO)
OPNQRYF FILE((QSYS/QADBXREF)) OPTION(*INP) +
FORMAT(QGPL/CHKPF) QRYSLT('DBXATR = +
%VALUES("PF" "TB")') KEYFLD(*FILE)
ENDDO
ELSE CMD(DO)
OPNQRYF FILE((QSYS/QADBXREF)) OPTION(*INP) +
FORMAT(QGPL/CHKPF) QRYSLT('DBXLIB = ''' +
*CAT &LIBRARY *CAT ''' *AND DBXATR = +
%VALUES("PF" "TB")') KEYFLD(*FILE)
ENDDO
/* OUTPUT THE PF'S TO BE CHECKED TO THE CHKPF FILE. */
DLTF FILE(QTEMP/CHKPF)
MONMSG MSGID(CPF0000)
CRTDUPOBJ OBJ(CHKPF) FROMLIB(QGPL) OBJTYPE(*FILE) +
TOLIB(QTEMP)
CPYFRMQRYF FROMOPNID(QADBXREF) TOFILE(QTEMP/CHKPF) +
MBROPT(*REPLACE) FMTOPT(*NOCHK)
CLOF OPNID(QADBXREF)
DLTOVR FILE(QADBXREF)
/* PROCESS THE RECORDS IN THE CHKPF FILE. */
OVRDBF FILE(CHKPF) TOFILE(QTEMP/CHKPF)
READ: DLTF FILE(QTEMP/&DBXFIL)
/* PHYSICAL FILE OR TABLE OF A LIBRARY OR ALL LIBRARIES ON THE */
/* SYSTEM. UPON COMPLETION ANY PF'S WITH DATA ERRORS WILL BE */
/* IDENTIFIED. THESE PF'S SHOULD BE REVIEWED FOR POSSIBLE INVALID */
/* DATA CONTENTS OR DAMAGE. */
PGM PARM(&LIBRARY)
DCL VAR(&LIBRARY) TYPE(*CHAR) LEN(10)
DCL VAR(&MSGTXT) TYPE(*CHAR) LEN(512)
DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
DCL VAR(&MSGKEY) TYPE(*CHAR) LEN(4) VALUE('9999')
DCL VAR(&MSGTXT1) TYPE(*CHAR) LEN(256)
DCL VAR(&PFCNT) TYPE(*DEC) LEN(9 0)
DCL VAR(&PFCNTA) TYPE(*CHAR) LEN(9)
DCL VAR(&PFERR) TYPE(*DEC) LEN(9 0)
DCL VAR(&PFERRA) TYPE(*CHAR) LEN(9)
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
/* FILE CHKPF MUST BE CREATED PRIOR TO COMPILING THIS CL PROGRAM. */
DCLF FILE(CHKPF)
/* MESSAGES OF FAILING FILES ARE SENT TO THE JOB'S USER PROFILE. */
RTVJOBA USER(&USER)
/* VALIDATE THE LIBRARY NAME. */
IF COND(&LIBRARY *NE '*ALL') THEN(DO)
CHKOBJ OBJ(&LIBRARY) OBJTYPE(*LIB)
MONMSG MSGID(CPF0000) EXEC(DO)
CHGVAR VAR(&MSGTXT) VALUE('Library ' *CAT &LIBRARY +
*BCAT 'not found or not available.')
SNDPGMMSG MSG(&MSGTXT) TOPGMQ(*PRV) TOMSGQ(*TOPGMQ) +
MSGTYPE(*COMP)
GOTO CMDLBL(ENDOFPGM)
ENDDO
ENDDO
/* OPEN THE SYSTEM CROSS REFERENCE FILE FOR PROCESSING OF PF'S. */
OVRDBF FILE(QADBXREF)
IF COND(&LIBRARY *EQ '*ALL') THEN(DO)
OPNQRYF FILE((QSYS/QADBXREF)) OPTION(*INP) +
FORMAT(QGPL/CHKPF) QRYSLT('DBXATR = +
%VALUES("PF" "TB")') KEYFLD(*FILE)
ENDDO
ELSE CMD(DO)
OPNQRYF FILE((QSYS/QADBXREF)) OPTION(*INP) +
FORMAT(QGPL/CHKPF) QRYSLT('DBXLIB = ''' +
*CAT &LIBRARY *CAT ''' *AND DBXATR = +
%VALUES("PF" "TB")') KEYFLD(*FILE)
ENDDO
/* OUTPUT THE PF'S TO BE CHECKED TO THE CHKPF FILE. */
DLTF FILE(QTEMP/CHKPF)
MONMSG MSGID(CPF0000)
CRTDUPOBJ OBJ(CHKPF) FROMLIB(QGPL) OBJTYPE(*FILE) +
TOLIB(QTEMP)
CPYFRMQRYF FROMOPNID(QADBXREF) TOFILE(QTEMP/CHKPF) +
MBROPT(*REPLACE) FMTOPT(*NOCHK)
CLOF OPNID(QADBXREF)
DLTOVR FILE(QADBXREF)
/* PROCESS THE RECORDS IN THE CHKPF FILE. */
OVRDBF FILE(CHKPF) TOFILE(QTEMP/CHKPF)
READ: DLTF FILE(QTEMP/&DBXFIL)
MONMSG MSGID(CPF0000 CPD0000)
RCVF
MONMSG MSGID(CPF0864) EXEC(GOTO CMDLBL(ENDREAD))
CHGVAR VAR(&PFCNT) VALUE(&PFCNT + 1)
IF COND(&DBXFIL *EQ 'CHKPF') THEN(GOTO +
CMDLBL(READ))
/* DELETE THE FILE IN QTEMP IF IT EXISTS. */
DLTF FILE(QTEMP/&DBXFIL)
MONMSG MSGID(CPF2105)
/* CHECK THE PF BY COPYING IT TO A NEW FILE IN QTEMP. */
CPYF FROMFILE(&DBXLIB/&DBXFIL) +
TOFILE(QTEMP/&DBXFIL) FROMMBR(*ALL) +
TOMBR(*FROMMBR) MBROPT(*REPLACE) +
CRTFILE(*YES) FROMRCD(1) +
INCCHAR(*RCD 1 *EQ '@#$%') +
ERRLVL(0)
/* ACCEPT EXPECTED ERROR CONDITIONS AND CONTINUE. */
MONMSG MSGID(CPF2817) EXEC(DO)
RCVMSG MSGTYPE(*LAST) RMV(*NO) KEYVAR(&MSGKEY) /* +
Message CPF2817. */
RECEIVE: RCVMSG MSGTYPE(*PRV) MSGKEY(&MSGKEY) +
KEYVAR(&MSGKEY) MSG(&MSGTXT1) +
MSGID(&MSGID) /* Actual failing message +
ID. */
IF COND(&MSGID *EQ 'CPF2868') THEN(GOTO +
CMDLBL(READ)) /* No members in file. */
IF COND(&MSGID *EQ 'CPF2883') THEN(GOTO +
CMDLBL(RECEIVE)) /* Generic create error. */
IF COND(&MSGID *EQ 'CPF320B') THEN(GOTO +
CMDLBL(READ)) /* Data dictionary file. */
IF COND(&MSGID *EQ 'CPF2833') THEN(GOTO +
CMDLBL(TEST1)) /* Record length < 4. */
IF COND(&MSGID *EQ 'CPF2869') THEN(GOTO +
CMDLBL(READ)) /* Empty member. */
GOTO CMDLBL(SNDERROR)
ENDDO
MONMSG MSGID(CPF2952) EXEC(DO)
RCVMSG MSGTYPE(*LAST) RMV(*NO) KEYVAR(&MSGKEY) /* +
Message CPF2952. */
RCVMSG MSGTYPE(*PRV) MSGKEY(&MSGKEY) +
KEYVAR(&MSGKEY) MSG(&MSGTXT1) +
MSGID(&MSGID) /* Actual failing message +
ID. */
IF COND(&MSGID *EQ 'CPF4234') THEN(GOTO +
CMDLBL(READ)) /* I/O not allowed. */
GOTO CMDLBL(SNDERROR)
ENDDO
/* REPORT PF ERROR FOR ALL OTHER MESSAGE ID'S. */
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
GOTO CMDLBL(READ)
/* RETEST CPYF IF RECORD LENGTH IS LESS THAN 4. */
TEST1: CPYF FROMFILE(&DBXLIB/&DBXFIL) +
TOFILE(QTEMP/&DBXFIL) FROMMBR(*ALL) +
TOMBR(*FROMMBR) MBROPT(*REPLACE) +
CRTFILE(*YES) FROMRCD(1) +
INCCHAR(*RCD 1 *EQ '@') +
ERRLVL(0)
/* REPORT PF ERROR FOR ANY ERROR MESSAGE. */
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
GOTO CMDLBL(READ)
/* DETERMINE FAILING ERROR MESSAGE. */
ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) KEYVAR(&MSGKEY)
RCVMSG MSGTYPE(*PRV) MSGKEY(&MSGKEY) +
KEYVAR(&MSGKEY) MSG(&MSGTXT1) +
MSGID(&MSGID)
/* SEND PF ERROR MESSAGE TO THE JOB'S USER PROFILE MESSAGE QUEUE. */
SNDERROR: CHGVAR VAR(&MSGTXT) VALUE('Error on file ' *CAT +
&DBXFIL *BCAT 'in library ' *CAT &DBXLIB +
*TCAT '. Failing message is ' *CAT &MSGID +
*BCAT ': ' *CAT &MSGTXT1)
SNDMSG MSG(&MSGTXT) TOUSR(&USER)
MONMSG MSGID(CPF0000)
/* SEND PF ERROR MESSAGE TO THE JOB'S PROGRAM MESSAGE QUEUE. */
CHGVAR VAR(&PFERR) VALUE(&PFERR + 1)
CHGVAR VAR(&MSGTXT) VALUE('File ' *CAT &DBXFIL +
*BCAT 'in library ' *CAT &DBXLIB *BCAT +
'in error.')
SNDPGMMSG MSG(&MSGTXT) TOPGMQ(*PRV) TOMSGQ(*TOPGMQ) +
MSGTYPE(*DIAG)
GOTO CMDLBL(READ)
/* SEND FILE COUNT MESSAGES TO THE JOB'S PROGRAM MESSAGE QUEUE. */
ENDREAD: CHGVAR VAR(&PFCNTA) VALUE(&PFCNT)
CHGVAR VAR(&MSGTXT) VALUE(&PFCNTA *BCAT 'physical +
files processed for library ' *CAT +
&LIBRARY *TCAT '.')
SNDPGMMSG MSG(&MSGTXT) TOPGMQ(*PRV) TOMSGQ(*TOPGMQ) +
MSGTYPE(*COMP)
IF COND(&PFERR *EQ 0) THEN(DO)
CHGVAR VAR(&MSGTXT) VALUE('No errors found.')
SNDPGMMSG MSG(&MSGTXT) TOPGMQ(*PRV) TOMSGQ(*TOPGMQ) +
MSGTYPE(*COMP)
ENDDO
ELSE CMD(DO)
CHGVAR VAR(&PFERRA) VALUE(&PFERR)
CHGVAR VAR(&MSGTXT) VALUE(&PFERRA *BCAT 'physical +
files were in error for library ' *CAT +
&LIBRARY *TCAT '. Review the previous job +
log messages for additional information.')
SNDPGMMSG MSG(&MSGTXT) TOPGMQ(*PRV) TOMSGQ(*TOPGMQ) +
MSGTYPE(*COMP)
ENDDO
ENDOFPGM: DLTOVR FILE(CHKPF)
ENDPGM
MONMSG MSGID(CPF0864) EXEC(GOTO CMDLBL(ENDREAD))
CHGVAR VAR(&PFCNT) VALUE(&PFCNT + 1)
IF COND(&DBXFIL *EQ 'CHKPF') THEN(GOTO +
CMDLBL(READ))
/* DELETE THE FILE IN QTEMP IF IT EXISTS. */
DLTF FILE(QTEMP/&DBXFIL)
MONMSG MSGID(CPF2105)
/* CHECK THE PF BY COPYING IT TO A NEW FILE IN QTEMP. */
CPYF FROMFILE(&DBXLIB/&DBXFIL) +
TOFILE(QTEMP/&DBXFIL) FROMMBR(*ALL) +
TOMBR(*FROMMBR) MBROPT(*REPLACE) +
CRTFILE(*YES) FROMRCD(1) +
INCCHAR(*RCD 1 *EQ '@#$%') +
ERRLVL(0)
/* ACCEPT EXPECTED ERROR CONDITIONS AND CONTINUE. */
MONMSG MSGID(CPF2817) EXEC(DO)
RCVMSG MSGTYPE(*LAST) RMV(*NO) KEYVAR(&MSGKEY) /* +
Message CPF2817. */
RECEIVE: RCVMSG MSGTYPE(*PRV) MSGKEY(&MSGKEY) +
KEYVAR(&MSGKEY) MSG(&MSGTXT1) +
MSGID(&MSGID) /* Actual failing message +
ID. */
IF COND(&MSGID *EQ 'CPF2868') THEN(GOTO +
CMDLBL(READ)) /* No members in file. */
IF COND(&MSGID *EQ 'CPF2883') THEN(GOTO +
CMDLBL(RECEIVE)) /* Generic create error. */
IF COND(&MSGID *EQ 'CPF320B') THEN(GOTO +
CMDLBL(READ)) /* Data dictionary file. */
IF COND(&MSGID *EQ 'CPF2833') THEN(GOTO +
CMDLBL(TEST1)) /* Record length < 4. */
IF COND(&MSGID *EQ 'CPF2869') THEN(GOTO +
CMDLBL(READ)) /* Empty member. */
GOTO CMDLBL(SNDERROR)
ENDDO
MONMSG MSGID(CPF2952) EXEC(DO)
RCVMSG MSGTYPE(*LAST) RMV(*NO) KEYVAR(&MSGKEY) /* +
Message CPF2952. */
RCVMSG MSGTYPE(*PRV) MSGKEY(&MSGKEY) +
KEYVAR(&MSGKEY) MSG(&MSGTXT1) +
MSGID(&MSGID) /* Actual failing message +
ID. */
IF COND(&MSGID *EQ 'CPF4234') THEN(GOTO +
CMDLBL(READ)) /* I/O not allowed. */
GOTO CMDLBL(SNDERROR)
ENDDO
/* REPORT PF ERROR FOR ALL OTHER MESSAGE ID'S. */
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
GOTO CMDLBL(READ)
/* RETEST CPYF IF RECORD LENGTH IS LESS THAN 4. */
TEST1: CPYF FROMFILE(&DBXLIB/&DBXFIL) +
TOFILE(QTEMP/&DBXFIL) FROMMBR(*ALL) +
TOMBR(*FROMMBR) MBROPT(*REPLACE) +
CRTFILE(*YES) FROMRCD(1) +
INCCHAR(*RCD 1 *EQ '@') +
ERRLVL(0)
/* REPORT PF ERROR FOR ANY ERROR MESSAGE. */
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
GOTO CMDLBL(READ)
/* DETERMINE FAILING ERROR MESSAGE. */
ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) KEYVAR(&MSGKEY)
RCVMSG MSGTYPE(*PRV) MSGKEY(&MSGKEY) +
KEYVAR(&MSGKEY) MSG(&MSGTXT1) +
MSGID(&MSGID)
/* SEND PF ERROR MESSAGE TO THE JOB'S USER PROFILE MESSAGE QUEUE. */
SNDERROR: CHGVAR VAR(&MSGTXT) VALUE('Error on file ' *CAT +
&DBXFIL *BCAT 'in library ' *CAT &DBXLIB +
*TCAT '. Failing message is ' *CAT &MSGID +
*BCAT ': ' *CAT &MSGTXT1)
SNDMSG MSG(&MSGTXT) TOUSR(&USER)
MONMSG MSGID(CPF0000)
/* SEND PF ERROR MESSAGE TO THE JOB'S PROGRAM MESSAGE QUEUE. */
CHGVAR VAR(&PFERR) VALUE(&PFERR + 1)
CHGVAR VAR(&MSGTXT) VALUE('File ' *CAT &DBXFIL +
*BCAT 'in library ' *CAT &DBXLIB *BCAT +
'in error.')
SNDPGMMSG MSG(&MSGTXT) TOPGMQ(*PRV) TOMSGQ(*TOPGMQ) +
MSGTYPE(*DIAG)
GOTO CMDLBL(READ)
/* SEND FILE COUNT MESSAGES TO THE JOB'S PROGRAM MESSAGE QUEUE. */
ENDREAD: CHGVAR VAR(&PFCNTA) VALUE(&PFCNT)
CHGVAR VAR(&MSGTXT) VALUE(&PFCNTA *BCAT 'physical +
files processed for library ' *CAT +
&LIBRARY *TCAT '.')
SNDPGMMSG MSG(&MSGTXT) TOPGMQ(*PRV) TOMSGQ(*TOPGMQ) +
MSGTYPE(*COMP)
IF COND(&PFERR *EQ 0) THEN(DO)
CHGVAR VAR(&MSGTXT) VALUE('No errors found.')
SNDPGMMSG MSG(&MSGTXT) TOPGMQ(*PRV) TOMSGQ(*TOPGMQ) +
MSGTYPE(*COMP)
ENDDO
ELSE CMD(DO)
CHGVAR VAR(&PFERRA) VALUE(&PFERR)
CHGVAR VAR(&MSGTXT) VALUE(&PFERRA *BCAT 'physical +
files were in error for library ' *CAT +
&LIBRARY *TCAT '. Review the previous job +
log messages for additional information.')
SNDPGMMSG MSG(&MSGTXT) TOPGMQ(*PRV) TOMSGQ(*TOPGMQ) +
MSGTYPE(*COMP)
ENDDO
ENDOFPGM: DLTOVR FILE(CHKPF)
ENDPGM
| 4. | Create program CHKPF in library QGPL. Library QGPL must be in your library list: CRTCLPGM PGM(QGPL/CHKPF) SRCFILE(QGPL/QCLSRC) SRCMBR(CHKPF) |
| 5. | Create source member of type CMD CHKPF in source file QCMDSRC of library QGPL. Update the source member with the following statements: CMD PROMPT('Check Damage on Physical Files') PARM KWD(LIBRARY) TYPE(*CHAR) LEN(10) + DFT(*ALL) MIN(0) PROMPT('Library name') |
| 6. | Create command CHKPF in library QGPL: CRTCMD CMD(QGPL/CHKPF) PGM(QGPL/CHKPF) SRCFILE(QGPL/QCMDSRC) SRCMBR(CHKPF) The CHKPF command is now ready for use. Prior to running the CHKPF command for all libraries, it is advisable to verify that the command works by running it for a single library first, for example, QGPL. |
[{"Business Unit":{"code":"BU070","label":"IBM Infrastructure"},"Product":{"code":"SWG60","label":"IBM i"},"Component":"Db2 for i","Platform":[{"code":"PF012","label":"IBM i"}],"Version":"Version Independent","Edition":"","Line of Business":{"code":"LOB68","label":"Power HW"}}]
Historical Number
N1010157
Was this topic helpful?
Document Information
Modified date:
26 November 2024
UID
nas8N1010157