Chinaunix首页 | 论坛 | 博客
  • 博客访问: 346857
  • 博文数量: 90
  • 博客积分: 847
  • 博客等级: 准尉
  • 技术积分: 1373
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-02 10:54
个人简介

跌打滚爬中的小菜鸟...

文章分类

全部博文(90)

文章存档

2015年(5)

2013年(47)

2012年(38)

我的朋友

分类: 系统运维

2012-10-22 14:30:03

原文章:

在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.      …………….
复制代码

阅读(1661) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~