先の例に挙げた「遅延評価型」、すなわち実際に必要になる時点まで読み込みを遅延させる方式のサブルーチンは、任意のファイルに適用可能な形に一般化できます。
次のようなFETCHコマンドを考えてみましょう。
FETCH FIELDS(#FIELD1 #FIELD2 ... #FIELDn) FROM_FILE(FILE)
WITH_KEY(#KEY1 ... #KEYn)
これは、FETCHコマンドを正確にエミュレートし、「遅延評価型」で実装した、次のようなサブルーチンで置き換えることができます。
EXECUTE SUBROUTINE(GET_FILE) WITH_PARMS(#KEY1 ... #KEYn)
サブルーチンの実装例を以下に示します。
SUBROUTINE NAME(GET_FILE) PARMS((#GETKEY1 *RECEIVED)
" "
(#GETKEYn *RECEIVED))
DEFINE FIELD(#GETKEY1) REFFLD(#KEY1)
" " " "
DEFINE FIELD(#GETKEYn) REFFLD(#KEYn)
DEF_LIST NAME(#FILE)
FIELDS(#KEY1 ... #KEYn #FIELD1 ... #FIELDn)
TYPE(*WORKING) ENTRYS(as required)
LOC_ENTRY IN_LIST(#FILE) WHERE('(#KEY1 = #GETKEY1) *AND
" " "
(#KEYn = #GETKEYn)')
IF_STATUS IS_NOT(*OKAY)
FETCH FIELDS(#FIELD1 #FIELD2 ... #FIELDn) FROM_FILE(FILE)
WITH_KEY(#GETKEY1 ... #GETKEYn)
ADD_ENTRY TO_LIST(#FILE)
ENDIF
着目点:
このサブルーチンは、次の2通りの可能性を考慮していません。
ひとつは作業リストがオーバーフローする可能性です。これに対処するためには、DEF_LISTコマンドにCOUNTERパラメータを指定するとよいでしょう。ADD_ENTRYコマンドの実行前にCOUNTERの値を調べ、ENTRYSの値以上であればCLR_LISTコマンドでリストをクリアします。
もうひとつは、要求されたレコードが作業リストにもデータベースにも見つからない場合の対処です。これはFETCHコマンドの後にIF_STATUSを置くことにより解消できます。レコードが見つかった場合はそれを作業リストに追加し、そうでない場合は適切なアクションをとるようにします(例:ABORTコマンドの実行)。