Wednesday, June 19, 2013

CHGPF there's a quirk that can bite your...

The Change Physical File (CHGPF) is a useful command that allows you to change many attributes of a physical file. Many IBM i (AS400) programmers use it to add fields or change the existing fields without having to recompile file. I do too, as I don't have to do the following:

  • Delete all the dependent logical files.
  • Make a copy of the phyiscal file with all the data in it.
  • Delete the phyiscal file.
  • Compile the physical file.
  • Copy the data from the copied file into the pysical file.
  • Delete the copied file.
  • Compile all the dependent logical files.

Generally the rule is in this IT department is that all dependent logical files have the same record format name as the physical. But there are a few odd-ball logical files with a different record format name.

When the physical file was changed using the CHGPF command it caused strange errors in programs that used some of the dependent logical files.

After scratching my head for awhile I worked out what had happened.

In this example I have a physical file, TESTPF, with two dependent logical files, TESTLF and TESTLF2.

The DDS source code for the physical file TESTPF was:

A                                      UNIQUE 
A          R TESTPFR 
A            FLD01          1A         TEXT('First field') 
                                       COLHDG('1st' 'fld')
A            FLD02          1A         TEXT('Second field')
                                       COLHDG('2nd' 'fld')
A          K FLD01

The first logical file, TESTLF, has the same record format name as the phyiscal file:

A          R TESTPFR                   PFILE(TESTPF)
A          K FLD02

The second, TESTLF2. has a different record format name.

A          R TESTLFR                   PFILE(TESTPF)
A            FLD01 
A            FLD02 
A          K FLD01

By using the Display File Field Description (DSPFFD) command to I confirm that the three files are identical, which they are.

           Data        Field  Buffer    Buffer        Field    Column 
Field      Type       Length  Length  Position        Usage    Heading
FLD01      CHAR            1       1         1        Both     1st
                                                               fld
  Field text  . . . . . . . . . . . . . . . :  First field
  Coded Character Set Identifier  . . . . . :     37 
FLD02      CHAR            1       1         2        Both     2nd
                                                               fld
  Field text  . . . . . . . . . . . . . . . :  Second field
  Coded Character Set Identifier  . . . . . :     37

I edit the DDS for TESTPF. I change FLD01 to be 2 alphanumeric, and add a new field called NEW.

A                                      UNIQUE
A          R TESTPFR
A            FLD01          2A         TEXT('First field') 
                                       COLHDG('1st' 'fld') 
A            FLD02          1A         TEXT('Second field')
                                       COLHDG('2nd' 'fld') 
A            NEW            1A         TEXT('New field')
                                       COLHDG('New' 'fld')
A          K FLD01

Now I use Change Physical file (CHGPF) command to make the changes. Fill in the fields on the first screen as shown below, and press Enter.

            Change Physical File (CHGPF) 

 Type choices, press Enter.

 Physical file  . . . . . . . . .   TESTPF    
   Library  . . . . . . . . . . .     MYLIB     
 System . . . . . . . . . . . . .   *LCL     
 Source file  . . . . . . . . . .   QDDSSRC   
   Library  . . . . . . . . . . .     MYLIB     

And I press Enter a second time when the Additional Parameters are displayed.

After running the CHGPF command I go and check the that files changes were successful using DSPFFD. TESTPF and TESTLF have changed:

           Data        Field  Buffer    Buffer        Field    Column
Field      Type       Length  Length  Position        Usage    Heading
FLD01      CHAR            2       2         1        Both     1st
                                                               fld
  Field text  . . . . . . . . . . . . . . . :  First field
  Coded Character Set Identifier  . . . . . :     37
FLD02      CHAR            1       1         3        Both     2nd
                                                               fld
  Field text  . . . . . . . . . . . . . . . :  Second field
  Coded Character Set Identifier  . . . . . :     37
NEW        CHAR            1       1         4        Both     New
                                                               fld
  Field text  . . . . . . . . . . . . . . . :  New field
  Coded Character Set Identifier  . . . . . :     37

Now for the quirk: TESTLF2 is unchanged!

When I move a two character value into FLD01 in either TESTPF or TESTLF, for example ‘12’, only the first character, ‘1’ is displayed in FLD01 in TESTLF2. This could cause big problems for any programs using TESTLF2.

What is causing this? And how can we stop this from happening again?

The cause appears to be that TESTLF2's record format is not the same name as TESTPF's.

One way to fix the problem is to change the record format name in TESTLF2. But TESTLF2 may be designed to only have certain fields in it, and keep the rest unavailable. Once upon a time I built a logical file over the Payroll Employee Master file, it contained only the employee number, name, and department fields. This logical was then used by another application that needed the employees' name and which department they belonged to

I need to identify all of the dependent logical files that do not have the same record format name as the physical file. How do I do this?

First, I would run the Display Data Base Relations (DSPDBR) command. I would just type on a command line:   DSPFD MYLIB/TESTPF   and press Enter. On the screen displayed I type "B" in the Control field and press Enter, to go the bottom of the report. We only care about the ‘Files Dependent on Specified file’ section. In this scenario this is what is displayed:

Files Dependent On Specified File 
  Dependent File         Library       Dependency   JREF    Constraint 
      TESTLF             MYLIB         Data 
      TESTLF2            MYLIB         Data

Then I would use the Display File Description (DSPFD) command to get the record format names. I would type on a command line:   DSPFD FILE(MYLIB/TESTLF*) TYPE(*RCDFMT)   and press Enter. By using the wildcard TESTLF* the data for all logical files are included in the same “report”. When the output is displayed use the Find field to scan for the word “Format”:

File  . . . . . :   QPDSPFD 
Control . . . . .   ________ 
Find  . . . . . .   Format                       
 *...+....1....+....2....+....3....+....4....+....5....+....6....+
    Auxiliary storage pool ID . . . . . . . . . :            00001 
  Record Format List
                         Record  Format Level
   Format       Fields   Length  Identifier
   TESTPFR           3        4  324444D952CAD
     Text . . . . . . . . . . . . . . . . . . . :
   Total number of formats  . . . . . . . . . . :           1
   Total number of fields . . . . . . . . . . . :           3
   Total record length  . . . . . . . . . . . . :           4
  File Description Header
    File  . . . . . . . . . . . . . . . . . . . : FILE       TESTLF2 
    Library . . . . . . . . . . . . . . . . . . :            MYLIB
    Type of file  . . . . . . . . . . . . . . . :            Logical
    File type . . . . . . . . . . . . . . . . . : FILETYPE   *DATA
    Auxiliary storage pool ID . . . . . . . . . :            00001
  Record Format List
                         Record  Format Level
   Format       Fields   Length  Identifier
   TESTLFR           2        2  336F4C73C9A21

The output shows that TESTLF2's record format name is different from the physical files’s.

I would delete all the logical files with the record format name that are not the same as the physical file’s and then compiled.

To make it easier and quicker for me I have created a program that does the same as the two steps mentioned above that produces a report listing all of a physical file's dependent logicals with their record format names.

You can learn more about the CHGPF command from the IBM website here»

 

This article was written for IBM i 7.1, and it should work with earlier releases too.

3 comments:

  1. If the logical file lists the fields it will not change after the CHGPF even if the record format name is the same.

    The behavior is documented at: http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Fdbp%2Frbaforcdfmtr.htm

    ReplyDelete
  2. You should use SQL to Create and Alter Tablesm DDL is now a days faster than DDS. IF you want to Document your SQL Table Definition, use ERM and ERD, also Sace them in a QDDLSRC and execute them with a small SQLRPGLE witch reads the source and Execute it ...

    ReplyDelete
    Replies
    1. Even though IBM has put all their eggs into the SQL database basket, many IBM i sites are still using DDS. Therefore, I consider the issue this post is about a valid problem for many IBM i programmers.

      I will do some posts about creating and altering tables in the future.

      Delete

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.