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:
- You have to give the from library name.
- If there is a trigger on the from file when it is duplicated the trigger is on the new file too.
- 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.
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.
ReplyDeleteThat would make it a lot easier (simpler). Thank you for sharing.
ReplyDeleteI 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.
ReplyDeleteSo why does it behave so randomly?
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.
DeleteThe 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.
Simon - this statement is slightly incorrect:
ReplyDelete"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
If I use CRTDUPOBJ on DDL Created table and try to create a duplicate obj with different name from original it is not allowing to create but If I create with same name as original it is creating in different library just want understand how CRTDUPOBJ works on DDL Created Table
ReplyDeleteThanks
Rather than CRTDUPOBJ DDL table you should try the SQL:
ReplyDeleteCREATE TABLE schema.table2 LIKE schema.table1