ヌル値可能フィールドおよびキー・フィールドに対するユーザー制御サポート

外部記述ファイルにヌル値可能フィールドが含まれてい て、ALWNULL(*USRCTL) キーワードが制御仕様書に指定されて いる場合には、以下が可能になります。

ヌル値を含むフィールドをプログラム内で正しく使用することは、 各自の責任で行っていただきます。 たとえば、ヌル値可能フィールドを、MOVE 命令の演算項目 2 として 使用する場合、MOVE を実行する前に、まず最初にそれがヌルであるかどうかを チェックする必要があります。これを行わないと、結果フィールド値が 失われる恐れがあります。また、ヌル値可能フィールドを、ヌル値可能と定義されていないフィールドを含む ファイル (たとえば、WORKSTN または PRINTER ファイル、あるいは プログラム記述ファイルなど) に出力するときにも、注意が必要です。

注:
ヌル値可能フィールドのヌル標識の値は、入力、出力、およびファイル位置付け の命令の場合にのみ、考慮されます。 以下に、ヌル標識が考慮に入れられない命令の例をいくつか示します。

フィールドは、それが外部記述データベース・レコード内で ヌル値可能であり、プログラム内の定数として定義されていない場合 に、ヌル値可能と見なされます。

フィールドが RPG プログラム内でヌル値可能と見なされているときは、 ヌル標識がそのフィールドに関連付けられます。 以下の点に注意してください。

ヌル標識は、プログラムの初期化時にゼロに初期化されるので、 プログラムの実行開始時点ではヌル値可能フィールドにはヌル値は含まれていません。

外部記述データ構造内のヌル可能フィールド

外部記述データ構造に使用されるファイルにヌル値可能フィールドが定義 されている場合、対応する RPG サブフィールドはヌル可能として定義されます。 同様に、レコード様式にヌル可能フィールドが含まれる場合、LIKEREC で定義されたデータ構造 にはヌル可能サブフィールドが含まれます。 あるデータ構造にヌル可能サブフィールドが含まれる場合には、LIKEDS を使用して そのデータ構造に似せて定義された別のデータ構造にも、ヌル可能サブフィールドが含まれるようになります。 ただし、LIKE キーワードを使用してあるフィールドを別のヌル可能フィールドに似せて定義しても、 新規フィールドはヌル可能になりません。

ヌル値可能フィールドの入力

RPG プログラム内でヌル値可能であるフィールド では、DISK、SEQ、WORKSTN および SPECIAL ファイルに関して、以下の 内容が入力時に適用されます。

ヌル値可能フィールドは、突き合わせフィールドまたは制御レベル・フィールド としては使用できません。

ヌル値可能フィールドの出力

ヌル値可能フィールドが外部記述ファイルに書き出される (出力 または更新) とき、ヌル値は、そのフィールドのヌル標識がその操作時にオンに 設定されている場合には書き出されます。

ヌル値可能フィールドが外部記述データベース・ファイルに出力される、 あるいはそのファイルで更新されるとき、そのフィールドがヌルであると、 バッファー内に置かれている値はデータ管理によって無視されます。

注:
出力時にオンになっているヌル標識を持つフィールドには、バッファーに転送 されるデータがあります。 これは、そのフィールドのヌル標識がオンになっている場合 でも、10 進データ・エラーあるいは基底ポインターが設定されていない、 などのエラーが発生することを意味します。

外部記述データベース・ファイルへの出力命令中に、ファイルに、プログラム 内ではヌル値可能と見なされ、ファイル内ではヌル値可能でないと見なされている フィールドが含まれている場合、そのヌル値可能フィールドに関連のヌル標識 は使用されません。

ヌル可能フィールドを含むレコード様式が WRITE または UPDATE 命令で使用され、 結果フィールドでデータ構造がコーディングされる場合、 出力または更新レコードのヌル・バイト・マップを設定するためにそのデータ構造のサブフィールドのヌル属性が使用されます。

ヌル可能フィールドを含むレコード様式が、%FIELDS が指定された UPDATE 命令で使用される場合、 ヌル・バイト・マップ情報は、指定されたフィールドのヌル属性から入手されます。

図 99 は、ALWNULL(*USRCTL) オプションが使用されているときに、 ヌル値を含むレコードの読み取り、書き出し、更新がどのように行われるかを示したものです。

図 99. ヌル値可能フィールドの入力および出力
*..1....+....2....+....3....+....4....+....5....+....6....+....7....+....
 *
 *
 * Specify the ALWNULL(*USRCTL) keyword on a control
 * specification or compile the ILE RPG program with ALWNULL(*USRCTL)
 * on the command.
 *
HKeywords++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 *H ALWNULL(*USRCTL)
 *
 * DISKFILE contains a record REC which has 2 fields: FLD1 and FLD2
 * Both FLD1 and FLD2 are null-capable.
 *
FDISKFILE  UF A E             DISK
 *
 * Read the first record.
 * Update the record with new values for any fields which are not
 * null.
C                   READ      REC                                    10
C                   IF        NOT %NULLIND(Fld1)
C                   MOVE      'FLD1'        Fld1
C                   ENDIF
C                   IF        NOT %NULLIND(Fld2)
C                   MOVE      'FLD2'        Fld2
C                   ENDIF
C                   UPDATE    REC
 *
 * Read another record.
 * Update the record so that all fields are null.
 * There is no need to set the values of the fields because they
      * would be ignored.
C                   READ      REC                                    10
C                   EVAL      %NULLIND(Fld1) = *ON
C                   EVAL      %NULLIND(Fld2) = *ON
C                   UPDATE    REC
 *
 * Write a new record where Fld 1 is null and Fld 2 is not null.
 *
C                   EVAL      %NULLIND(Fld1) = *ON
C                   EVAL      %NULLIND(Fld2) = *OFF
C                   EVAL      Fld2 = 'New value'
C                   WRITE     REC

キー順命令

ヌル値可能キー・フィールドがある場合には、KFLD 命令の演算項目 2 中の 標識を指定し、キー順入力命令の前に標識をオンに設定することによって、 ヌル値を含むレコードを検索することができます。 ヌル・キーを選択する必要がない場合には、標識をオフに設定します。

ヌル値可能キー・フィールドを含むレコード様式を CHAIN、SETLL、READE、または READPE 命令で使用するときに、 キーを指定するために %KDS データ構造を使用する場合、 ヌル・キー・バイト・マップ情報は、%KDS の引数として指定されたデータ構造のサブフィールドのヌル属性から入手されます。

ヌル値可能キー・フィールドを含むレコード様式を CHAIN、SETLL、READE、または READPE 命令で使用するときに、 キー・フィールドのリストを使用する場合、 ヌル・キー・バイト・マップ情報は、指定されたキーのヌル属性から入手されます。

図 100 および 図 101 は、ヌル・キーによってレコードを位置付け、 検索するためにどのようにキー付き命令が使用されるかを示しています。

図 100. ヌル値可能キー・フィールドの処理の例
  // 下記の File1 に、3 つのキー・フィールド Key1、Key2、および Key3 からなる
  // 複合キーを使用する、レコード Rec1 が含まれていると想定します。Key2
  // および Key3 はヌルにすることができ、Key1 はヌルにすることができません。
  // それぞれのキー・フィールドの長さは 2 文字です。
*..1....+....2....+....3....+....4....+....5....+....6....+....7....+..
FFilename++IPEASFRlen+LKlen+AIDevice+.Keywords++++++++++++++++++++++++++
FFile1     IF   E             DISK 
  // ファイルのためのキーを含む 2 つのデータ構造を定義します。
  // 両方のデータ構造のサブフィールド Key2 および Key3 は、
  // ヌルにすることができます。
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++
D Keys            DS                  LIKEREC(Rec1 : *KEY)
D OtherKeys       DS                  LIKEDS(keys) 
  // ファイルの入力フィールドが入ったデータ構造を定義します。
  // データ構造のサブフィールド Key2 および Key3 は、
  // ヌルにすることができます。
D File1Flds       DS                  LIKEREC(Rec1 : *INPUT)
 /free
     // 下記の SETLL 命令の場合、Keys.Key2 の
     // ヌル標識は ON で、Keys.Key3 のヌル標識は OFF です。
     // File1 は、キー値が 'AA??CC' 以上になっている、
     // 次のレコードに位置付けられます
     // (この例では、?? は NULL を表すために
     // 使用されています)。
   
     // %NULLIND(Keys.Key2) が ON になっているため、
     // 検索引数 Keys.Key2 内の実際の内容は無視されます。

     // File1 内に、Key1 が 'AA'、Key2 がヌル、Key3 が 'CC' になっている
     // レコードが存在する場合、%EQUAL(File1) は true になります。

     Keys.Key1 = 'AA';   
     Keys.Key3 = 'CC';   
     %NULLIND(Keys.Key2) = *ON;   
     %NULLIND(Keys.Key3) = *OFF;   
     SETLL %KDS(Keys) Rec1;   
     // 下記の CHAIN 命令は、Key1 が 'JJ'、Key2 が 'KK'、
     // Key3 がヌルになっているレコードを検索します。
     // %NULLIND(OtherKeys.Key3) が ON になっているため、OtherKeys.Key3
     // 内の値 'XX' は使用されません。つまり、'JJKKXX' という
     // キー値のレコードが File1 内に実際に存在する場合にも、
     // そのレコードは使用されません。

     OtherKeys.Key3 = 'XX';   
     %NULLIND(Keys.Key3) = *ON;   
     CHAIN ('JJ' : 'KK' : OtherKeys.Key3) Rec1;  
     // 以下の CHAIN 命令は、部分キーを検索引数として使用します。
     // この命令は、Key1 が 'NN'、Key2 がヌル、Key3 が
     // ヌル値を含む任意の値になっているレコードを検索します。
     // 検索されたレコードは File1Flds データ構造に入ります。
     // これにより、(CHAIN でレコードが検出された場合に)
     // File1Flds.Key2 にはヌル・フラグが立てられ、
     // File1Flds.Key3 はこの命令で変更されるように
     // なります。

     Keys.Key1 = 'NN';   
     %NULLIND(Keys.Key2) = *ON;   
     CHAIN %KDS(Keys : 2) Rec1 File1Flds;

図 101. KLIST が指定されたヌル・キー・フィールドの処理の例
 * Using the same file as the previous example, define two
 * key lists, one containing three keys and one containing
 * two keys.
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq.
 C     Full_Kl       KLIST
 C                   KFLD                    Key1
 C                   KFLD      *IN02         Key2
 C                   KFLD      *IN03         Key3
 C     Partial_Kl    KLIST
 C                   KFLD                    Key1
 C                   KFLD      *IN05         Key2
  *
  * *IN02 is ON and *IN03 is OFF for the SETLL operation below.
  * File1 will be positioned at the next record that has a key
  * that is equal to or greater than 'AA??CC' (where ?? is used
  * in this example to indicate NULL)
  *
  * Because *IN02 is ON, the actual content in the search argument
  * for Key2 will be ignored.
  *
  * If a record exists in File1 with 'AA' in Key1, a null Key2, and
  * 'CC' in Key3, indicator 90 (the Eq indicator) will be set ON.
  *
 C                   MOVE      'AA'          Key1
 C                   MOVE      'CC'          Key3
 C                   EVAL      *IN02 = '1'
 C                   EVAL      *IN03 = '0'
 C     Full_Kl       SETLL     Rec1                                   90
  *
  * The CHAIN operation below will retrieve a record with 'JJ' in Key1,
  * 'KK' in Key2, and a null Key3.  Again, because *IN03 is ON, even
  * if the programmer had moved some value (say 'XX') into the search
  * argument for Key3, 'XX' will not be used.  This means if File1
  * actually has a record with a key 'JJKKXX', that record will not
  * be retrieved.
  *
 C                   MOVE      'JJ'          Key1
 C                   MOVE      'KK'          Key2
 C                   EVAL      *IN02 = '0'
 C                   EVAL      *IN03 = '1'
 C     Full_Kl       CHAIN     Rec1                               80
  *
  * The CHAIN operation below uses a partial key as the search argument.
  * It will retrieve a record with 'NN' in Key1, a null key2, and any
  * value including a null value in Key3.
  *
  * In the database, the NULL value occupies the highest position in
  * the collating sequence.  Assume the keys in File1 are in ascending
  * sequence.  If File1 has a record with 'NN??xx' as key (where ??
  * means NULL and xx means any value other than NULL), that record
  * will be retrieved.  If such a record does not exist in File1, but
  * File1 has a record with 'NN????' as key, the 'NN????' record will
  * be retrieved.  The null flags for Key2 and Key3 will be set ON
  * as a result.
  *
 C                   MOVE      'NN'          Key1
 C                   SETON                                        05
 C     Partial_Kl    CHAIN     Rec1                               70