免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 15861 | 回复: 22
打印 上一主题 下一主题

AS/400开发经验点滴(七)--在RPG程序中巧用相对记录号RRN [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-11-30 12:26 |只看该作者 |倒序浏览
AS/400开发经验点滴(七)

BLOG LIOU


十.在RPG程序中巧用相对记录号RRN

1.        RRN

正像INFORMIX数据库有记录号ROWID,AS/400的PF文件的记录也都有一个隐含的记录号RRN。RRN是Relative-Record Number的缩写,也就是相对记录号,有时俗称记录“物理地址”。当向PF文件中增加记录时,每条记录都被赋上了一个RRN。在PF文件属性中有一个“Reuse deleted records”属性,表示是否重复使用删除记录的RRN,可以用CHGPF来修改该属性,如果该属性指定为*NO,那么新加的记录就只会追加到文件尾部,RRN号则顺序加1,如果删除一条记录,那么该条记录的RRN号仍会被保留,即记录空间不会被释放,那么文件就会一直增长,可以通过文件重组来重新排序RRN号。如果“Reuse deleted records”属性指定为*YES,那么被删除记录RRN号可以被重复利用,在新增加记录时,会优先查找以前是否有被删除的记录,如果有,就会把先前的RRN号赋给新增加的记录。

同时,RRN还是SQL保留字,可以在SQL语句中使用,比如下例就可以看到RRN号:

SELECT RRN(TESTPF), FLD1, FLD2, FLD3  FROM BLOG/TESTPF


2. RPG中使用RRN

在RPG程序中,同样可以使用RRN。巧用善用RRN,有时候还具有意想不到的效果。

对没有键值的文件就可以根据相对记录号RRN,来连续或随机处理。RRN号也可以在SETLL、SETGT、CHAIN操作码中使用。要在RPG程序中使用RRN,必须在文件定义中指定RECNO关键词。RECNO关键词就表示DISK类文件是按照相对记录号(RRN)来处理的。RECNO可以在INPUT/UPDATE类文件上指定,提取的相对记录号会放在RECNO关键词括号内定义的一个字段内,该字段名可以自己定义,类型必须定义成数字类型,定义的长度应该足够放下提取的记录号长度。关键值RECNO和BLOCK(*YES)不能同时在同一个文件上定义。而且文件定义的34位必须为空,通常有键值的文件该位会被填K。使用了RECNO关键词,ILE RPG编译器不允许记录块读写(RECORD BLOCKING),但如果文件仅仅是输入文件,而且设置快速顺序访问(用OVRDBF指定SEQONLY(*YES)),那么块读写仍然被允许。

比如文件定义:

FTESTPF    IF   E             DISK    RECNO(RRNO)

定义字段RRNO:

DRRNO                            9P 0 INZ(0)

定义了相对记录号存放的RRNO字段后,就可以在RPG程序中使用相对记录号了。在读写每条记录时,都会返回该记录的RRN号。


3.使用RRN优化处理大文件的例子

下面举一例,看看如何使用RRN来优化处理大文件。假设有一个数据量为海量的大文件,需要对其顺序处理。通常我们会想到把该大文件拆分成若干小文件,然后对若干小文件进行并行处理。但把海量大文件拆分成若干小文件也需要耗去可观的时间,能不能不用对海量大文件进行拆分,就可以对该文件进行分段并行处理呢?使用RRN就可以做到。

具体办法:
(1)        首先在RPG程序的文件定义中定义RECNO关键词以及定义存放RRN号的字段。
(2)        在RPG程序中指定分段的开始和结束RRN号。
(3)        用开始RRN号和SETLL语句来定位分段的开始位置
(4)        用读写记录返回的RRN号,来与分段结尾RRN号比较,当读写记录返回的RRN号大于分段结尾RRN号时,该段处理结束,程序返回。
(5)        再编一个调用的RPG或CL的程序,指定若干个连续的分段,并用提交方式调用被调用的分段处理的RPG的程序,就可以完成海量文件的分段并行处理。

示范程序源码如下:

  1.      FTESTPF    IF   E             DISK    RECNO(RRNO)
  2.      ………….
  3.      DRRNO                            9P 0  INZ(0)
  4.      ………….
  5.      C     *ENTRY     Plist
  6.      C                      Parm                    BEGNO            10 0
  7.      C                      Parm                    ENDNO            10 0
  8.      ………….
  9.      C     BEGNO      SETLL    TESTPF
  10.      C                      DOW     1=1
  11.      C                      READ    TESTPF                                31
  12.      C     *IN31        IFEQ      '1'
  13.      C                      LEAVE
  14.      C                      ENDIF
  15.      ……………
  16.     C                      IF        RRNO >; ENDNO
  17.      C                      LEAVE
  18.      C                      ENDIF
  19.      ……………
  20.      C                      ENDDO  
  21.      …………….
复制代码



2004.11.30

论坛徽章:
0
2 [报告]
发表于 2004-11-30 13:19 |只看该作者

AS/400开发经验点滴(七)--在RPG程序中巧用相对记录号RRN

好东西!

论坛徽章:
0
3 [报告]
发表于 2004-11-30 14:00 |只看该作者

AS/400开发经验点滴(七)--在RPG程序中巧用相对记录号RRN

Very Good !

另外,我也借题发挥,针对文件相对记录号的话题做如下补充。

我们在文件中定义使用相对记录号处理文件,在一定的条件下,比如按顺序处理文件,存取速度很快。使用相对记录号文件应该在文件定义的第34列留空白。
下面再举2个例子解读CHAIN、使用相对记录号写文件的用法。


例1、从文件头至尾利用相对记录号对其进行CHAIN操作,最后显示文件记录总数:

  1. 0001.00 ** Create by qingzhou  2004.11.30
  2. 0002.00 **
  3. 0003.00 FTEST_PF   IF    E             DISK     RECNO(RRN) ← 在关键字文件定义RECNO(RRN),RRN是相对记录号.
  4. 0004.00 **
  5. 0005.00 D RRN               S            9B 0   INZ(1)     ← D类定义一个变量RRN为9位16进制格式.
  6. 0006.00 **
  7. 0007.00 C       RRN          CHAIN     TEST_PF   ← 相对记录号索引文件TEST_PF(这里是升序).
  8. 0008.00 C                    DOW       %FOUND(TEST_PF)
  9. 0009.00 C                    EVAL      RRN=RRN+1
  10. 0010.00 C       RRN          CHAIN     TEST_PF
  11. 0011.00 C                    ENDDO
  12. 0012.00 C**                                      ← 循环定义每读到一个记录将相对记录号+1,直到读到文件结束.
  13. 0013.00 C                    EVAL      RRN=RRN-1 ← 将RRN-1,因为RRN最后的记数为记录数+1.
  14. 0014.00 C       RRN          DSPLY ← DSPLY语句是将RRN显示在屏幕上,本语句在调试程序很有用。当语句执行DSPLY时,程序显示变量值,按执行键程序继续运行.
  15. 0015.00 C**
  16. 0016.00 C                    EVAL      *INLR=*ON
复制代码


例2、使用相对记录号写文件:

  1. 0001.00 ** Create by qingzhou  2004.11.30
  2. 0002.00 **
  3. 0003.00 FTEST_PF   O    E             DISK     RECNO(RRN)
  4. 0004.00 **
  5. 0005.00 D RRN               S            9B 0   INZ(1)     
  6. 0006.00 **
  7. ......
  8. 0009.00 C                    EVAL      RRN=RRN+1
  9. 0010.00 C                    WRITE(E)  EMFMT  ← TEST_PF的记录格式名EMFMT
  10. 0011.00 C                    IF        *ERROR
  11. 0012.00 **                   Error processing                                       
  12. 0013.00 C                    ENDIF
  13. ......
复制代码


备注:本例使用相对记录号将记录写入指定的位置上。
注意:只能将写入的记录放在原先已经删除的文件记录位置上,或者放置在使用INZPFM命令做过初始化操作的文件成员上。对于一个活动的文件记录,本操作无效。WRITE(E)的‘E’表示使用错误检验,%ERROR是错误检验内置函数。
如果不使用相对记录号,记录将被写入文件尾部。

显示文件的子文件存取方式就是利用相对记录号对文件进行操作的实例。

论坛徽章:
0
4 [报告]
发表于 2004-11-30 14:19 |只看该作者

AS/400开发经验点滴(七)--在RPG程序中巧用相对记录号RRN

是不是在写帐票或SUBFILE时经常用这个纪录号吧

论坛徽章:
0
5 [报告]
发表于 2004-11-30 14:40 |只看该作者

AS/400开发经验点滴(七)--在RPG程序中巧用相对记录号RRN

qingzhou  补充得非常好啊!另外subfile确实也是用RRN来计算的。

论坛徽章:
0
6 [报告]
发表于 2004-12-01 08:09 |只看该作者

AS/400开发经验点滴(七)--在RPG程序中巧用相对记录号RRN

先提个小问题给楼主:怎么就看到AS/400开发经验1,2,3,4,然后一下子到7了,那个5和6那2个贴到哪去了呢?
都非常实用!

论坛徽章:
0
7 [报告]
发表于 2004-12-01 08:50 |只看该作者

AS/400开发经验点滴(七)--在RPG程序中巧用相对记录号RRN

guud!

论坛徽章:
0
8 [报告]
发表于 2004-12-01 09:04 |只看该作者

AS/400开发经验点滴(七)--在RPG程序中巧用相对记录号RRN

原帖由 "fairyboy" 发表:
先提个小问题给楼主:怎么就看到AS/400开发经验1,2,3,4,然后一下子到7了,那个5和6那2个贴到哪去了呢?
都非常实用!


5和6原来也发过,我刚才在坛上查了一遍,好象确实没有了?要不我重发一遍?

论坛徽章:
0
9 [报告]
发表于 2004-12-01 09:22 |只看该作者

AS/400开发经验点滴(七)--在RPG程序中巧用相对记录号RRN

感謝您,麻煩您重發一下5 & 6 ...3q ! ^^

论坛徽章:
0
10 [报告]
发表于 2004-12-01 09:50 |只看该作者

AS/400开发经验点滴(七)--在RPG程序中巧用相对记录号RRN

原帖由 "blogliou" 发表:


5和6原来也发过,我刚才在坛上查了一遍,好象确实没有了?要不我重发一遍?


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP