我知道如何通过在dow循环中读取一个文件并写入另一个文件来将记录从一个pf复制到另一个pf,如下所示。文件是分别具有记录格式rec1和rec2的PF1和PF2,其中每个文件只有一个分别命名为fld1和@fld1的字段-
READ PF1
DOW not %eof(PF1) and not %error
eval fld1 = @fld1
write Rec2
READ PF1
ENDDO
正如Buck回答中的评论所提到的,你的队友暗指使用RPG循环来处理文件。循环基本上是声明为"P"primary的文件的隐式读取循环。http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzasc/sc09250726.htm%23wq121
最初,即使RPG IV程序也包含了作为循环一部分使用的代码,例如自动打开文件,即使您实际上没有声明任何输入主文件。然而,现在,您可以使用Main()h-spec创建"Linear Main"程序,并且您的程序将是无周期的。
在现代RPG中,使用循环是不受欢迎的。主要是因为正在发生的事情的隐含性质使得理解非琐碎的代码变得困难。此外,循环代码的性能并不比非循环代码好;写起来就少了。正在执行的I/O保持完全相同。
最后,正如评论中提到的那样。如果要优化性能,请使用SQL。SQL的基于集合的特性胜过RPG的一次一行。我最近还没有对其进行基准测试,但早在v5r2上,SQL复制100行或更多行的速度比RPG快。
仅供参考,FWiW;即不是建议,只是可以做什么的例子,特别是在暗示但没有给出具体细节的情况下:
我的队友告诉我,他只能在4行中为这个问题编写代码,包括在F-spec中声明这两个文件。他也不会使用read、move或dow循环。我不知道他怎么能这么做。这就是为什么我渴望知道这一点。
以下来源是循环程序的示例;我的REC1的FLD1有一个10字节的字段,但我描述了20字节的输出,所以为了避免根据sev-20 RNF7501编译失败"结果字段中的数据结构长度不等于因子2的记录长度。",我在CRTBNDRPG:上指定了GENLVL(20)
FPF1 IP E DISK rename(rec1:rcd1)
FPF2 O F 20 DISK
DINOUT E DS EXTNAME(PF1)
C WRITE PF2 INOUT
我不想使用CL程序。我只想用RPG3或RPG4 中的单个程序来完成
类似的RPG循环程序可以有效地执行相同的事情,类似地将数据从PF1复制到PF2,尽管列名不同,[因此本质上也]记录格式不同,使用CL命令而不使用CL程序和几乎同样少的行。以下示例取决于通常在系统库列表中的QSYS2中名为QSQPTABL的"必须始终是一行表",第二个参数可以反映命令字符串的实际长度,但同样容易的是,根据Const定义对最大原型长度进行编码,确保空白填充达到该长度,而不必实际计算级联字符串表达式的[~53]字节:
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)
尽管上述两个来源对任何不熟悉周期的人来说都可能是一个谜,但后者的总体影响很可能是由几乎任何了解CL命令字符串的人正确推断出来的[?也许更恰当地描述为猜测正确?],尽管他们对周期缺乏了解。
当然,正如人们所指出的,有了SQL,这个程序可能会更简单;对于外行来说可能更容易阅读[尽管添加了WITH NONE子句,显示为WITH NC,只是为了防止在编译请求中忽略COMMIT(*NONE),但可能不容易直觉]:
C/Exec SQL
C+ insert into pf2 select * from pf1 WITH NC
C/End-Exec
C SETON LR
附言:OP的源代码最初[至少在我在这里添加评论之前]用eval fld1 = @fld1
错误地编码,而根据给定的设置,它的目的肯定是eval @fld1 = fld1
。
如果需要使用RPG,请使用嵌入式SQL。查找INSERT INTO。如果你不局限于RPG,可以考虑CPYF。。。MBROPT(*ADD)。
你想通过另一种方式来解决什么业务问题?