get considerations for DL/I

In the context of DL/I, the EGL get statement retrieves a single segment in a DL/I database.

The statement includes the forUpdate option that you can use to replace or delete the stored data later in your code. You can also use this statement to retrieve a set of DL/I segments and place the contents of each succeeding segment into the next DLISegment record of a dynamic array.

The get statement generates a DL/I GU (get unique) statement. The get...forUpdate statement generates a DL/I GHU statement.

The get statement has the following principal uses:

For an example of using the get...forUpdate statement with DL/I, see delete considerations for DL/I.

DL/I also supports the use of path calls on get statements. When you use path calls, you can read parent segments for all segment levels between the lowest level segment you are reading and the root. In the following example, EGL reads all three DL/I segments (customer, location, and order) into their respective DLISegment records with a single call:
get myCustomer, myLocation, myOrder;
EGL generates the following pseudo-DL/I code from this statement:
GU STSCCST*D (STQCCNO = :myCustomer.customerNo) 
   STSCLOC*D (STQCLNO = :myLocation.locationNo) 
   STPCORD

When you specify a dynamic array of DLISegment records as the object of the get statement, you generate a DL/I GU call for the first record in the array and a GN call for each subsequent record in the array. If the array does not specify a number of elements, the statement generates GN calls until the end of the DL/I file or an error code occurs.

Syntax

Syntax diagram for DL/I get considerations
positionOption
The next and next inParent position options are valid with the get statement in DL/I. For more information, see "Position options" in this topic.
DLISegmentVariable
Name of the DLISegment variable that corresponds to the segment you want to read from the database.
forUpdate
Option to use a later EGL replace or delete statement with the data that was retrieved from the file or database.
The forUpdate option locks the record so that it cannot be changed by other programs until a commit occurs. For more information about commit processing, see Logical unit of work.
usingPCB pcbName
Option to specify the name of a PCB, as defined in your PSB record, to use instead of the default PCB.
with #dli{ dliStatement }
Option to use an explicit DL/I GU or GHU statement. For more information, see #dli directive. Leave no space between #dli and the left brace.
DLIDynamicArray
Name of a dynamic array that is composed of DLISegment records.

Position options

The get next statement generates a DL/I GN statement. The get next...forUpdate statement generates a DL/I GHN statement. The statement reads the segment that immediately follows the current segment in hierarchical order. Hierarchical order means the database manager begins at the root segment and reads as far down the hierarchy as it can, reading the first child of the first child and so on, until it reaches the bottom. It then moves up until it finds a parallel child that it has not read and reads that segment and all child segments.

For example, the customer database in Example DL/I database has the following hierarchical order:
  1. The database manager first reads the root segment (Customer Name and Address).
  2. The database manager reads the first Location segment for this customer, the first Order segment, and all Item segments for that order.
  3. If there are more Order segments, the database manager reads the next Order segment and all Item segments for that order. If there are no more Order segments for this Location, go to step 4.
  4. If there are more Location segments, the database manager reads the next Location segment, the first Order segment for that Location, and all Item segments for that order. Go back to step 3. If there are no more Location segments, go to step 5.
  5. If there are more Customer segments, the database manager reads the next Customer segment. Go back to step 2. If there are no more Customer segments, the manager has read the entire file.

DL/I also supports the use of path calls on get next statements. This means that you can read parent segments for all segment levels between the lowest level segment you are reading and the root.

The current database position is affected by I/O operations just as it is when you write a local COBOL or PL/I program. In addition, you can use an EGL set record position statement to cause EGL to change a subsequent get next statement (GN call) into a get statement (GU call). Consider the following example:
// define DLI Segment records using the hostVarQualifier property
Record CustomerRecordPart type DLISegment
  { segmentName="STSCCST", keyItem="customerNo", hostVarQualifier="myCustomer" }
  ...
end
Record LocationRecordPart type DLISegment
  { segmentName="STSCLOC", keyItem="locationNo", hostVarQualifier="myLocation" }
  ...
end
Record OrderRecordPart type DLISegment
  { segmentName="STPCORD", keyItem="orderDateNo", hostVarQualifier="myOrder" }
  ...
end

  //create variables for the records 
  myCustomer CustomerRecord; 
  myLocation LocationRecord; 
  myOrder OrderRecord; 

  //build a segment search argument 
  myCustomer.customerNo = "005001"; 
  myLocation.locationNo = "000022"; 
  myOrder.orderDateNo = "20050730A003"; 
  set myOrder position;

  //loop through the orders
  while (myOrder not noRecordFound)
    try 
      get next myOrder; 
      onException 
        myErrorHandler(2); 
    end // end try
  end // end while
The first time the get next statement runs, EGL uses a GU call with qualified SSAs for customer, location, and order as follows:
GU STSCCST (STQCCNO = :myCustomer.customerNo) 
   STSCLOC (STQCLNO = :myLocation.locationNo) 
   STPCORD (STQCODN = :myOrder.orderDateNo)

After the first time through the loop, EGL uses a GN call.

The following considerations apply when you use a set record position statement:
  • set record position sets a flag that indicates that EGL should convert the first get next statement for the DLISegment record to a get (GU call).
  • If the next I/O statement for the DLISegment record is not a get next statement, the set record position statement is ignored and the flag is reset.
  • If the get next statement specifies the #dli directive, the set record position statement is ignored and the flag is reset.

When you specify a dynamic array of DLISegment records as the object of the get next statement, you generate a DL/I GN call for each record in the array. If the array does not specify a number of elements, the statement generates GN calls until the end of the DL/I database or an error code occurs. For more predictable behavior, use the get next inParent statement in this situation.

The get next inParent statement generates a DL/I GNP statement (if there is no forUpdate modifier) or a GHNP (if there is a forUpdate modifier). The statement reads the next child segment that has the same parent as the segment at the current database position. You can also use the next inParent modifier to retrieve a set of DL/I segments into a dynamic array.

Example

The following example shows how to read and replace a file record:
  emp.empnum = 1;         // sets the key in record emp

  try
    get emp forUpdate;
  onException(dex DLIException)
    myErrorHandler(dex);  // exits the program
  end

  emp.empname = emp.empname + " Smith";

  try
    replace emp;
  onException(dex DLIException)
    myErrorHandler(dex);
  end

Compatibility

Table 1. Compatibility considerations for get and DL/I
Platform Issue
CICS® for z/OS® The get position is lost in the following situations:
  • When a commit or rollback is issued
  • After a converse statement, if it is running in segmented mode

Feedback