代入

EGL による代入の結果は以下のとおりです。

assignment 文の構文図
target
項目、レコード、またはシステム変数
source
式またはレコード。式は、一連のシンボルの組み合わせとして構成されるか (例えば a + b + c) 、または 次のいずれかとなります。
  • 項目またはシステム変数
  • 関数呼び出し
  • リテラル
デフォルトでは、レコードは CHAR 型の項目と同等であり、その合計バイト数は構造体項目内の合計バイト数と等しくなります。 レコードの型が CHAR の場合は、以下の例外が適用されます。

代入の例を以下に示します。

  z = a + b + c;
  myDate = VGVar.currentShortGregorianDate;
  myUser = sysVar.userID;
  myRecord01 = myRecord02;
  myRecord02 = "USER";

次の表とそれに続く説明は、互換性の規則を示しています。

ターゲットのプリミティブ型

ターゲットとして有効なソースのプリミティブ型
(またはルーズ型)

BIN BIN、INT、BIGINT、SMALLINT、DECIMAL、NUM、NUMBER、NUMC、PACF、FLOAT、SMALLFLOAT、MONEY
CHAR CHAR、DATE、TIME、HEX、MBCHAR、NUM、NUMBER、TIMESTAMP
DATE DATE、CHAR、NUM、TIMESTAMP
DBCHAR DBCHAR
DECIMAL BIN、INT、BIGINT、SMALLINT、DECIMAL、NUM、 NUMBER、NUMC、PACF
FLOAT BIN、INT、BIGINT、SMALLINT、DECIMAL、NUM、NUMBER、NUMC、PACF、FLOAT、SMALLFLOAT、MONEY
HEX CHAR、HEX
INTERVAL INTERVAL
MBCHAR CHAR、MBCHAR
MONEY BIN、INT、BIGINT、SMALLINT、DECIMAL、NUM、NUMBER、NUMC、PACF、FLOAT、SMALLFLOAT
NUM BIN、INT、DATE、TIME、BIGINT、SMALLINT、CHAR、NUM、NUMBER、NUMC、PACF、DECIMAL、FLOAT、SMALLFLOAT、MONEY
NUMC BIN、INT、BIGINT、SMALLINT、DECIMAL、NUM、NUMBER、NUMC、PACF、FLOAT、SMALLFLOAT
PACF BIN、INT、BIGINT、SMALLINT、DECIMAL、NUM、 NUMBER、NUMC、PACF
SMALLFLOAT BIN、INT、BIGINT、SMALLINT、DECIMAL、NUM、NUMBER、NUMC、PACF、FLOAT、SMALLFLOAT、MONEY
TIME TIME、CHAR、NUM、TIMESTAMP
TIMESTAMP CHAR、DATE、TIME、TIMESTAMP
UNICODE UNICODE
特別な例として、数値システム・ワードから戻された数値は、HEX 型の項目に代入することができます。詳細については、『数学的 (システム・ワード)』を参照してください。

EGL の assignment 文の振る舞いは、別の参照トピックで説明している move 文と異なります。

各種の数値型への代入

数値型 (BIN、DECIMAL、FLOAT、MONEY、NUM、NUMBER、NUMC、PACF、SMALLFLOAT) の値は、任意の数値型とサイズを持つ項目に代入できます。EGL では、値をターゲットの形式で保持するために必要な変換が行われます。

ターゲットが固定小数点型 (FLOAT や SMALLFLOAT でないもの) の場合は、必要に応じて無効のゼロの追加または切り捨てが行われます。(値の整数部分の先頭からのゼロは無効です。同様に、値の小数部分の後続のゼロも無効です。)

いずれの数値型の場合でも、システム変数 sysVar.overflowIndicator を使用すると、代入または算術計算によって算術オーバーフローが発生したかどうかをテストできます。また、システム変数 VGVar.handleOverflow を設定すると、そうしたオーバーフローの結果を指定できます。

算術オーバーフローが発生した場合、ターゲット項目の値は変更されません。算術オーバーフローが発生しない場合、ターゲット項目に代入される値は、ターゲット項目の宣言に従って位置合わせされます。

NUM 型の項目を別の項目にコピーするときに、ソース項目の実行時の値が 108.314 であると想定しましょう。
  • ターゲット項目で 7 桁 (1 桁は小数部) を収容できる場合、ターゲット項目は値 000108.3 を受け取り、数値オーバーフローは検出されません。 (小数値の精度の情報が失われても、オーバーフローとは見なされません。)
  • ターゲット項目で 4 桁 (2 桁は小数部) を収容できる場合は、数値オーバーフローが検出され、ターゲット項目の値は変更されません。

固定小数点型の項目に浮動小数点値 (FLOAT 型または SMALLFLOAT 型) を代入すると、ターゲットの値は必要に応じて切り捨てられます。 例えば、ソース値が 108.357 で、固定小数点のターゲットの小数点以下の桁が 1 つの場合、ターゲットは 108.3 を受け取ります。

その他の異なる型への代入

その他の異なる型への代入について、以下に詳しく説明します。
  • NUM 型の値を CHAR 型のターゲットに代入する場合は、ソースの宣言に小数部がない場合にのみ、代入が有効となります。この操作は、CHAR から CHAR への代入と同等です。
    例えば、ソースの長さが 4 で値が 21 の場合、データの内容は "0021" となり、長さの不一致によってエラー条件は発生しません。
    • ターゲットの長さが 5 の場合、値は "0021 " として格納されます (右端に単一バイトのスペースが付加されます)。
    • ターゲットの長さが 3 の場合、値は "002" として格納されます (右端の 1 桁が切り捨てられます)。

    負の NUM 型の値が CHAR 型の値に代入される場合、項目にコピーされる最後のバイトは印刷不能文字となります。

  • CHAR 型の値を NUM 型のターゲットに代入する場合は、以下の場合のみ代入が有効となります。
    • ソース (項目またはストリング式) が数字のみで、他の文字を含まない。
    • ターゲットの宣言に小数部がない。

    この操作は、NUM から NUM への代入と同等です。

    例えば、ソースの長さが 4 で値が "0021" の場合、データの内容は数値の 21 と等しくなります。長さの不一致があると、次のような結果が生じます。
    • ターゲットの長さが 5 の場合、値は 00021 として格納されます (数値のゼロが左端に埋め込まれます)。
    • ターゲットの長さが 3 の場合、値は 021 として格納されます (無効な数字が切り捨てられます)。
    • ターゲットの長さが 1 の場合、値は 1 として格納されます。
  • NUMC 型の値を CHAR 型のターゲットに代入する場合は、2 段階の操作で代入が可能になります。値が正の場合は、符号が除去されます。
    1. NUMC の値を NUM 型のターゲットに代入する。
    2. NUM の値を CHAR 型のターゲットに代入する。

    NUMC 型のターゲットの値が負の場合、CHAR 型のターゲットにコピーされる最後のバイトは、印刷不能文字となります。

  • CHAR 型の値を HEX 型のターゲットに代入する場合は、ソース内の文字が 16 進数文字 (0 から 9、A から F、a から f) の範囲内にある場合にのみ、代入が有効となります。
  • HEX 型の値を CHAR 型のターゲットに代入する場合は、数字と英大文字 (A から F) がターゲットに格納されます。
  • MONEY 型の値を CHAR 型のターゲットに代入することは無効です。 MONEY から CHAR に変換する最良の方法は、システム関数の formatNumber を使用することです。
  • NUM 型または CHAR 型の値を DATE 型のターゲットに代入することは、ソース値がマスク yyyyMMdd に従った有効な日付である場合にのみ有効です。詳細については、『DATE』のトピックを参照してください。
  • NUM 型または CHAR 型の値を TIME 型のターゲットに代入することは、ソース値がマスク hhmmss に従った有効な時刻である場合にのみ有効です。詳細については、『TIME』のトピックを参照してください。
  • CHAR 型の値を TIMESTAMP 型のターゲットに代入することは、ソース値が TIMESTAMP 項目のマスクに従った有効なタイム・スタンプである場合にのみ有効です。 以下に例を示します。
       // 2 月 30 日は有効な日付でないので無効
       myTS timestamp("yyyyMMdd");
       myTS = "20050230";
    フル・マスクの先頭の文字が欠落している場合 (例えば、マスクが「dd」の場合)、EGL は、上位レベルの文字 (この例では「yyyyMM」) がマシン・クロックに従って現在の瞬間を表すものと見なします。 次の文を使用すると、2 月にランタイム・エラーが発生します。
       // 2 月に実行された場合は無効
       myTS timestamp("dd"); 
       myTS = "30";
  • TIME 型または DATE 型の値を NUM 型のターゲットに代入することは、NUM から NUM への代入と等価です。
  • TIME、DATE、または TIMESTAMP 型の値を CHAR 型のターゲットに代入することは、CHAR から CHAR への代入と等価です。

文字型に関する埋め込みと切り捨て

ターゲットが文字型 (CHAR、DBCHAR、HEX、MBCHAR、UNICODE) であり、ソース値を格納するのに必要とされる以上のスペースを持っている場合は、EGL によって右端にデータが埋め込まれます。
  • CHAR 型または MBCHAR 型のターゲットの埋め込みには、単一バイトのブランクが使用されます。
  • DBCHAR 型のターゲットの埋め込みには、2 バイトのブランクが使用されます。
  • UNICODE 型のターゲットの埋め込みには、ユニコードの 2 バイトのブランクが使用されます。
  • HEX 型のターゲットの埋め込みには、2 進ゼロが使用されます。例えば、ソース値が "0A" であるなら、2 バイトのターゲットに "000A" ではなく "0A00" として値が格納されます。
ソース値を格納するためのスペースが文字型のターゲットで不足している場合は、EGL によって右側の値が切り捨てられます。通知されるエラーはありません。以下の場合は、特殊な問題が発生することがあります。
  • ランタイム・プラットフォームで EBCDIC 文字セットがサポートされている
  • assignment 文により、MBCHAR 型のリテラルまたは MBCHAR 型の項目が、より短い MBCHAR 型の項目にコピーされる
  • 1 バイトずつ切り捨てを行うと、最後のシフトイン文字が除去されたり、DBCHAR 文字が分割されたりする

このような場合、EGL は、MBCHAR 型の有効なストリングがターゲット項目に格納されるように文字を切り捨て、必要があれば、終端に単一バイトのブランクを付加します。

タイム・スタンプ間の代入

TIMESTAMP 型の値を別の TIMESTAMP 型の項目に代入する場合は、以下の規則が適用されます。
  • ソース項目のマスクに、ターゲット項目が必要とする相対的に上位レベルのエントリーが欠落している場合、それらのターゲット・エントリーには、代入時点でのマシンのクロックに従って代入が行われます。次に例を示します。
    •   sourceTimeStamp timestamp ("MMdd");
      	 targetTimeStamp timestamp ("yyyyMMdd");
      	
      	 sourceTimeStamp = "1201";
      
        // このコードが 2004 年に実行された場合、次の文が
        // targetTimeStamp に 20041201 を代入する
      	 targetTimeStamp = sourceTimeStamp; 
    •   sourceTimeStamp02 timestamp ("ssff");
        targetTimeStamp02 timestamp ("mmssff");
      	
      	 sourceTimeStamp02 = "3201";
      
        // 次の代入は、分を含んでいる
        // それは、assignment 文が実行されたときの現行の分である
        targetTimeStamp02 = sourceTimeStamp02;
    • ソース項目のマスクに、ターゲット項目が必要とする相対的に下位レベルのエントリーが欠落している場合、それらのターゲット・エントリーには、有効な最低の値が代入されます。次に例を示します。
      • sourceTimeStamp timestamp ("yyyyMM");
        targetTimeStamp timestamp ("yyyyMMdd");
        
        sourceTimeStamp = "200412";
        
        // 日に関係なく、次の文は
        // targetTimeStamp に 20041201 を代入する
        targetTimeStamp = sourceTimeStamp; 
      • sourceTimeStamp02 timestamp ("hh");
        targetTimeStamp02 timestamp ("hhmm");
        
        sourceTimeStamp02 = "11";
        
        // 分に関係なく、次の文は
        // targetTimeStamp02 に 1100 を代入する
        targetTimeStamp02 = sourceTimeStamp02;

副構造のある項目への代入、または副構造のある項目からの代入

副構造のある項目を副構造のない項目に代入したり、その逆を行うことができます。また、2 つの副構造項目の間で値を代入できます。 例えば、myNum および myRecord という名前の変数が、次のパーツに基づいているものとします。

  DataItem myNumPart
    NUM(12)
  end

  Record myRecordPart type basicRecord
    10 topMost CHAR(4);
      20 next01 HEX(4);
      20 next02 HEX(4);
  end

数値システム・ワードの外側では、HEX 型の値を NUM 型の項目へ代入するのは無効です。しかし、myNum = topMost という書式の代入は、topMost が CHAR 型なので有効です。一般に、代入は、assignment 文内の項目のプリミティブ型に基づいて実行され、従属項目のプリミティブ型は考慮されません。

副構造のある項目のプリミティブ型は、デフォルトで CHAR に設定されています。副構造のある項目にデータを代入したり、副構造のある項目からデータを代入したりする場合、宣言時に別のプリミティブ型を指定しないと、CHAR 型の項目に対する前述の規則が代入時に適用されます。

レコードの代入

レコードから別のレコードへの代入は、CHAR 型の副構造の項目から別の CHAR 型の副構造の項目への代入と同等です。長さの不一致があると、受け取った値の右端に単一バイトのブランクが付加されたり、受け取った値の右端から 1 バイトの文字が除去されたりします。代入では、従属構造体項目のプリミティブ型は考慮されません。

前述したように、次のような例外があります。
  • レコードの内容を代入できるのは、レコードまたは、CHAR 型、HEX 型、または MBCHAR 型の項目です。その他の型の項目には代入することはできません。
  • レコードが受け取ることができるのは、レコードからのデータ、文字列リテラルからのデータ、または CHAR 型、HEX 型、または MBCHAR 型の項目からのデータです。数値リテラルからのデータ、または CHAR 型、HEX 型、MBCHAR 型以外の項目からのデータを受け取ることはできません。

最後に、SQL レコードと、異なる型のレコードとの間で代入を行う場合は、 構造体の各項目に先行する 4 バイトの領域のためのスペースを非 SQL レコードに確保する必要があります。

関連する概念
構文図

ご利用条件 | フィードバック
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.(C) Copyright IBM Japan 2005.