Wednesday, October 22, 2014

Three CRTDUPOBJ myths busted

3 examples of how ti use CRTDUPOBJ command

I am writing this post in response to several comments that have been made on posts in this blog, discussions threads I have seen in Facebook, and discussions I have had with work colleagues.

The Create Duplicate Object command, CRTDUPOBJ, is used to create a duplicate any object, not just files. But in this post I am just going to cover what I call "data files", physical and logical files.

The myths I have recently encountered are:

  1. You have to give the from library name.
  2. If there is a trigger on the from file when it is duplicated the trigger is on the new file too.
  3. If you duplicate a physical file to another library and then duplicate a logical file that is built over the original physical the new logical still dependent upon the original physical file.

 

You have to give the from library name.

Before OS/400 release V4R5 you could not use library list, *LIBL, in the 'From library' parameter, FROMLIB. You had to determine in which library the object resided and then pass it as a parameter in the command. In my experience many programmers got lazy and hard coded in the library name, which caused problems with testing, etc.

As one of the changes to commands in V4R5 CRTDUPOBJ was changed to allow *LIBL to be given for FROMLIB.

I am surprised that some people are still under this impression. I do run occasionally across the hard coded FROMLIB in a few dark corners of the code I am responsible for, and where I can I change it to use *LIBL.

Before V4R5:
  CRTDUPOBJ OBJ(TESTFILE) FROMLIB(MYLIB) OBJTYPE(*FILE) +
              TOLIB(QTEMP) NEWOBJ(@TESTFILE)
Better:
  RTVOBJD OBJ(TESTFILE) OBJTYPE(*FILE) RTNLIB(&RTNLIB)
  CRTDUPOBJ OBJ(TESTFILE) FROMLIB(&RTNLIB) OBJTYPE(*FILE) +
              TOLIB(QTEMP) NEWOBJ(@TESTFILE)
V4R5 and beyond:
  CRTDUPOBJ OBJ(TESTFILE) FROMLIB(*LIBL) OBJTYPE(*FILE) + 
              TOLIB(QTEMP) NEWOBJ(@TESTFILE)

 

If there is a trigger on the from file when it is duplicated the trigger is on the new file too.

I am sure this scenario has burnt many, me too. Prior to OS/400 V5R4 if there is a trigger on a file and you used the CRTDUPBOJ command the trigger was duplicated too.

V5R4 added four new parameters to the command, one of those was the 'Duplicate triggers' parameter, TRG. If TRG is *NO the trigger is not copied to the To file.

Before V5R4:
  CRTDUPOBJ OBJ(TESTFILE) FROMLIB(*LIBL) OBJTYPE(*FILE) +
              TOLIB(QTEMP) NEWOBJ(@TESTFILE)
  RMVPFTRG FILE(QTEMP/TESTFILE) TRGTIME(*ALL)
V5R4 and beyond:
  CRTDUPOBJ OBJ(TESTFILE) FROMLIB(*LIBL) OBJTYPE(*FILE) +
              TOLIB(QTEMP) NEWOBJ(@TESTFILE) TRG(*NO)

 

If you duplicate a physical file to another library and then duplicate a logical file that is built over the original physical the new logical still dependent upon the original physical file.

Anyone who has done the above has also been concerned that the duplicated logical file is still dependent upon the original physical file.

To test this I created a physical file and a logical file in the library MYLIB.

Physical file
  A          R TESTPFR
  A            FLD001         1A
  A            FLD002         1A
  A          K FLD001
Logical file
  A          R TESTPFR                   PFILE(TESTPF)
  A          K FLD002

I added the library QTEMP to the top of the user part of my library, therefore, it is before MYLIB. Now I can use the CRTDUPOBJ command to duplicate the physical file, and then do the same with the logical file:

  CRTDUPOBJ OBJ(TESTPF) FROMLIB(MYLIB) OBJTYPE(*FILE) TOLIB(QTEMP) TRG(*NO)

  CRTDUPOBJ OBJ(TESTLF) FROMLIB(MYLIB) OBJTYPE(*FILE) TOLIB(QTEMP) TRG(*NO)

I can check if the logical file is dependent upon the physical file using the Display Database Relations command, DSPDBR:

  DSPDBR QTEMP/TESTPF

It shows that the logical file in QTEMP is dependent upon the physical file in QTEMP:

                        Display Data Base Relations
DSPDBR Command Input
  File  . . . . . . . . . . . . . . . . . . . : FILE       TESTPF
    Library . . . . . . . . . . . . . . . . . :            QTEMP
  Member  . . . . . . . . . . . . . . . . . . : MBR        *NONE
  Record format . . . . . . . . . . . . . . . : RCDFMT     *NONE
  Output  . . . . . . . . . . . . . . . . . . : OUTPUT     *
Specifications
  Type of file  . . . . . . . . . . . . . . . :            Physical
  File  . . . . . . . . . . . . . . . . . . . :            TESTPF
    Library . . . . . . . . . . . . . . . . . :            QTEMP
    Member  . . . . . . . . . . . . . . . . . :            *NONE
    Record format . . . . . . . . . . . . . . :            *NONE
    Number of dependent files . . . . . . . . :                1
Files Dependent On Specified File
  Dependent File         Library       Dependency   JREF    Constraint
      TESTLF             QTEMP         Data

What would happen if I used a library that was at the bottom of my library list, below MYLIB, would the same happen?

I create the library MYLIB2 and added it to the bottom of my library list. I then ran the CRTDUPOBJ commands to duplicate the physical and logical files from MYLIB to MYLIB2.

  CRTDUPOBJ OBJ(TESTPF) FROMLIB(MYLIB) OBJTYPE(*FILE) TOLIB(MYLIB2) TRG(*NO)

  CRTDUPOBJ OBJ(TESTLF) FROMLIB(MYLIB) OBJTYPE(*FILE) TOLIB(MYLIB2) TRG(*NO)

Using the DSPDBR I could see that the logical file in MYLIB2 was dependent upon the physical file in MYLIB2, even though there were two other versions of the physical file above it in the library list, in QTEMP and MYLIB.

The one gotcha I have found with this is with logical files where the dependent physical file, PFILE, is qualified with the library name. No matter where you copy the logical file it will remain dependent upon the qualified physical file.

A          R TESTPFR                   PFILE(MYLIB/TESTPF)
A          K FLD002

 

If you have any other examples of CRTDUPOBJ or other command myths please email them to me using the Contact form on the right.

 

You can learn more about these on the IBM website:

 

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

5 comments:

  1. To copy the physical and logical files related with a new name in the same library I copy them all to another library, rename them and then copy them in the first library, otherwise renamed logical files remain dependent upon the first physical file.

    ReplyDelete
  2. That would make it a lot easier (simpler). Thank you for sharing.

    ReplyDelete
  3. I have a long dwelling doubt about copying logical files with this command. Sometimes when I copy a logical file to another library using CRTDUPOBJ it correctly points to the correct file present in destination library. But sometimes after getting duplicated, it still points to the PF of source library. I have tried by submitting a job to copy file too, but it didn't help.

    So why does it behave so randomly?

    ReplyDelete
    Replies
    1. At the start I had the same lurking suspicion that the CRTDUPOBJ would not change the PF the LF was based on. I tried it many ways for a couple of days and found that the LF was always based on the PF in the same library, as I have described in the above post.

      The only time I was caught out was when the library name was coded into the PFILE keyword,

      Is the scenario you are working in where the LF and the PF are in different libraries?

      If you find a scenario where it does not work as described and you come up with a reason why please share it here.

      Delete
  4. Simon - this statement is slightly incorrect:

    "The Create Duplicate Object command, CRTDUPOBJ, is used to create a duplicate [of] any object, not just files."

    At least one AS/400 - iSeries - IBM i object type (*DTAQ) cannot be duplicated by the CRTDUPOBJ command...
    http://www.itjungle.com/mgo/mgo061803-story02.html

    ReplyDelete

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.