RPGユーザーが C/400を学習すると SETLL & READE や CHAIN は C/400ではどのように
行うのか気になるところである。
一般に C言語では RPGの SETLL や CHAIN というものは無い。
C/400 においてもこれは同じことであるが、RPGに慣れ親しんでいる場合は同じことを C/400で
再現する方法を知りたいものである。
ここからは RPGでのこれらのレコード制御の命令を C/400で再現する方法を紹介しよう。
それらの方法は IBMの解説書にも RPGと対応した方法としては解説されていないのでこれが初めての
解説となるはずである。
これらの手法は EnterpriseServer の DB2エンジンに使用されている。
次の例は QTRFIL/LSHOHINS という4桁の品種コード別の論理ファイルを同じ品種コード='0001' だけを
SETLL & READE を行っている例である。
0001.00 #include <stdio.h> 0002.00 #include <stdlib.h> 0003.00 #include <string.h> 0004.00 #include <recio.h> 0005.00 0006.00 #define TRUE 0 0007.00 #define FALSE -1 0008.00 #define MAX_LEN 3000 0009.00 #define MAX_KEY_LEN 256 0010.00 0011.00 void main(void){ 0012.00 _RFILE *fp; 0013.00 _RIOFB_T *iofb; 0014.00 char key[MAX_KEY_LEN]; 0015.00 unsigned int key_len; 0016.00 char record[128]; 0017.00 int i; 0018.00 unsigned long rrn =0; 0019.00 0020.00 if((fp = _Ropen("QTRFIL/LSHOHNS", "rr+ blkrcd=Y")) == NULL){ 0021.00 printf("cannot open\n"); return; 0022.00 } 0023.00 memset(key, 0, sizeof(key)); 0024.00 strcpy(key, "0001"); 0025.00 key_len = 4; 0026.00 _Rlocate(fp, &key, key_len, __KEY_LT); /*[ SETLL ]*/ 0027.00 0028.00 /*[ 以下は READE による読み取り ]*/ 0029.00 for(i=0; i< 99999; i++){/*for-loop*/ 0030.00 if(i == 0) 0031.00 iofb = _Rreadk(fp, record,MAX_LEN, __KEY_NEXTUNQ, &key, key_len); 0032.00 else 0033.00 iofb = _Rreadk(fp, record,MAX_LEN, __KEY_NEXTEQ, &key, key_len); 0034.00 if(iofb->num_bytes == EOF || iofb->rrn == rrn || 0035.00 strncmp(iofb->key, key, key_len) != 0){ 0036.00 break; 0037.00 } 0038.00 printf("record = %s\n", record); 0039.00 rrn = iofb->rrn; 0040.00 }/*for-loop*/ 0041.00 _Rclose(fp); 0042.00 getchar(); 0043.00 }
まず _Rlocate(fp, &key, key_len, __KEY_LT); は指定したキーの位置をセットして
指定したキーより小さな位置にセットしているので、これが SETLL の役割 を果たしている。
次に _Rreadk で読み取るわけであるが、最初だけは __KEY_NEXTUNQ で読み取って
2回目以降は __KEY_NEXTEQ で読み取る。
注意しなければならないのは、READE を終えた後も実際は 物理的なレコードが存在している場合には
EOFはセットされない。
RPGの場合は READE で EOF標識が ON になるが C/400の場合に EOF が使えるのは物理的なファイルの
終わりのときだけである。
よって同じレコードが読み込まれていないかを RRN を記憶しておいて EOF の検出に利用している点に
注意されたし。