PLISRTx サブルーチン

目的

以下のルーチンを使用すると、次の表に示すソースと宛先でデータをソートできます。

  入力データのソース     出力データの宛先
PLISRTA     入力ファイル 出力ファイル
PLISRTB プロシージャ 出力ファイル
PLISRTC 入力ファイル プロシージャ
PLISRTD プロシージャ プロシージャ
RECORD 入力ファイル ??

構文

CALL PLISRTA(fields–spec, records-spec, storage,
			 ret-code [,prefix][,msg-level]
			 [,algorithm]);
CALL PLISRTB(fields-spec, records-spec, storage,
			 ret-code, input-proc[,prefix][msg-level][,algorithm]);
CALL PLISRTC(fields-spec, records-spec, storage,
			 ret-code, output-proc [,prefix][,msg-level]
			 [,algorithm]);
CALL PLISRTD(fields-spec, records-spec, storage,
			 ret-code, input-proc, output-proc [,prefix]
			 [,msg-level][,algorithm]);

パラメーター

fields-spec は次の形式の文字列です。

`boxSORTboxFIELDS=(pos,len,type,seq,[,posj,lenj,typej,seqj]...)[,options-list]box'

box (3 つの各インスタンスに出現) は、1 つ以上の空白文字を表します。文字列に含めることができる空白はこの空白だけです。

  • pos は、レコードにおけるソート キー フィールドの開始位置です。この位置はバイト単位で指定し、1 は先頭バイトを表します。
  • len は、キーの長さ (バイト単位) です。
  • type は、次のようなキー タイプです。
    CH 文字列
    ZD ピクチャ
    PD 固定 10 進
    Fl 固定 2 進
    BI ビット文字列
    FL 浮動バイナリ
  • seq は A または D にする必要があり、このキーの昇順値でソートするか降順値でソートするかを指定します。

    options-list には次の項目を指定できます。

    FILSZ=n ソート内のレコード数を指定します。このオプションは無視されます。
    SKIPREC=n 入力ファイルの先頭にある n 個のレコードをスキップするように指定します。
    CKPT または CHKPT チェックポイントを取得するように指定します。このオプションは無視されます。
    EQUALS 安定ソート アルゴリズムを指定します。つまり、同じキー値のレコードを入力ファイル内と同じ順序、または入力プロシージャで指定された際と同じ順序で保持するように指定します。
    NOEQUALS 安定ソート アルゴリズムを使用しないように指定します。これはデフォルトの設定です。
    DYNALLOC=(d,n) 中間記憶域を指定します。

records–spec は次の形式の文字列です。

`boxRECORDboxTYPE=rectype,LENGTH=(len)[,ftype]box'

box (3 つの各インスタンスに出現) は、1 つ以上の空白文字を表します。文字列に含めることができる空白はこの空白だけです。

  • rectype は、F (固定長レコード) または V (可変長 ASCII レコード) です。
  • len は、ソートするレコードの長さを指定します。
  • ftype は INDEXED です。ftype を省略すると、CONSECUTIVE と想定されます。

storage:この引数は無視されます。

説明

入力レコードは、パラメーターの指定に従ってソートされ、出力ファイルに書き込まれるか出力プロシージャに渡されます。

入力プロシージャまたは出力プロシージャを使用する場合、このプロシージャは、ソートに関連するレコードごとに 1 回、ソート サブルーチンによって繰り返し呼び出されます。そのため、プロシージャは一度に 1 つのレコードを処理するように記述する必要があります。これらのプロシージャは通常の PL/I プロシージャであるため、すべての PL/I 言語規則が適用されます。含まれている AUTOMATIC 変数は、プロシージャが呼び出されるごとに再初期化され、割り当てられた BASED 変数または CONTROLLED 変数は、プロシージャが戻る際に解放されます。

入力プロシージャは次の形式にする必要があります。

IN_PROC: PROCEDURE RETURNS(CHAR(len));
   DECLARE S CHAR(len);
   IF LAST_REC THEN DO;
      CALL PLIRETC(8);
/* must tell the sort routine all records have been sent */
      RETURN(S);
      END;
   ELSE DO;
      /* code to produce the record goes here */
      CALL PLIRETC(12);
/* tell the sort routine this is not the last record */ 
      RETURN(S);
      END;
END IN_PROC;

出力プロシージャは次の形式にする必要があります。

OUT_PROC: PROCEDURE(S);
   DECLARE S CHAR(*);
   /* code to process the sorted record goes here */ 
   CALL PLIRETC(4);
/* tell the sort routine to continue sending records */ 
END OUT_PROC;

出力プロシージャで、異常終了するようにソート ルーチンに指示するには、CALL PLI RETC(16) を使用します。

例 1

 plisrt1: proc options(main);
   /* 
      Examples of the PLISRT Built in functions.

      This program uses a data file named 'SRT1IN', 
      with a record length of 20, which must already exist.
   */

   dcl  (plisrta, plisrtb, plisrtc, plisrtd) builtin;

   declare ret_code fixed bin(31);
   declare eof bit(1);
   declare chkdata file;
   declare rec char(20);

   put skip list('Plisrt1 starting...');
   put skip(2) list('Contents of SRT1IN :-');

   /* display the input file */
   open file(chkdata) record title('SRT1IN');
   eof = '0'b;
   on endfile(chkdata) eof='1'b;
   read file(chkdata) into(rec);
   do while(eof = '0'b);
      put skip list(rec);
      read file(chkdata) into(rec);
      end;
   close file(chkdata);
   revert endfile(chkdata);

   put skip(2) list('Calling plisrta ---------------------------->');
   call plisrta(' sort fields=(1,10,ch,a),equals',
             ' record type=F,length=(20) ',
             0 ,              /* strg */
             ret_code,
             'SRT1',         /* data name prefix */
             'AP',           /* msg level */
             'xxxx'          /* sort method */);
   put skip list('result code is ', ret_code);

   /* display output file of above */
   put skip(2) list('Contents of SRT1OUT :-');
   open file(chkdata) record title('SRT1OUT');
   eof = '0'b;
   on endfile(chkdata) eof='1'b;
   read file(chkdata) into(rec);
   do while(eof = '0'b);
      put skip list(rec);
      read file(chkdata) into(rec);
      end;
   close file(chkdata);
   revert endfile(chkdata);

   put skip(2) list('Calling plisrtb ---------------------------->');
   call plisrtb(' sort fields=(1,10,ch,a)',
             ' record type=f,length=(20) ',
             0 ,              /* strg */
             ret_code,
             input_proc,
             ,               /* data name prefix */
             'AP',           /* msg level */
             'xxxx'          /* sort method */);
   put skip list('result code is ',ret_code);

   /* display output file of above */
   put skip(2) list('Contents of SORTOUT :-');
   open file(chkdata) record title('SORTOUT');
   eof = '0'b;
   on endfile(chkdata) eof='1'b;
   read file(chkdata) into(rec);
   do while(^eof);
      put skip list(rec);
      read file(chkdata) into(rec);
      end;
   close file(chkdata);
   revert endfile(chkdata);

   put skip(2) list('Calling plisrtc ---------------------------->');
   call plisrtc(' sort fields=(1,10,ch,a) ',
             ' record type=f,length=(20) ',
             0 ,              /* strg */
             ret_code,
             output_proc,
             'SRT1',          /* data name prefix */
             'AP',            /* msg level */
             'xxxx'           /* sort method */);
   put skip list('result code is ',ret_code);

   put skip(2) list('Calling plisrtd ---------------------------->');
   call plisrtd(' sort fields=(1,10,ch,a),skiprec=3 ',
             ' record type=f,length=(20) ',
             0 ,              /* strg */
             ret_code,
             input_proc,
             output_proc,
             ,                /* data name prefix */
             'AP',            /* msg level */
             'xxxx'          /* sort method */);
   put skip list('result code is ',ret_code);

   /* reset the PL/1 return code */
   call pliretc(0);
   put skip(2) list('Plisrt1 processing completed');


 input_proc: procedure returns(char(20));
   dcl x char(20);
   dcl cnt fixed bin(31) static internal initial(0);
   dcl rec(1:5) char(20) static internal initial (
        'abc2', 'abc4', 'abc1', 'abc6', 'abc3');
   
   cnt = cnt + 1;
   if cnt <= 5 then do;
      x=rec(cnt); 
      call pliretc(12);
      end;
   else do;
      x = '';
      call pliretc(8);   /* no more */
      cnt = 0;
      end;
   return(x);
 end input_proc;

 output_proc: procedure(y);
   dcl y char(*);

   put skip list(y);
   call pliretc(4);    /* ready for more */
 end output_proc;

end plisrt1;

例 2

test: proc options(main);

   /* Test of SORT Bif using a indexed file as input.
   /* The input file is 1st created by this program prior to the sort. */

/*
/* How to compile/link
/*
/* mfplx srt2.pl1 -defext -cisam
*/

/* Output of this program:
/*
/* Creating a indexed file with following records:
/*
/* Calling plisrtc ---------------------------------------
/* Sorting on 2nd column ASCENDING, 1st column DECENDING
/*    Boston                             abc
/*    Albany                             ccc
/*    Westboro                           xyz
/*    Milford                            xyz
/*    Acton                              xyz
/*
/**/

   dcl   plisrtd builtin;
   declare ret_code fixed bin(31);
   declare (input_proc,output_proc) entry;

   dcl SORTIN direct env(vsam keylength(8) keyloc (5) recsize(50));
   dcl rec char(50);

   %replace KEY2 by 40;       /* be sure to change other references */
   %replace KEY2_LEN by 3;    /* be sure to change other references */

   put skip list('Creating a indexed file with following records:');
   open file(SORTIN) output;

   rec = ' ';
   substr(rec,KEY2,KEY2_LEN) = 'ccc';
   write file(SORTIN) from(rec) keyfrom('Albany');

   rec = ' ';          
   substr(rec,KEY2,KEY2_LEN) = 'xyz';
   write file(SORTIN) from(rec) keyfrom('Acton');

   rec = ' ';          
   substr(rec,KEY2,KEY2_LEN) = 'abc';
   write file(SORTIN) from(rec) keyfrom('Boston');

   rec = ' ';          
   substr(rec,KEY2,KEY2_LEN) = 'xyz';
   write file(SORTIN) from(rec) keyfrom('Westboro');

   rec = ' ';          
   substr(rec,KEY2,KEY2_LEN) = 'xyz';
   write file(SORTIN) from(rec) keyfrom('Milford');
   close file(SORTIN);
   put skip;

   put skip list('Calling plisrtc ---------------------------------------');
   put skip list('Sorting on 2nd column ASCENDING, 1st column DECENDING');
   call plisrtc(' sort fields=(40,3,ch,a,5,8,ch,d) ',
             ' record type=f,length(50),indexed ',
             0 ,            /* strg */
             ret_code,      /* result status */
             output_proc,
             ,              /* data name prefix */
             'AP',          /* msg level */
             'xxxx'         /* sort method */);
   put skip list('result code is ',ret_code);

end test;

output_proc: procedure(x);
   dcl x char(*);

   put skip list(x);
   call pliretc(4);    /* ready for more */
end output_proc;

制限事項

Open PL/I では、最大 64 個のソート キーがサポートされます。すべてのソート制御キーを 1024 バイトに収める必要があります。