Large Object field processing for non-FILEORG X'100' files: Difference between revisions

From m204wiki
Jump to navigation Jump to search
m (→‎Overview: add sentence re Universal Buffer)
m (link repair)
Line 223: Line 223:
<li><var class="term">length</var> is a positive number specifying the length to move. The length can be a %variable or a constant.</li>
<li><var class="term">length</var> is a positive number specifying the length to move. The length can be a %variable or a constant.</li>
   
   
<li><var>RESERVE</var> <var class="term">n</var> specifies a positive number of bytes to reserve for the Large Object field value. The number of bytes is always greater than or equal to <var>[[$LOBLEN]]</var>. </li>
<li><var>RESERVE</var> <var class="term">n</var> specifies a positive number of bytes to reserve for the Large Object field value. The number of bytes is always greater than or equal to <var>[[$LobLen]]</var>. </li>
   
   
<li><var>BYTES</var>, optional, specifies that <var class="term">n</var> applies to bytes. </li>
<li><var>BYTES</var>, optional, specifies that <var class="term">n</var> applies to bytes. </li>

Revision as of 18:04, 12 July 2017

Overview

Model 204 Version 7.5 introduced the X'100' bit on the FILEORG parameter which provides for a variety of extended features, including a simpler syntax for adding, changing and deleting Large Object fields (fields with a BLOB or CLOB attribute). Without FILEORG X'100', working with Large Objects requires the use of a Universal Buffer. The Universal Buffer is a one-per-user, temporary storage area that automatically expands to accommodate its data contents.

This page describes the Universal Buffer syntax, which is deprecated for X'100' files but required for earlier-version files that use BLOB or CLOB fields. For LOB syntax used in X'100' files, see Data maintenance.

Data maintenance statements

Special processing necessary for non-FILEORG X'100' files with LOB fields is needed for:

Statement Action
ADD Place a new field-value pair on a record.
CHANGE Alter the value of fields in a record.
STORE RECORD Add a new record to a Model 204 file.

Using FOR EACH RECORD loops

Since the SOUL data maintenance statements handle one record at a time, the data maintenance statements are always part of a FOR EACH RECORD loop. The data maintenance may involve a field-value pair for the field.

Data used in examples in this topic

Each statement is discussed separately on the pages that follow. To illustrate their usage, assume that the following two records have been stored:

VIN = A99999998E VIN = X99999999Z MAKE = FORD MAKE = FORD COLOR = GREEN COLOR = RED YEAR = 88 YEAR = 04 MODEL = FOCUS MODEL = MUSTANG

Adding Large Object fields

Use the following special syntax of the ADD statement to add a Large Object field to a record:

ADD lob-name=BUFFER,position,length [RESERVE n [BYTES]]

Where:

  • lob-name specifies the field name of the Large Object data.

    Note: You cannot use subscripts on ADD statements.

  • BUFFER specifies the Universal Buffer
  • position is a positive number specifying the offset of the first character in the buffer or Large Object data. If the position is set to a negative value, an error occurs. The position can be a %variable or a constant.
  • length is a positive number specifying the length to move. The length can be a %variable or a constant.
  • RESERVE n specifies a positive number of bytes to reserve for the Large Object field value. The number of RESERVE bytes is always greater than or equal to maximum length of Large Object.
  • BYTES, optional, specifies that n applies to bytes.

Example

BEGIN IMAGE XYZ BUFF_DATA IS STRING LEN 200 END IMAGE IDENTIFY IMAGE XYZ * add LOB field with "CURRECn" to the records: FOR EACH RECORD * enter data into image item: %XYZ:BUFF_DATA = 'CURREC' WITH $CURREC * write image on the buffer: WRITE IMAGE XYZ ON BUFFER POSITION=1 MAXLEN=200 * add LOB field from buffer contents: ADD MY.LOB.FIELD=BUFFER,1,10 RESERVE 200 BYTES END FOR * print LOB data: FOR EACH RECORD * place LOB data into the buffer: BUFFER,1,200=MY.LOB.FIELD,1,200 * place contents of the buffer into image: READ IMAGE XYZ FROM BUFFER * print LOB data that has been placed into the buffer: PRINT VIN AND %XYZ:BUFF_DATA END

This request adds a Large Object field to each record containing the text CURREC followed by the internal record number and this output:

A99999998E CURREC0 X99999999Z CURREC1

Usage

For Large Object data, a compiler error is issued for ADD (and STORE) statements if the context to the right of the equal sign (=) is not a BUFFER reference:

M204.0037: INVALID SYNTAX

Changing Large Object fields

To change large object fields, use the CHANGE statement with the following syntax:

CHANGE lob-fieldname,position1,length TO BUFFER position2,length

  • lob-fieldname specifies the name of the field
  • position, position1 and position2 are positive numbers specifying the offset of the first character in the buffer or Large Object data. If position, position1, or position2 is set to a negative value, an error occurs. Any positions can be a %variable or a constant.
  • length is a positive number specifying the length to move. The length can be a %variable or a constant. The source and target lengths must be equal.

    If position plus length minus one exceeds the current length of the LOB field, the intervening bytes are filled with binary 0. If the file has the FILEORG X'100' bit set, then any final length of the LOB field is allowed. Otherwise extending a LOB field requires that the final length must fit within the RESERVE clause length specified when the LOB field was added.

    For example, if the buffer contains ABCDEFGHIJKL and the field is initially stored with:

    ADD LOB.FLD=BUFFER,1,3 RESERVE 500 BYTES

    The field would contain ABC. If it was subsequently changed as follows:

    CHANGE LOB.FLD,5,10 TO BUFFER,1,10

    The field would then contain ABC ABCDEFGHIJ with position 4 being a binary zero.

  • TO BUFFER specifies the Universal Buffer. You can use BUFFER only in conjunction with a Large Object field.

Example

BEGIN IMAGE XYZ BUFF_DATA IS STRING LEN 200 END IMAGE IDENTIFY IMAGE XYZ IN JUNK FOR EACH RECORD * place LOB data into the buffer: %XYZ:BUFF_DATA = 'This is the data for VIN ' WITH VIN * write image on the buffer: WRITE IMAGE XYZ ON BUFFER POSITION=1 MAXLEN=200 * change the LOB field to the contents of the buffer: CHANGE MY.LOB.FIELD,1,50 TO BUFFER,1,50 END FOR * print LOB data: FOR EACH RECORD * place LOB data into the buffer: BUFFER,1,200=MY.LOB.FIELD,1,200 * place contents of the buffer into image: READ IMAGE XYZ FROM BUFFER * print LOB data that has been placed into the buffer: PRINT VIN AND %XYZ:BUFF_DATA END

This code results in changing the large object field in each record to the text This is the data for VIN followed by the VIN field and this output:

A99999998E This is the data for VIN A99999998E X99999999Z This is the data for VIN X99999999Z

Usage

  • If you issue a CHANGE statement on a Large Object field to a record that does not contain the field, nothing happens. Unlike a non-Large Object field, a new occurrence of the field is not added to the record.
  • Extending a LOB field requires that the final length must fit within the RESERVE clause length specified when the LOB field was added.

    Note: You cannot change the number of RESERVE bytes. Furthermore, facilities are not available to delete a portion of data or to insert data: for example, to replace 10 bytes with 25 bytes within Large Object data. When an attempt to insert or delete data is made the following error message is issued:

    M204.2693: SOURCE AND TARGET LENGTH MUST BE EQUAL

  • All Large Object data implicitly has the contiguous characteristic. A SOUL procedure can store some amount of initial data and then extend the data up to the RESERVE number of bytes with subsequent CHANGE statements. For example:

    FR * add initial 10 bytes: ADD LOB.FLD=BUFFER,1,10 RESERVE 200 BYTES * add increments of 10 bytes at * positions 11, 21, 31, 41 * moving data from the buffer to the field FOR %X FROM 1 TO 4 %Y = %X WITH '1' CHANGE LOB.FLD,%Y,10 TO BUFFER,%Y,10 END FOR PAI PRINT 'LOBLEN' AND $LOBLEN(LOB.FLD) END

Storing Large Object fields

To store a Large Object (prior to Model 204 V7.5 or absent the X'100' FILEORG bit), LOB fields require the Universal Buffer and this STORE RECORD syntax to access the buffer:

STORE RECORD lob-name=BUFFER,position,length [RESERVE n [BYTES]] . . . END_STORE [label]

Where:

  • lob-name specifies the field name of the Large Object field.

    Note: you cannot use subscripts on statements for any field type.

  • BUFFER specifies the Universal Buffer
  • position is a positive number specifying the offset of the first character in the buffer. If the position is less than one, an error occurs. The position can be a %variable or a constant.
  • length is a positive number specifying the length to move. The length can be a %variable or a constant.
  • RESERVE n specifies a positive number of bytes to reserve for the Large Object field value. The number of bytes is always greater than or equal to $LobLen.
  • BYTES, optional, specifies that n applies to bytes.

Example

STORE RECORD NOVEL=BUFFER,%POSITION,%LENGTH [RESERVE n [BYTES]] AUTHOR_PIC=BUFFER,%POSITION2,%LENGTH2 END STORE

Usage

When you store an instance of a Large Object field, the value of the data is stored in the file's Table E. Additionally, a LOB descriptor containing a pointer to the value in Table E, as well as other items, are stored in the record data in a Table B entry. The LOB descriptor is 27 bytes in length, plus the 1-byte length and 2-byte field code that apply to all fields — unless the field is preallocated. See Building a Large Object descriptor for a description of how to build a Large Object data descriptor.

The following compiler error is issued when the right side of the equal sign is expected to contain a BUFFER expression and it does not:

M204.0037: INVALID SYNTAX