简体   繁体   中英

Write records from one PF to another without READ operation or DOW loop or move operation.

I know how to copy records from one pf to another by reading one file in dow loop and writing into another file like below. Files are PF1 and PF2 having record format rec1 and rec2 respectively where each file have only one field named fld1 and @fld1 respectively-

READ PF1
DOW not %eof(PF1) and not %error
eval fld1 = @fld1
write Rec2
READ PF1
ENDDO 

As the comments in Buck's answer mention, your team mate is alluding to using the RPG cycle to process the file. The cycle is basically an implicit read loop of files declared as 'P'rimary. http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzasc/sc09250726.htm%23wq121

Originally, even RPG IV programs included code to used as part of the cycle, such as automatically opening files, even if you didn't actually declare any input primary files. Now however, you can create "Linear Main" programs using the MAIN() h-spec and your program will be cycle free.

Using the cycle is frowned upon in modern RPG. Primarily because the implicit nature of what's going on makes it tricky to understand non-trivial code. Additionally, cycle code doesn't perform any better than non-cycle code; it's just less to write. The I/Os being done remain exactly the same.

Finally, again as mentioned in the comments. If you want to optimize performace, use SQL. The set based nature of SQL beats RPG's one row at a time. I haven't benchmarked it recently, but way back on v5r2 or so, copying 100 or more rows was faster with SQL than RPG.

For reference only, FWiW; ie not recommendations, just examples of what can be done, esp. in cases alluded but for which no specifics were given:

My team mate told me that he can write code for this problem only in 4 lines including declaration of both files in F-spec. He will also not use read, move or dow loop. I don't know how can he do this. That's why I am eager to know this.

The following source is an example Cycle-program; my FLD1 of REC1 had a 10-byte field but I described my output for 20-bytes, so to avoid failed compile per sev-20 RNF7501 "Length of data structure in Result-Field does not equal the record length of Factor 2.", I specified GENLVL(20) on the CRTBNDRPG:

  FPF1       IP   E             DISK    rename(rec1:rcd1) 
  FPF2       O    F   20        DISK                      
  DINOUT          E DS                  EXTNAME(PF1)      
  C                   WRITE     PF2           INOUT       

I don't want to use CL program. I just want to do it with a single program either in RPG3 or RPG4

A similar RPG Cycle-program could perform effectively the same thing, similarly copying the data from PF1 to PF2 despite different column name and [thus inherently also] the different record format, using the CL command without a CL program and almost as few lines. The following example depends on the must-always-be-one-row table called QSQPTABL in QSYS2 that would typically be in the system Library List, and the second argument could reflect the actual length of the command string, but just as easily codes the max prototyped length per the Const definition assuring the blank-padding up to that length without actually having to count the [~53] bytes of the concatenated string expression:

  FQSQPTABL  IP   E             DISK    rename(qsqptabl:qsqptable)
  DQcmdExc          PR                  ExtPgm('QSYS/QCMDEXC')
  D                              200A   const
  D                               15P05 const
  c                   callp     QcmdExc('cpyf pf1 pf2 mbropt(*add)'
  c                                    +' fmtopt(*nochk) crtfile(*no)':200)

Whereas both of the above sources are probably an enigma to anyone unfamiliar with the Cycle, the overall effects of the latter are quite likely to be inferred correctly [¿perhaps more appropriately described as guessed correctly?], by just about anyone with an understanding of the CL command string, despite their lack of understanding of the Cycle.

And of course, as was also noted, with the SQL the program is probably arguably even easier\\simpler; possibly even more readable to the uninitiated [although the WITH NONE clause, shown as WITH NC, added just in case the COMMIT(*NONE) was overlooked on the compile request, probably is not easily intuited]:

  C/Exec SQL                                                         
  C+ insert into pf2 select * from pf1 WITH NC                       
  C/End-Exec                                                         
  C                   SETON                                        LR

PS The source-code from the OP was originally [at least was, prior to my comment added here] incorrectly coded with eval fld1 = @fld1 when surely what was intended was eval @fld1 = fld1 according to the setup\\given.

If you need to use RPG, use embedded SQL. Look up INSERT INTO. If you aren't limited to RPG, consider CPYF... MBROPT(*ADD).

What business problem are you trying to solve by doing it another way?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM