このドキュメントでは、次のトピックについて説明します。
通常、次の規則が適用されます。
ダイナミック英数字フィールドは、英数字フィールドを使用できる場所であればどこにでも使用できます。
ダイナミックバイナリフィールドは、バイナリフィールドを使用できる場所であればどこにでも使用できます。
ダイナミック Unicode フィールドは、Unicode フィールドを使用できる場所であればどこにでも使用できます。
ダイナミック変数は、SORT
ステートメント内では使用できません。ダイナミック変数を DISPLAY
、WRITE
、PRINT
、REINPUT
または INPUT
の各ステートメント内で使用するには、セッションパラメータ AL
または EM
のいずれかを使用して変数の長さを定義する必要があります。
ダイナミック変数に割り当てられているストレージの使用長(Natural システム変数 *LENGTH
によって示される。「ダイナミック変数の現在の値スペース」を参照)およびサイズは、その変数がターゲットオペランドとして最初にアクセスされるまではゼロです。割り当て操作またはその他の操作によって、ダイナミック変数はソースオペランドの正確なサイズに初めて割り当てまたは拡張(再割り当て)されます。
以下のステートメントで変更可能なオペランド(ターゲットオペランド)としてダイナミック変数を使用する場合、ダイナミック変数のサイズを拡張できます。
ASSIGN |
operand1 (割り当て内の応答先オペランド)。
|
CALLNAT |
「ダイナミック変数を使用したパラメータ引き渡し」を参照してください(AD=O 、または対応するパラメータデータエリア内に BY
VALUE が存在する場合を除く)。
|
COMPRESS |
operand2 。「処理」を参照してください。
|
EXAMINE |
DELETE
REPLACE 節の operand1 。
|
MOVE |
operand2 (応答先オペランド)。「機能」を参照してください。
|
PERFORM |
(AD=O 、または対応するパラメータデータエリア内に BY
VALUE が存在する場合を除く)。
|
READ WORK
FILE |
operand1 および operand2 。「」「ラージ変数およびダイナミック変数の処理」を参照してください。
|
SEPARATE |
operand4 。
|
SELECT (SQL)
|
parameter INTO 節。into-clause を参照してください。
|
SEND
METHOD |
operand3 (AD=O の場合を除く)。
|
現時点では、ラージ変数の使用には以下の制限があります。
CALL |
各パラメータのサイズは 64 KB 未満です(INTERFACE4 オプションを使用した CALL には制限はありません)。
|
以下のセクションでは、ダイナミック変数の使用について、例に基づいてさらに詳しく説明します。
通常は、ソースオペランドの現在の使用長(Natural システム変数 *LENGTH
によって示される)で割り当てが行われます。応答先オペランドがダイナミック変数の場合、ソースオペランドを切り捨てずに移動できるよう、現在割り当てられているサイズが拡張される場合があります。
例:
#MYDYNTEXT1 := OPERAND MOVE OPERAND TO #MYDYNTEXT1 /* #MYDYNTEXT1 IS AUTOMATICALLY EXTENDED UNTIL THE SOURCE OPERAND CAN BE COPIED
MOVE
ALL
、およびダイナミックターゲットオペランドを使用した MOVE ALL UNTIL
は、以下のように定義されています。
MOVE ALL
では、ターゲットオペランドの使用長(*LENGTH
)に到達するまで、ソースオペランドをターゲットオペランドに繰り返し移動します。システム変数 *LENGTH
は変更されません。*LENGTH
がゼロの場合、このステートメントは無視されます。
MOVE ALL operand1 TO
operand2 UNTIL operand3
は、operand3
で指定された長さに達するまで、operand1
を繰り返し operand2
に移動します。operand3
が *LENGTH(operand2)
より大きい場合、operand2
は拡張され、*LENGTH(operand2)
は operand3
に設定されます。operand3
が *LENGTH(operand2)
より小さい場合、使用長は operand3
に縮小されます。operand3
が *LENGTH(operand2)
に等しい場合、動作は MOVE ALL
と等しくなります。
例:
#MYDYNTEXT1 := 'ABCDEFGHIJKLMNO' /* *LENGTH(#MYDYNTEXT1) = 15 MOVE ALL 'AB' TO #MYDYNTEXT1 /* CONTENT OF #MYDYNTEXT1 = 'ABABABABABABABA'; /* *LENGTH IS STILL 15 MOVE ALL 'CD' TO #MYDYNTEXT1 UNTIL 6 /* CONTENT OF #MYDYNTEXT1 = 'CDCDCD'; /* *LENGTH = 6 MOVE ALL 'EF' TO #MYDYNTEXT1 UNTIL 10 /* CONTENT OF #MYDYNTEXT1 = 'EFEFEFEFEF'; /* *LENGTH = 10
MOVE JUSTIFIED
は、ターゲットオペランドがダイナミック変数の場合、コンパイル時に拒否されます。
MOVE SUBSTR
および MOVE TO SUBSTR
は実行できます。MOVE SUBSTR
は、ダイナミック変数の使用長(*LENGTH
)を超えるサブストリングを参照すると、ランタイムエラーになります。MOVE TO
SUBSTR
は、*LENGTH + 1
を超えるサブストリングの位置を参照すると、ダイナミック変数の内容に未定義のギャップが生じるため、ランタイムエラーになります。ターゲットオペランドを MOVE TO SUBSTR
で拡張する必要がある場合(第 2 オペランドが *LENGTH+1
に設定されている場合など)、第 3 オペランドは必須です。
有効な構文:
#OP2 := *LENGTH(#MYDYNTEXT1) MOVE SUBSTR (#MYDYNTEXT1, #OP2) TO OPERAND /* MOVE LAST CHARACTER TO OPERAND #OP2 := *LENGTH(#MYDYNTEXT1) + 1 MOVE OPERAND TO SUBSTR(#MYDYNTEXT1, #OP2, #lEN_OPERAND) /* CONCATENATE OPERAND TO #MYDYNTEXT1
無効な構文:
#OP2 := *LENGTH(#MYDYNTEXT1) + 1 MOVE SUBSTR (#MYDYNTEXT1, #OP2, 10) TO OPERAND /* LEADS TO RUNTIME ERROR; UNDEFINED SUB-STRING #OP2 := *LENGTH(#MYDYNTEXT1 + 10) MOVE OPERAND TO SUBSTR(#MYDYNTEXT1, #OP2, #EN_OPERAND) /* LEADS TO RUNTIME ERROR; UNDEFINED GAP #OP2 := *LENGTH(#MYDYNTEXT1) + 1 MOVE OPERAND TO SUBSTR(#MYDYNTEXT1, #OP2) /* LEADS TO RUNTIME ERROR; UNDEFINED LENGTH
例:
#MYDYNTEXT1 := #MYSTATICVAR1 #MYSTATICVAR1 := #MYDYNTEXT2
ソースオペランドがスタティック変数の場合、ダイナミックな応答先オペランドの使用長(*LENGTH(#MYDYNTEXT1)
)はスタティック変数のフォーマット長に設定され、末尾の空白(フォーマット A および U)またはバイナリゼロ(フォーマット B)を含め、この長さでソースオペランドがコピーされます。
応答先オペランドがスタティックでソースオペランドがダイナミックの場合、ダイナミック変数は現在の使用長でコピーされます。この長さがスタティック変数のフォーマット長より短い場合、残りの部分は空白(英数字フィールドおよび Unicode フィールドの場合)またはバイナリゼロ(バイナリフィールドの場合)で埋められます。そうでない場合、値は切り捨てられます。ダイナミック変数の現在の使用長が 0 の場合、スタティックのターゲットオペランドは空白(英数字フィールドおよび Unicode フィールドの場合)またはバイナリゼロ(バイナリフィールドの場合)で埋められます。
ダイナミック変数は、RESET
ステートメントを使用して、最大で現在の使用長(= *LENGTH
)まで、空白(英数字フィールドおよび Unicode フィールドの場合)またはゼロ(バイナリフィールドの場合)で初期化できます。システム変数 *LENGTH
は変更されません。
例:
DEFINE DATA LOCAL 1 #MYDYNTEXT1 (A) DYNAMIC END-DEFINE #MYDYNTEXT1 := 'SHORT TEXT' WRITE *LENGTH(#MYDYNTEXT1) /* USED LENGTH = 10 RESET #MYDYNTEXT1 /* USED LENGTH = 10, VALUE = 10 BLANKS
ダイナミック変数を特定のサイズと値で初期化するには、MOVE ALL
UNTIL
ステートメントを使用します。
例:
MOVE ALL 'Y' TO #MYDYNTEXT1 UNTIL 15 /* #MYDYNTEXT1 CONTAINS 15 'Y'S, USED LENGTH = 15
変更可能なオペランドがダイナミック変数の場合、切り捨てまたはエラーメッセージを発生させずに操作できるよう、現在割り当てられているサイズが拡張される場合があります。これは、ダイナミック変数の連結(COMPRESS
)および分割(SEPARATE
)で有効です。
例:
** Example 'DYNAMX01': Dynamic variables (with COMPRESS and SEPARATE) ************************************************************************ DEFINE DATA LOCAL 1 #MYDYNTEXT1 (A) DYNAMIC 1 #TEXT (A20) 1 #DYN1 (A) DYNAMIC 1 #DYN2 (A) DYNAMIC 1 #DYN3 (A) DYNAMIC END-DEFINE * MOVE ' HELLO WORLD ' TO #MYDYNTEXT1 WRITE #MYDYNTEXT1 (AL=25) 'with length' *LENGTH (#MYDYNTEXT1) /* dynamic variable with leading and trailing blanks * MOVE ' HELLO WORLD ' TO #TEXT * MOVE #TEXT TO #MYDYNTEXT1 WRITE #MYDYNTEXT1 (AL=25) 'with length' *LENGTH (#MYDYNTEXT1) /* dynamic variable with whole variable length of #TEXT * COMPRESS #TEXT INTO #MYDYNTEXT1 WRITE #MYDYNTEXT1 (AL=25) 'with length' *LENGTH (#MYDYNTEXT1) /* dynamic variable with leading blanks of #TEXT * * #MYDYNTEXT1 := 'HERE COMES THE SUN' SEPARATE #MYDYNTEXT1 INTO #DYN1 #DYN2 #DYN3 IGNORE * WRITE / #MYDYNTEXT1 (AL=25) 'with length' *LENGTH (#MYDYNTEXT1) WRITE #DYN1 (AL=25) 'with length' *LENGTH (#DYN1) WRITE #DYN2 (AL=25) 'with length' *LENGTH (#DYN2) WRITE #DYN3 (AL=25) 'with length' *LENGTH (#DYN3) /* #DYN1, #DYN2, #DYN3 are automatically extended or reduced * EXAMINE #MYDYNTEXT1 FOR 'SUN' REPLACE 'MOON' WRITE / #MYDYNTEXT1 (AL=25) 'with length' *LENGTH (#MYDYNTEXT1) /* #MYDYNTEXT1 is automatically extended or reduced * END
注意:
非ダイナミック変数の場合、エラーメッセージが返されます。
ダイナミック変数を使用して読み取り専用の操作(比較など)を行う場合、通常は現在の使用長を使用して実行されます。読み取り操作(変更なし)で使用される場合、ダイナミック変数はスタティック変数と同様に処理されます。
例:
IF #MYDYNTEXT1 = #MYDYNTEXT2 OR #MYDYNTEXT1 = "**" THEN ... IF #MYDYNTEXT1 < #MYDYNTEXT2 OR #MYDYNTEXT1 < "**" THEN ... IF #MYDYNTEXT1 > #MYDYNTEXT2 OR #MYDYNTEXT1 > "**" THEN ...
英数字変数および Unicode 変数の末尾の空白またはバイナリ変数の先頭のバイナリゼロは、スタティック変数とダイナミック変数で同様に処理されます。例えば、AA
および空白が続く AA
を値として持つ英数字変数は同一とみなされ、H’0000031’
および H’3031’
という値を持つバイナリ変数は同一とみなされます。値が完全に同じ場合にのみ比較結果を TRUE
とする場合は、ダイナミック変数の使用長も比較する必要があります。一方の変数ともう一方の変数の値が完全に同じであれば、その使用長もまた同じです。
例:
#MYDYNTEXT1 := 'HELLO' /* USED LENGTH IS 5 #MYDYNTEXT2 := 'HELLO ' /* USED LENGTH IS 10 IF #MYDYNTEXT1 = #MYDYNTEXT2 THEN ... /* TRUE IF #MYDYNTEXT1 = #MYDYNTEXT2 AND *LENGTH(#MYDYNTEXT1) = *LENGTH(#MYDYNTEXT2) THEN ... /* FALSE
2 つのダイナミック変数は、どちらか短い方の使用長に達するまで 1 ポジションずつ比較されます(英数字変数の場合は左から右、バイナリ変数の場合は右から左)。最初に値が異なったポジションで、1 番目の変数と 2 番目の変数のどちらがより大きいか、小さいか、または同じかが判断されます。変数の短い方の使用長まで値が同じで、長い方の残りの値がダイナミック英数字変数の場合は空白のみ、ダイナミックバイナリ変数の場合はバイナリゼロのみの場合、それらの変数は同じとみなされます。2 つのダイナミック Unicode 変数を比較する場合、両方の値の末尾の空白を削除してから、ICU 照合アルゴリズムを使用して 2 つの値が比較されます。『Unicode とコードページのサポート』ドキュメントの「論理条件の基準」も参照してください。
例:
#MYDYNTEXT1 := 'HELLO1' /* USED LENGTH IS 6 #MYDYNTEXT2 := 'HELLO2' /* USED LENGTH IS 10 IF #MYDYNTEXT1 < #MYDYNTEXT2 THEN ... /* TRUE #MYDYNTEXT2 := 'HALLO' IF #MYDYNTEXT1 > #MYDYNTEXT2 THEN ... /* TRUE
ダイナミック変数とスタティック変数の比較は、ダイナミック変数間の比較と同じです。スタティック変数のフォーマット長が使用長として使用されます。
例:
#MYSTATTEXT1 := 'HELLO' /* FORMAT LENGTH OF MYSTATTEXT1 IS A20 #MYDYNTEXT1 := 'HELLO' /* USED LENGTH IS 5 IF #MYSTATTEXT1 = #MYDYNTEXT1 THEN ... /* TRUE IF #MYSTATTEXT1 > #MYDYNTEXT1 THEN ... /* FALSE
ブレイクコントロールフィールドの元の値との比較は、左から右に向かって 1 ポジションずつ実行されます。ダイナミック変数の元の値と新しい値で長さが異なる場合、比較するために長さが短い方の値の右側に空白(ダイナミック英数字変数またはダイナミック Unicode 変数の場合)またはバイナリゼロ(バイナリ値の場合)が追加されます。
英数字または Unicode のブレイクコントロールフィールドの場合、比較において末尾の空白は意味を持ちません。つまり、末尾の空白は値の変更を意味しないため、ブレイクは発生しません。
バイナリのブレイクコントロールフィールドの場合、比較において末尾のバイナリゼロは意味を持ちません。つまり、末尾のバイナリゼロは値の変更を意味しないため、ブレイクは発生しません。
ダイナミック変数は、呼び出されたプログラムオブジェクト(CALLNAT
、PERFORM
)へのパラメータとして渡すことができます。ダイナミック変数の値スペースは連続しているので、値による呼び出しが可能です。値による呼び出しを使用すると、呼び出し元の変数定義がソースオペランドとして割り当てられ、パラメータ定義が応答先オペランドとして割り当てられます。また、値による呼び出しの結果では、逆方向にデータが移動します。
参照による呼び出しを使用する場合、変数定義およびパラメータ定義は DYNAMIC
である必要があります。そのうちの 1 つだけが DYNAMIC
の場合、ランタイムエラーが発生します。値による呼び出し(結果)の場合、すべての組み合わせを使用できます。以下の表に、有効な組み合わせを示します。
呼び出し元 | パラメータ | |
---|---|---|
スタティック | ダイナミック | |
スタティック | 可 | 不可 |
ダイナミック | 不可 | 可 |
ダイナミック変数 A または B のフォーマットは一致する必要があります。
呼び出し元 | パラメータ | |
---|---|---|
スタティック | ダイナミック | |
スタティック | 可 | 可 |
ダイナミック | 可 | 可 |
注意:
スタティック/ダイナミック定義またはダイナミック/スタティック定義を使用する場合、割り当てのデータ転送規則によって値が切り捨てられることがあります。
** Example 'DYNAMX02': Dynamic variables (as parameters) ************************************************************************ DEFINE DATA LOCAL 1 #MYTEXT (A) DYNAMIC END-DEFINE * #MYTEXT := '123456' /* extended to 6 bytes, *LENGTH(#MYTEXT) = 6 * CALLNAT 'DYNAMX03' USING #MYTEXT * WRITE *LENGTH(#MYTEXT) /* *LENGTH(#MYTEXT) = 8 * END
サブプログラム DYNAMX03
:
** Example 'DYNAMX03': Dynamic variables (as parameters) ************************************************************************ DEFINE DATA PARAMETER 1 #MYPARM (A) DYNAMIC BY VALUE RESULT END-DEFINE * WRITE *LENGTH(#MYPARM) /* *LENGTH(#MYPARM) = 6 #MYPARM := '1234567' /* *LENGTH(#MYPARM) = 7 #MYPARM := '12345678' /* *LENGTH(#MYPARM) = 8 EXPAND DYNAMIC VARIABLE #MYPARM TO 10 /* 10 bytes are allocated * WRITE *LENGTH(#MYPARM) /* *LENGTH(#MYPARM) = 8 * /* content of #MYPARM is moved back to #MYTEXT /* used length of #MYTEXT = 8 * END
** Example 'DYNAMX04': Dynamic variables (as parameters) ************************************************************************ DEFINE DATA LOCAL 1 #MYTEXT (A) DYNAMIC END-DEFINE * #MYTEXT := '123456' /* extended to 6 bytes, *LENGTH(#MYTEXT) = 6 * CALLNAT 'DYNAMX05' USING #MYTEXT * WRITE *LENGTH(#MYTEXT) /* *LENGTH(#MYTEXT) = 8 /* at least 10 bytes are /* allocated (extended in DYNAMX05) * END
サブプログラム DYNAMX05
:
** Example 'DYNAMX05': Dynamic variables (as parameters) ************************************************************************ DEFINE DATA PARAMETER 1 #MYPARM (A) DYNAMIC END-DEFINE * WRITE *LENGTH(#MYPARM) /* *LENGTH(#MYPARM) = 6 #MYPARM := '1234567' /* *LENGTH(#MYPARM) = 7 #MYPARM := '12345678' /* *LENGTH(#MYPARM) = 8 EXPAND DYNAMIC VARIABLE #MYPARM TO 10 /* 10 bytes are allocated * WRITE *LENGTH(#MYPARM) /* *LENGTH(#MYPARM) = 8 * END
CALL
ステートメントで INTERFACE4
オプションを使用すると、ダイナミック変数およびラージ変数を有効に使用できます。このオプションを使用すると、異なるパラメータ構造を使用した 3GL プログラムとのインターフェイスになります。
このインターフェイスを使用するには 3GL プログラムを少々変更する必要がありますが、従来の FINFO
構造体と比較して、以下のような大きな利点があります。
渡すパラメータの数は無制限です(従来の制限:40)。
パラメータのデータサイズは無制限です(従来の制限:パラメータ当たり 64 KB)。
配列情報を含め、完全なパラメータ情報を 3GL プログラムに渡すことができます。パラメータデータへの安全なアクセスを可能にする、エクスポートされたファンクションが用意されています(従来は Natural 内部でメモリを上書きしないよう注意する必要がありました)。
FINFO
構造体の詳細については、CALL
INTERFACE4
ステートメントの説明を参照してください。
ダイナミックパラメータを使用して 3GL プログラムを呼び出す前に、必要なバッファサイズを必ず割り当てるようにしてください。これは、EXPAND
ステートメントを使用すると明示的に実行できます。
バッファを初期化する必要がある場合、MOVE ALL UNTIL
ステートメントを使用することにより、ダイナミック変数を初期値および必要なサイズに設定できます。Natural には、3GL プログラムでダイナミックパラメータに関する情報を取得し、パラメータデータを返すときに長さを変更できるようにする、一連のファンクションが用意されています。
例:
MOVE ALL ' ' TO #MYDYNTEXT1 UNTIL 10000 /* a buffer of length 10000 is allocated /* #MYDYNTEXT1 is initialized with blanks /* and *LENGTH(#MYDYNTEXT1) = 10000 CALL INTERFACE4 'MYPROG' USING #MYDYNTEXT1 WRITE *LENGTH(#MYDYNTEXT1) /* *LENGTH(#MYDYNTEXT1) may have changed in the 3GL program
詳細については、『ステートメント』ドキュメントに記載されている、CALL
ステートメントの説明を参照してください。
以下では次のトピックについて説明します。
2 つのワークファイルタイプ PORTABLE
と UNFORMATTED
を使用して、ラージ変数およびダイナミック変数をワークファイルに書き込んだりワークファイルから読み取ったりできます。これらのタイプには、ダイナミック変数に対するサイズ制限がありません。ただし、ラージ変数は最大フィールド/レコード長の 32766
バイトを超えることはできません。
ワークファイルタイプ PORTABLE
の場合は、フィールド情報がワークファイル内に保存されます。レコード内のフィールドサイズが現在のサイズと異なる場合は、ダイナミック変数は READ
中にサイズ変更されます。
ワークファイルタイプ UNFORMATTED
は、例えば、データベースから読み込んだビデオを、他のユーティリティで再生可能なファイルに直接格納する場合などに使用できます。WRITE WORK
ステートメントでは、フィールドはそのバイト長でファイルに書き込まれます。すべてのデータタイプ(DYNAMIC
であるかどうかに関わらず)は同じように扱われます。構造情報は挿入されません。Natural ではバッファリングメカニズムを使用するので、データが完全に書き込まれるのは CLOSE WORK
の後のみであることが予測できます。これは、Natural の稼働中にファイルが別のユーティリティで処理される場合に特に重要です。
READ WORK
ステートメントでは、固定長のフィールドはその全体の長さで読み込まれます。ファイルの終わりに到達すると、現在のフィールドの残りは空白で埋められます。次のフィールドは変更されません。データタイプが DYNAMIC
の場合、ファイルが 1073741824 バイトを超えない限り、ファイルの残りの部分がすべて読み込まれます。ファイルの終わりに到達すると、残りのフィールド(変数)は変更されないまま維持されます(通常の Natural の動作)。
ワークファイルタイプ ASCII、ASCII-COMPRESSED、および SAG(バイナリ)では、ダイナミック変数は処理できず、エラーが生成されます。これらのワークファイルタイプに対するラージ変数では、フィールド/レコードの最大長である 32766 バイトを超えない限り、問題は発生しません。
READ WORK FILE
ステートメントとともに使用すると、ワークファイルタイプ TRANSFER
はダイナミック変数を処理できます。この場合、ダイナミック変数に対するサイズ制限はありません。ワークファイルタイプ ENTIRE
CONNECTION
では、ダイナミック変数は処理できません。ただし、これらは両方とも、最長フィールド/レコードである 1073741824 バイトのラージ変数を処理できます。
WRITE WORK FILE
ステートメントとともに使用すると、ワークファイルタイプ TRANSFER
は、フィールド/レコードの最大長が 32766 バイトのダイナミック変数を処理できます。ワークファイルタイプ ENTIRE
CONNECTION
では、ダイナミック変数は処理できません。ただし、これらは両方とも、最長フィールド/レコードである 1073741824 バイトのラージ変数を処理できます。
データタイプに応じて、対応するデータベースフォーマット A または フォーマット B が生成されます。データベースのデータタイプが VARCHAR
の場合、Natural の列の長さは DBMS で定義されているデータタイプの最大長に設定されます。データタイプが非常に大きい場合、フィールド長の位置にキーワード DYNAMIC
が生成されます。
すべての可変長の列に対し、LINDICATOR
フィールド L@<column-name>
が生成されます。データベースのデータタイプが VARCHAR
の場合、フォーマット/長さが I2 の LINDICATOR
フィールドが生成されます。大きなデータタイプ(下表参照)の場合、フォーマット/長さは I4 になります。
データベースにアクセスするときには、LINDICATOR
を操作することにより、定義済みのバッファ長(または *LENGTH
)に関係なく、読み込むフィールドの長さを取得したり、書き込むフィールドの長さを設定したりできます。通常は、取得処理の後、対応するインジケータの長さに *LENGTH
は設定されます。
T L Name F Leng S D Remark : 1 L@PICTURE1 I 4 /* length indicator 1 PICTURE1 B DYNAMIC IMAGE 1 N@PICTURE1 I 2 /* NULL indicator 1 L@TEXT1 I 4 /* length indicator 1 TEXT1 A DYNAMIC TEXT 1 N@TEXT1 I 2 /* NULL indicator 1 L@DESCRIPTION I 2 /* length indicator 1 DESCRIPTION A 1000 VARCHAR(1000) : : ~~~~~~~~~~~~~~~~~~~~~~Extended Attributes~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/* concerning PICTURE1 Header : --- Edit Mask : --- Remarks : IMAGE
生成されるフォーマットは可変長のフォーマットです。Natural プログラマは、定義を DYNAMIC
から固定長に変更したり(拡張フィールド編集)、データタイプ VARCHAR
に対応する DDM のフィールド定義をマルチプルバリューフィールド(従来の生成タイプ)にしたりできます。
T L Name F Leng S D Remark : 1 L@PICTURE1 I 4 /* length indicator 1 PICTURE1 B 1000000000 IMAGE 1 N@PICTURE1 I 2 /* NULL indicator 1 L@TEXT1 I 4 /* length indicator 1 TEXT1 A 5000 TEXT 1 N@TEXT1 I 2 /* NULL indicator 1 L@DESCRIPTION I 2 /* length indicator M 1 DESCRIPTION A 100 VARCHAR(1000) : : ~~~~~~~~~~~~~~~~~~~~Extended Attributes~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/* concerning PICTURE1 Header : --- Edit Mask : --- Remarks : IMAGE
データベースのラージオブジェクト(CLOB または BLOB)にアクセスするには、対応する英数字、Unicode、またはバイナリの各ラージフィールドの DDM を使用する必要があります。フィールドが固定長で定義され、データベースのラージオブジェクトがこのフィールドに収まらない場合、ラージオブジェクトは切り捨てられます。データベースオブジェクトの明確な長さがわからない場合、ダイナミックフィールドを使用します。そのオブジェクトを保持するために必要な再割り当てが行われます。切り捨ては行われません。
DEFINE DATA LOCAL 1 person VIEW OF xyz-person 2 last_name 2 first_name_1 2 L@PICTURE1 /* I4 length indicator for PICTURE1 2 PICTURE1 /* defined as dynamic in the DDM 2 TEXT1 /* defined as non-dynamic in the DDM END-DEFINE SELECT * INTO VIEW person FROM xyz-person /* PICTURE1 will be read completely WHERE last_name = 'SMITH' /* TEXT1 will be truncated to fixed length 5000 WRITE 'length of PICTURE1: ' L@PICTURE1 /* the L-INDICATOR will contain the length /* of PICTURE1 (= *LENGTH(PICTURE1) /* do something with PICTURE1 and TEXT1 L@PICTURE1 := 100000 INSERT INTO xyz-person (*) VALUES (VIEW person) /* only the first 100000 Bytes of PICTURE1 /* are inserted END-SELECT
ビューのフォーマット/長さの定義が省略されている場合、DDM の定義が使用されます。レポーティングモードでは、対応する DDM フィールドが DYNAMIC
で定義されている場合、任意の長さを指定できます。ダイナミックフィールドは、固定長のバッファにマップされます。この逆は実行できません。
DDM のフォーマット/長さの定義 | ビューのフォーマット/長さの定義 | |
---|---|---|
(An) | - | 有効 |
(An) | 有効 | |
(Am) | レポーティングモードでのみ有効 | |
(A) DYNAMIC | 無効 | |
(A) DYNAMIC | - | 有効 |
(A) DYNAMIC | 有効 | |
(An) | レポーティングモードでのみ有効 | |
(Am / i : j) | レポーティングモードでのみ有効 |
フォーマット B の変数も同様です。
LINDICATOR
フィールドを I2 フィールドとして定義すると、対応する列の送受信には SQL データタイプ VARCHAR
が使用されます。LINDICATOR
ホスト変数を I4 として指定する場合、ラージオブジェクトデータタイプ(CLOB/BLOB)を使用します。
フィールドを DYNAMIC
として定義すると、列は内部ループでは実際の長さまで読み取られます。LINDICATOR
フィールドとシステム変数 *LENGTH
がこの長さに設定されます。固定長フィールドの場合、定義した長さまで列が読み込まれます。いずれの場合も、フィールドは LINDICATOR
フィールドで定義した値まで書き込まれます。
ダイナミック変数を少量ずつ複数回にわたって拡張する場合(バイト単位など)、必要なストレージの(おおよその)上限がわかっているときは、拡張を繰り返すのではなく EXPAND
ステートメントを使用します。これにより、必要なストレージを調整するための余分なオーバーヘッドを回避できます。
ダイナミック変数が不要になった場合、特に *LENGTH
の値が大きい変数の場合は、REDUCE
ステートメントまたは RESIZE
ステートメントを使用します。これにより、Natural でストレージを解放または再利用できます。したがって、全体的なパフォーマンスが向上します。
ダイナミック変数に割り当てられているメモリの量は、REDUCE DYNAMIC
VARIABLE
ステートメントを使用すると減らすことができます。変数に特定の長さを(再)割り当てするには、EXPAND
ステートメントを使用できます(変数を初期化する場合は、MOVE ALL UNTIL
ステートメントを使用します)。
** Example 'DYNAMX06': Dynamic variables (allocated memory) ************************************************************************ DEFINE DATA LOCAL 1 #MYDYNTEXT1 (A) DYNAMIC 1 #LEN (I4) END-DEFINE * #MYDYNTEXT1 := 'a' /* used length is 1, value is 'a' /* allocated size is still 1 WRITE *LENGTH(#MYDYNTEXT1) * EXPAND DYNAMIC VARIABLE #MYDYNTEXT1 TO 100 /* used length is still 1, value is 'a' /* allocated size is 100 * CALLNAT 'DYNAMX05' USING #MYDYNTEXT1 WRITE *LENGTH(#MYDYNTEXT1) /* used length and allocated size /* may have changed in the subprogram * #LEN := *LENGTH(#MYDYNTEXT1) REDUCE DYNAMIC VARIABLE #MYDYNTEXT1 TO #LEN /* if allocated size is greater than used length, /* the unused memory is released * REDUCE DYNAMIC VARIABLE #MYDYNTEXT1 TO 0 WRITE *LENGTH(#MYDYNTEXT1) /* free allocated memory for dynamic variable END
ダイナミックオペランドは、適切な場所で使用します。
メモリ使用量の上限がわかっている場合は、EXPAND
ステートメントを使用します。
ダイナミックオペランドが不要になった場合は、REDUCE
ステートメントを使用します。
ダイナミック変数は、以下のような出力ステートメント内で使用できます。
ステートメント | 注 |
---|---|
DISPLAY |
これらのステートメントでは、セッションパラメータの AL (出力に対する英数字長)またはEM (編集マスク)を使用して、ダイナミック変数の入出力フォーマットを設定する必要があります。
|
WRITE |
|
INPUT |
|
REINPUT |
-- |
PRINT |
PRINT ステートメントの出力はフォーマットが指定されていないため、AL および EM パラメータを使用して、PRINT ステートメント内のダイナミック変数の出力フォーマットを設定する必要はありません。したがって、これらのパラメータは無視されます。
|
ダイナミック X-array の割り当てでは、最初にオカレンス数を指定し、後でそのオカレンス数を拡張できます。
例:
DEFINE DATA LOCAL 1 #X-ARRAY(A/1:*) DYNAMIC END-DEFINE * EXPAND ARRAY #X-ARRAY TO (1:10) /* Current boundaries (1:10) #X-ARRAY(*) := 'ABC' EXPAND ARRAY #X-ARRAY TO (1:20) /* Current boundaries (1:20) #X-ARRAY(11:20) := 'DEF'