Fast/Unload BLOB/CLOB processing considerations: Difference between revisions

From m204wiki
Jump to navigation Jump to search
(Automatically generated page update)
 
m (link repair)
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<!-- Page name: Fast/Unload BLOB/CLOB processing considerations-->
As of version 4.3, <var class="product">Fast/Unload</var> included the ability
<p></p>
to operate on <var>BLOB</var> and <var>CLOB</var> (collectively called "Lob") fields, which
As of version 4.3, <var class="product">Fast/Unload</var> includes the ability
to operate on BLOB and CLOB (collectively called "Lob") fields, which
were introduced with V6R1 of <var class="product">Model 204</var>.
were introduced with V6R1 of <var class="product">Model 204</var>.
<p></p>
<p class="note"><b>Note:</b> Processing <var>BLOB</var> or <var>CLOB</var> fields that have the <var>[[Field_design#DEFAULT-VALUE (DV) attribute|DEFAULT-VALUE]]</var> attribute requires <var class="product">Fast/Unload</var> version 4.6 or higher. </p>
 
The following <var class="product">Fast/Unload</var> 4.3 features support these fields:
The following <var class="product">Fast/Unload</var> 4.3 features support these fields:
<ul>
<ul>
<li>NEW field declaration statements
<li><var>NEW</var> field declaration statements
may have a WITH CLOB or WITH BLOB designation
may have a <var>WITH CLOB</var> or <var>WITH BLOB</var> designation
(for example, for creating a Lob field by concatenating "old"
(for example, for creating a Lob field by concatenating "old"
non-Lob fields).
non-Lob fields).
See [[#newlob|NEW statement option for Lobs]].
See [[#newlob|NEW statement option for Lobs]]. </li>
 
<li>#functions may both accept arguments and produce
<li>#functions may both accept arguments and produce
results in excess of 255 bytes.
results in excess of 255 bytes.
See:
See:
<ul>
<ul>
<li>[[#concat|#CONCAT supports long string arguments and result]]
<li>[[#concat|#CONCAT supports long string arguments and result]] </li>
<li>[[#len|#LEN supports a long string argument]]
<li>[[#len|#LEN supports a long string argument]] </li>
<li>[[#substr|#SUBSTR supports a long string argument and result]]
<li>[[#substr|#SUBSTR supports a long string argument and result]] </li>
</ul>
</ul> </li>
 
<li>The contexts where FUEL %variables may contain strings longer
<li>The contexts where FUEL %variables may contain strings longer
than 255 bytes,
than 255 bytes, the statements, #functions, and directives that allow
the statements, #functions, and directives that allow
string values longer than 255 bytes, and the contexts where Lob fields may be used are specified
string values longer than 255 bytes,
(see [[#conlong|Contexts for long strings and Lobs]]). </li>
and the contexts where Lob fields may be used are specified
 
(see [[#conlong|Contexts for long strings and Lobs]]).
<li>A job statistic reports Table E page usage for each Lob field
<li>A job statistic reports Table E page usage for each Lob field
([[#stat|Lob statistics]]).
([[#stat|Lob statistics]]). </li>
</ul>
</ul>
<p></p>
<p>
The above features are discussed in the rest of this wiki page,
The above features are discussed in the rest of this wiki page,
at the end of which is a pair of examples
at the end of which are two examples
that use these features ([[#exlong|Lob field examples]]).
that use these features ([[#exlong|Lob field examples]]). </p>
<div id="statfun"></div>
==Statement and #function modifications==
<!--Caution: <div> above-->
<p></p>
The NEW statement and three #functions are changed to define
Lob fields and work with strings longer than 255 bytes.
   
   
<div id="newlob"></div>
==<b id="statfun"></b>Statement and #function modifications==
===NEW statement option for Lobs===
<p>
<!--Caution: <div> above-->
The <var>NEW</var> statement and three #functions let you define
Lob fields and work with strings longer than 255 bytes. </p>
   
   
<p></p>
===<b id="newlob"></b>NEW statement option for Lobs===
As of version 4.3, the NEW statement
<p>
([[#newfld|NEW fieldname [WITH BLOB | CLOB&#x5C;]]) lets you specify that the
As of version 4.3, the <var>NEW</var> statement
new field you are defining is either a BLOB or CLOB field.
([[Fast/Unload Extraction Language (FUEL)#newfld|NEW fieldname [WITH BLOB | CLOB&#x5C;]]) lets you specify that the new field you are defining is either a <var>BLOB</var> or <var>CLOB</var> field. This is primarily useful for a <var>UAI</var>-type unload, allowing you to
This is primarily useful for a UAI type unload, allowing you to
create values in the new field that are loaded by <var>LAI</var> as Lob occurrences.
create values in the new field that are loaded by LAI as Lob
</p>
occurrences.
<p>
<p></p>
The syntax is: </p>
<p></p>
<p class="syntax">NEW <span class="term">fieldname</span> WITH BLOB | CLOB
The syntax is:
</p>
<p class="code"><nowiki>NEW fieldname WITH BLOB | CLOB
<p class="note"><b>Note:</b> Version 4.3 also introduced a change to the default attributes that are assigned to fields defined with <var>NEW</var>.
</nowiki></p>
As of version 4.3, the default attributes are <var>NFRV</var>, <var>NKEY</var>, <var>NCOD</var>, <var>UPDATE IN PLACE</var>
<blockquote class="note"><b>Note:</b> Version 4.3 also introduces a change to the default attributes
(formerly, they were <var>FRV</var>, <var>KEY</var>, <var>CODED</var>, <var>UPDATE AT END</var>).
that are assigned to fields defined with NEW.
</p>
As of 4.3, the default attributes are NFRV, NKEY, NCOD, UPDATE IN PLACE
<p>
(formerly, they were FRV, KEY, CODED, UPDATE AT END).
See [[#crenew|Creating a NEW Lob field]] for an example that uses a Lob option. </p>
</blockquote>
<p></p>
See [[#crenew|Creating a NEW Lob field]] for an example that uses a Lob option.
   
   
<div id="concat"></div>
===<b id="concat"></b>#CONCAT supports long string arguments and result===
===#CONCAT supports long string arguments and result===
<p>
<!--Caution: <div> above-->
The arguments of <var>[[Fast/Unload standard functions#conc|#CONCAT]]</var> may be string values that exceed 255 bytes in length (as the contents of %variables or Lob fields). </p>
<p>
<p></p>
The result of <var>#CONCAT</var> may be a string longer than 255 bytes.
The arguments of #CONCAT ([[#conc|#CONCAT: Concatenate strings]]) may now be string values that
</p>
exceed 255 bytes in length (as the contents of %variables or Lob fields).
<p>
<p></p>
Prior to version 4.3 of <var class="product">Fast/Unload</var>, the maximum length of an argument was 255 bytes, and if the concatenation of the arguments exceeded 255 bytes, the
The result of #CONCAT may now be a string longer than 255 bytes.
FUEL program was terminated. </p>
<p></p>
<p>
There is no compatibility issue with previous use of the #CONCAT
function: the maximum length of an argument was 255 bytes,
and if the concatenation of the arguments exceeded 255 bytes, the
FUEL program was terminated.
<p></p>
See [[#crenew|Creating a NEW Lob field]] for an example that uses this #function with
See [[#crenew|Creating a NEW Lob field]] for an example that uses this #function with
a long string value.
a long string value. </p>
   
   
<div id="len"></div>
===<b id="len"></b>#LEN supports a long string argument===
===#LEN supports a long string argument===
<p>
<!--Caution: <div> above-->
The first argument of <var>[[Fast/Unload standard functions##len|#LEN]]</var> may be a string value
that exceeds 255 bytes in length (as the content of a %variable or Lob field). </p>
<p></p>
<p>
The first argument of #LEN ([[##len|#LEN: Length of string]]) may now be a string value
Prior to version 4.3 of <var class="product">Fast/Unload</var>, the maximum length of an argument was 255 bytes. </p>
that exceeds 255 bytes in length (as the content of a %variable or Lob field).
<p>
<p></p>
There is no compatibility issue with previous use of the #LEN
function, because the maximum length of an argument was 255 bytes.
<p></p>
See [[#unlexmp|Structured unload of Lob field]] for an example that uses this #function with
See [[#unlexmp|Structured unload of Lob field]] for an example that uses this #function with
a long string value.
a long string value. </p>
   
   
<div id="substr"></div>
===<b id="substr"></b>#SUBSTR supports a long string argument and result===
===#SUBSTR supports a long string argument and result===
<p>
<!--Caution: <div> above-->
The first argument of <var>[[Fast/Unload standard functions##substr|#SUBSTR]]</var> may be a string value
that exceeds 255 bytes in length (as the content of a %variable or Lob field). </p>
<p></p>
<p>
The first argument of #SUBSTR ([[##substr|#SUBSTR: Substring]]) may now be a string value
The result of <var>#SUBSTR</var> may be a string longer than 255 bytes. </p>
that exceeds 255 bytes in length (as the content of a %variable or Lob field).
<p>
<p></p>
Prior to to version 4.3 of <var class="product">Fast/Unload</var>, the maximum length of an argument was 255 bytes. </p>
The result of #SUBSTR may now be a string longer than 255 bytes.
<p>
<p></p>
There is no compatibility issue with previous use of the #SUBSTR
function, because the maximum length of an argument was 255 bytes.
<p></p>
See [[#unlexmp|Structured unload of Lob field]] for an example that uses this #function with
See [[#unlexmp|Structured unload of Lob field]] for an example that uses this #function with
a long string value.
a long string value. </p>
   
   
<div id="conlong"></div>
==<b id="conlong"></b>Contexts for long strings and Lobs==  
==Contexts for long strings and Lobs==
The version 4.3 <var class="product">Fast/Unload</var> accommodations for Lob fields included
<!--Caution: <div> above-->
The version 4.3 <var class="product">Fast/Unload</var> accommodations for Lob fields include
allowing %variables to contain strings longer than 255 bytes
allowing %variables to contain strings longer than 255 bytes
and specifying the contexts that allow such strings and Lob fields.
and specifying the contexts that allow such strings and Lob fields.
   
   
<div id="longstr"></div>
===<b id="longstr"></b>%Variables containing strings longer than 255===
===%Variables containing strings longer than 255===
<p>
<!--Caution: <div> above-->
<p></p>
The value of a %variable may be a string longer than 255 bytes.
The value of a %variable may be a string longer than 255 bytes.
This can arise as the result of:
This can arise as the result of: </p>
<table>
<table>
<tr><th>%v1 = %v2</th><td>assignment from another %variable which contains a string longer than 255 bytes</td></tr>
<tr><th>%v1 = %v2</th>
<tr><th>%v = fld</th><td>assignment from a Lob field</td></tr>
<td>Assignment from another %variable that contains a string longer than 255 bytes</td></tr>
<tr><th>%v = #SUBSTR(...)</th><td>assignment from a substring of a string value longer than 255 bytes</td></tr>
 
<tr><th>%v = #CONCAT(...)</th><td>assignment from the concatenation of strings, whose lengths total more than 255 bytes</td></tr>
<tr><th>%v = fld</th>
<td>Assignment from a Lob field</td></tr>
 
<tr><th>%v = <var>#SUBSTR(...)</var></th>
<td>Assignment from a substring of a string value longer than 255 bytes</td></tr>
 
<tr><th>%v = <var>#CONCAT(...)</var></th>
<td>Assignment from the concatenation of strings, whose lengths total more than 255 bytes</td></tr>
</table>
</table>
<p></p>
<p>
[[#longnot|Permitted use of long string values]] specifies the contexts in which a %variable
[[#longnot|Permitted use of long string values]] specifies the contexts in which a %variable
may be used if it contains a string longer than 255 bytes.
may be used if it contains a string longer than 255 bytes. </p>
<div id="longnot"></div>
===Permitted use of long string values===
<!--Caution: <div> above-->
   
   
<p></p>
===<b id="longnot"></b>Permitted use of long string values===
A long string value may be used in the following contexts:
<p>
A long string value may be used in the following contexts: </p>
<ul>
<ul>
<li>as an argument of #CONCAT
<li>As an argument of <var>#CONCAT</var> </li>
<li>as the argument of #LEN
<li>As the argument of <var>#LEN</var> </li>
<li>as the first argument of #SUBSTR
<li>As the first argument of <var>#SUBSTR</var> </li>
<li>as the right hand side of an assignment to a %variable
<li>As the right-hand side of an assignment to a %variable </li>
<li>as the right hand side of a CHANGE or ADD[C] statement,
<li>As the right-hand side of a <var>CHANGE</var> or <var>ADD[C]</var> statement,
when the field on the left hand side is a Lob
when the field on the left-hand side is a Lob </li>
</ul>
</ul>
<p></p>
<p>
If the <b>value</b> of a %variable is used in any other context,
If the <i>value</i> of a %variable is used in any other context,
and it is a string longer than 255 bytes, the FUEL program is terminated.
and it is a string longer than 255 bytes, the FUEL program is terminated.
For example, the following program creates one line of output, because
For example, the following program creates one line of output, because
the PUT statement does not allow a %variable containing a string longer
the <var>PUT</var> statement does not allow a %variable containing a string longer
than 255:
than 255: </p>
<p class="code"><nowiki>OPEN MYFILE
<p class="code"><nowiki>OPEN MYFILE
%X = #LEFT('ABC', 150, 'Z')
%X = #LEFT('ABC', 150, 'Z')
Line 169: Line 144:
END FOR
END FOR
</nowiki></p>
</nowiki></p>
Other examples of contexts prohibiting a %variable containing
Other examples of contexts prohibiting a %variable containing
a string longer than 255 bytes include arithmetic expressions,
a string longer than 255 bytes include arithmetic expressions,
comparisons in the IF statement, and more.
comparisons in the <var>IF</var> statement, and more.
<p></p>
<p>
Note that, since the EXISTS and MISSING clauses of the IF and
Note that, since the <var>EXISTS</var> and <var>MISSING</var> clauses of the <var>IF</var> and
ELSEIF statements do not reference the value of a %variable,
<var>ELSEIF</var> statements do not reference the value of a %variable,
you may use them to test a %variable even if it contains
you may use them to test a %variable even if it contains
a string longer than 255 bytes.
a string longer than 255 bytes.
That is, the following statement is acceptable in all cases:
That is, the following statement is acceptable in all cases: </p>
<p class="code"><nowiki>IF %S MISSING THEN  /* OK even if #LEN(%S) > 255
<p class="code">IF %S MISSING THEN  /* OK even if #LEN(%S) > 255
</nowiki></p>
</p>
   
   
<div id="lobnot"></div>
===<b id="lobnot"></b>Permitted use of Lobs===
===Permitted use of Lobs===
<p>
<!--Caution: <div> above-->
The value of a Lob field may only be used in the contexts discussed above that
<p></p>
The value of
a Lob field may only be used in the contexts discussed above that
allow a string longer than 255 bytes, even if the actual length of
allow a string longer than 255 bytes, even if the actual length of
the Lob field occurrence does not exceed 255.
the Lob field occurrence does not exceed 255.
Use of a Lob field in an invalid context causes the
Use of a Lob field in an invalid context causes the
compilation of the FUEL program to fail; it never begins execution.
compilation of the FUEL program to fail; it never begins execution. </p>
<p></p>
<p>
There are four contexts in which any field, Lob or not, may be referenced:
There are four contexts in which any field, Lob or not, may be referenced: </p>
<ul>
<ul>
<li>The UNLOAD(C) statement
<li>The <var>UNLOAD(C)</var> statement </li>
<li>The EXISTS and MISSING clauses of an IF/ELSEIF statement
 
<li>The #IF/#ELSEIF directives
<li>The <var>EXISTS</var> and <var>MISSING</var> clauses of an <var>IF/ELSEIF</var> statement </li>
<li>Preceding the number sign (<code>#</code>) "qualifier," which
 
specifies the number of occurrences of the field
<li>The <var>#IF/#ELSEIF</var> directives </li>
<p></p>
 
For example, the following statement is valid for any type of field:
<li>Preceding the number sign (<tt>#</tt>) "qualifier," which
<p class="code"><nowiki>FOR I FROM 1 TO BLOB(#)  /* OK for any field
specifies the number of occurrences of the field.
</nowiki></p>
<p>
For example, the following statement is valid for any type of field: </p>
<p class="code">FOR I FROM 1 TO BLOB(#)  /* OK for any field
</p> </li>
</ul>
</ul>
   
   
<div id="stat"></div>
==<b id="stat"></b>Lob statistics==
==Lob statistics==
<!--Caution: <div> above-->
<p></p>
If you display field statistics in the <var class="product">Fast/Unload</var> job statistics,
If you display field statistics in the <var class="product">Fast/Unload</var> job statistics,
the total number of pages used in Table E is shown for each Lob field
the total number of pages used in [[File architecture overview#Data tables|Table E]] is shown for each Lob field on the second line of the field's display.
on the second line of the field's display.
<p>
<p></p>
Note that the length statistics given for a Lob field, just like
Note that the length statistics given for a Lob field, just like
other fields, is based on the field occurrence values: in this case,
other fields, is based on the field occurrence values: in this case,
the number of bytes in Table E <b>used</b> by each field
the number of bytes in Table E <i>used</i> by each field
occurrence value (that is, unused bytes in Table E pages are not
occurrence value (that is, unused bytes in Table E pages are not
included in the length statistics).
included in the length statistics).</p>
<p></p>
<p>
The <b>Table B</b> usage for a Lob field is:
The Table B usage for a Lob field is: </p>
<ul>
<ul>
<li>27 bytes for a non-preallocated
<li>27 bytes for a non-preallocated Lob field occurrence (in addition to the
Lob field occurrence (in addition to the
overhead, as usual, for a count byte and field code) </li>
overhead, as usual, for a count byte and field code)
 
<li>28 bytes for a preallocated Lob field occurrence
<li>28 bytes for a preallocated Lob field occurrence </li>
</ul>
</ul>
<p></p>
<p>
For more information about the field statistics, see [[#fst|FSTATS [AVGTOT | MINMAX&#x5C;]].
For more information about the field statistics, see [[Fast/Unload Extraction Language (FUEL)#fst|FSTATS [AVGTOT | MINMAX&#x5C;]]. </p>
   
   
<div id="exlong"></div>
==<b id="exlong"></b>Lob field examples==
==Lob field examples==
 
<!--Caution: <div> above-->
===<b id="crenew"></b>Creating a NEW Lob field===
<p>
The following example unloads file <code>PRODFILE</code> such that, when it is
<div id="crenew"></div>
reloaded, all occurrences of field <code>COMMENT</code> are combined into a
===Creating a NEW Lob field===
single Lob field named <code>ALLCOMMENTS</code>: </p>
<!--Caution: <div> above-->
<p class="code">OPEN PRODFILE
<p></p>
The following example unloads file PRODFILE such that, when it is
reloaded, all occurrences of field COMMENT are combined into a
single Lob field named ALLCOMMENTS:
<p class="code"><nowiki>OPEN PRODFILE
UAI OINDEX
UAI OINDEX
NEW ALLCOMMENTS WITH BLOB
NEW ALLCOMMENTS WITH BLOB
Line 258: Line 222:
UNLOAD
UNLOAD
END FOR
END FOR
</nowiki></p>
</p>
Note that the first occurrence of COMMENT is used in each
 
iteration of the FOR I loop; when it is deleted at the tail
Note that the first occurrence of <code>COMMENT</code> is used in each
of the loop, the occurrence after it becomes the first occurrence
iteration of the <code>FOR I</code> loop. When this occurrence is deleted at the tail
on the next iteration.
of the loop, the occurrence after it becomes the first occurrence on the next iteration.
   
   
<div id="unlexmp"></div>
===<b id="unlexmp"></b>Structured unload of Lob field===
===Structured unload of Lob field===
<p>
<!--Caution: <div> above-->
The following example unloads file <code>PRODFILE</code>, creating one output
record for each 255 bytes (the maximum for a <var>PUT</var> statement) of
<p></p>
the Lob field named <code>ALLCOMMENTS</code>: </p>
The following example unloads file PRODFILE, creating one output
<p class="code">OPEN PRODFILE
record for each 255 bytes (the maximum for a PUT statement) of
the Lob field named ALLCOMMENTS:
<p class="code"><nowiki>OPEN PRODFILE
FOR EACH RECORD
FOR EACH RECORD
PUT '* '
PUT '* '
Line 296: Line 257:
END IF
END IF
END FOR
END FOR
</nowiki></p>
</p>
<b>Important notes:</b>
<blockquote class="note">
<p>
<b>Important notes:</b> </p>
<ul>
<ul>
<li>The <b>plus sign</b> (<code>+</code>) in <code>IF +%I >= %LIM</code>
<li>The <b>plus sign</b> (<tt>+</tt>) in <code>IF +%I >= %LIM</code>
is very important &mdash; otherwise a string comparison will be done, which is not
is very important &mdash; otherwise a string comparison is done, which is not
correct.
correct.
For example, if the length is 1,000,000, the first 255 bytes would be unloaded
For example, if the length is 1,000,000, the first 255 bytes would be unloaded
and the final PUT will fail, because then the length of <code>%X</code>
and the final <var>PUT</var> will fail, because then the length of <code>%X</code>
would be 1,000,000-254.
would be <code>1,000,000-254</code>. </li>
 
<li>The above approach is <i>vastly superior</i> to an approach that uses
<li>The above approach is <i>vastly superior</i> to an approach that uses
something like <code>%COM = $SUBSTR(#COM, 256)</code> to repeatedly
something like <code>%COM = $SUBSTR(#COM, 256)</code> to repeatedly
remove the first 255
remove the first 255 bytes, because that would involve unnecessary copying (approximately the square of the number of bytes in each field). </li>
bytes, because that would involve unnecessary copying on the order of the square
of the number of bytes in each field.
</ul>
</ul>
</blockquote>
   
   
<!-- .im comdate-->
<!-- .im comdate-->
==See also==
==See also==
[[Fast/Unload overview#WIKFUN$$topics|Fast/Unload topics]]
{{Template:Fast/Unload topic list}}

Latest revision as of 15:54, 14 March 2016

As of version 4.3, Fast/Unload included the ability to operate on BLOB and CLOB (collectively called "Lob") fields, which were introduced with V6R1 of Model 204.

Note: Processing BLOB or CLOB fields that have the DEFAULT-VALUE attribute requires Fast/Unload version 4.6 or higher.

The following Fast/Unload 4.3 features support these fields:

The above features are discussed in the rest of this wiki page, at the end of which are two examples that use these features (Lob field examples).

Statement and #function modifications

The NEW statement and three #functions let you define Lob fields and work with strings longer than 255 bytes.

NEW statement option for Lobs

As of version 4.3, the NEW statement (NEW fieldname [WITH BLOB | CLOB\) lets you specify that the new field you are defining is either a BLOB or CLOB field. This is primarily useful for a UAI-type unload, allowing you to create values in the new field that are loaded by LAI as Lob occurrences.

The syntax is:

NEW fieldname WITH BLOB | CLOB

Note: Version 4.3 also introduced a change to the default attributes that are assigned to fields defined with NEW. As of version 4.3, the default attributes are NFRV, NKEY, NCOD, UPDATE IN PLACE (formerly, they were FRV, KEY, CODED, UPDATE AT END).

See Creating a NEW Lob field for an example that uses a Lob option.

#CONCAT supports long string arguments and result

The arguments of #CONCAT may be string values that exceed 255 bytes in length (as the contents of %variables or Lob fields).

The result of #CONCAT may be a string longer than 255 bytes.

Prior to version 4.3 of Fast/Unload, the maximum length of an argument was 255 bytes, and if the concatenation of the arguments exceeded 255 bytes, the FUEL program was terminated.

See Creating a NEW Lob field for an example that uses this #function with a long string value.

#LEN supports a long string argument

The first argument of #LEN may be a string value that exceeds 255 bytes in length (as the content of a %variable or Lob field).

Prior to version 4.3 of Fast/Unload, the maximum length of an argument was 255 bytes.

See Structured unload of Lob field for an example that uses this #function with a long string value.

#SUBSTR supports a long string argument and result

The first argument of #SUBSTR may be a string value that exceeds 255 bytes in length (as the content of a %variable or Lob field).

The result of #SUBSTR may be a string longer than 255 bytes.

Prior to to version 4.3 of Fast/Unload, the maximum length of an argument was 255 bytes.

See Structured unload of Lob field for an example that uses this #function with a long string value.

Contexts for long strings and Lobs

The version 4.3 Fast/Unload accommodations for Lob fields included allowing %variables to contain strings longer than 255 bytes and specifying the contexts that allow such strings and Lob fields.

%Variables containing strings longer than 255

The value of a %variable may be a string longer than 255 bytes. This can arise as the result of:

%v1 = %v2 Assignment from another %variable that contains a string longer than 255 bytes
%v = fld Assignment from a Lob field
%v = #SUBSTR(...) Assignment from a substring of a string value longer than 255 bytes
%v = #CONCAT(...) Assignment from the concatenation of strings, whose lengths total more than 255 bytes

Permitted use of long string values specifies the contexts in which a %variable may be used if it contains a string longer than 255 bytes.

Permitted use of long string values

A long string value may be used in the following contexts:

  • As an argument of #CONCAT
  • As the argument of #LEN
  • As the first argument of #SUBSTR
  • As the right-hand side of an assignment to a %variable
  • As the right-hand side of a CHANGE or ADD[C] statement, when the field on the left-hand side is a Lob

If the value of a %variable is used in any other context, and it is a string longer than 255 bytes, the FUEL program is terminated. For example, the following program creates one line of output, because the PUT statement does not allow a %variable containing a string longer than 255:

OPEN MYFILE %X = #LEFT('ABC', 150, 'Z') PUT %X /* Length is 150 OUTPUT %X = #CONCAT(%X, %X) /* Length is 300 PUT %X /* FUEL program will be cancelled here OUTPUT FOR EACH RECORD /* Make it a legal FUEL program END FOR

Other examples of contexts prohibiting a %variable containing a string longer than 255 bytes include arithmetic expressions, comparisons in the IF statement, and more.

Note that, since the EXISTS and MISSING clauses of the IF and ELSEIF statements do not reference the value of a %variable, you may use them to test a %variable even if it contains a string longer than 255 bytes. That is, the following statement is acceptable in all cases:

IF %S MISSING THEN /* OK even if #LEN(%S) > 255

Permitted use of Lobs

The value of a Lob field may only be used in the contexts discussed above that allow a string longer than 255 bytes, even if the actual length of the Lob field occurrence does not exceed 255. Use of a Lob field in an invalid context causes the compilation of the FUEL program to fail; it never begins execution.

There are four contexts in which any field, Lob or not, may be referenced:

  • The UNLOAD(C) statement
  • The EXISTS and MISSING clauses of an IF/ELSEIF statement
  • The #IF/#ELSEIF directives
  • Preceding the number sign (#) "qualifier," which specifies the number of occurrences of the field.

    For example, the following statement is valid for any type of field:

    FOR I FROM 1 TO BLOB(#) /* OK for any field

Lob statistics

If you display field statistics in the Fast/Unload job statistics, the total number of pages used in Table E is shown for each Lob field on the second line of the field's display.

Note that the length statistics given for a Lob field, just like other fields, is based on the field occurrence values: in this case, the number of bytes in Table E used by each field occurrence value (that is, unused bytes in Table E pages are not included in the length statistics).

The Table B usage for a Lob field is:

  • 27 bytes for a non-preallocated Lob field occurrence (in addition to the overhead, as usual, for a count byte and field code)
  • 28 bytes for a preallocated Lob field occurrence

For more information about the field statistics, see FSTATS [AVGTOT | MINMAX\.

Lob field examples

Creating a NEW Lob field

The following example unloads file PRODFILE such that, when it is reloaded, all occurrences of field COMMENT are combined into a single Lob field named ALLCOMMENTS:

OPEN PRODFILE UAI OINDEX NEW ALLCOMMENTS WITH BLOB FOR EACH RECORD IF COMMENT EXISTS THEN %X = /* Initialize BLOB value FOR I FROM 1 TO COMMENT(#) %X = #CONCAT(%X, COMMENT) DELETE COMMENT END FOR ADD ALLCOMMENTS = %X END IF UNLOAD END FOR

Note that the first occurrence of COMMENT is used in each iteration of the FOR I loop. When this occurrence is deleted at the tail of the loop, the occurrence after it becomes the first occurrence on the next iteration.

Structured unload of Lob field

The following example unloads file PRODFILE, creating one output record for each 255 bytes (the maximum for a PUT statement) of the Lob field named ALLCOMMENTS:

OPEN PRODFILE FOR EACH RECORD PUT '* ' PUT CUSTOMER_ID OUTPUT IF ALLCOMMENTS EXISTS THEN %COM = ALLCOMMENTS %LENGTH = #LEN(ALLCOMMENTS) %I = 1 %LIM = %LENGTH - 254 REPEAT IF +%I >= %LIM THEN LEAVE REPEAT END IF %X = #SUBSTR(%COM, %I, 255) PUT %X OUTPUT %I = %I + 255 END REPEAT %X = #SUBSTR(%COM, %I) PUT %X OUTPUT END IF END FOR

Important notes:

  • The plus sign (+) in IF +%I >= %LIM is very important — otherwise a string comparison is done, which is not correct. For example, if the length is 1,000,000, the first 255 bytes would be unloaded and the final PUT will fail, because then the length of %X would be 1,000,000-254.
  • The above approach is vastly superior to an approach that uses something like %COM = $SUBSTR(#COM, 256) to repeatedly remove the first 255 bytes, because that would involve unnecessary copying (approximately the square of the number of bytes in each field).

See also