Subset pointer options

To take advantage of subsets, application programs use five different options.

The options are:
GETFIRST
Allows you to retrieve the first segment in a subset.
SETZERO
Sets a subset pointer to zero.
MOVENEXT
Sets a subset pointer to the segment following the current segment. Current position is at the current segment.
SET
Unconditionally sets a subset pointer to the current segment. Current position is at the current segment.
SETCOND
Conditionally sets a subset pointer to the current segment. Current position is at the current segment.

Banking transaction application example

The examples in these topics are based on a sample application, the recording of banking transactions for a passbook account. The transactions are written to a database as either posted or unposted, depending on whether they were posted to the customer's passbook. For example, when Bob Emery does business with the bank, but forgets to bring in his passbook, an application program writes the transactions to the database as unposted. The application program sets a subset pointer to the first unposted transaction, so it can be easily accessed later. The next time Bob remembers to bring in his passbook, a program posts the transactions. The program can directly retrieve the first unposted transaction using the subset pointer that was previously set. After the program has posted the transactions, it sets the subset pointer to zero; an application program that subsequently updates the database can determine that no unposted transactions exist. The following figure summarizes the processing performed when the passbook is unavailable.

Figure 1. Processing performed for the sample passbook example when the passbook is unavailable
Begin figure description. Seven consecutive boxes represent a chain of segment occurrences labelled B1 through B7. An arrow representing subset pointer 1 (P1) points to the first unposted transaction represented by segment occurrence B5. End figure description.

When the passbook is available, an application program adds the unposted transactions to the database, setting subset pointer 1 to the first unposted transaction. The following figure summarizes the processing performed when the passbook is available.

Figure 2. Processing performed for the sample passbook example when the passbook is available
Begin figure description. Seven consecutive boxes represent a chain of segment occurrences labelled B1 through B7. An arrow representing subset pointer 1 (P1) points to none of the segment occurrences and P1 is set to zero. End figure description.

When the passbook is available, an application program retrieves the first unposted transaction using the program, then posts all unposted transactions, setting subset pointer 1 to zero.

GETFIRST option: retrieving the first segment of a subset

To retrieve the first segment occurrence in the subset, your program issues a Get command with the GETFIRST option. The GETFIRST option does not set or move the pointer, but indicates to IMS that you want to establish position on the first segment occurrence in the subset. The GETFIRST option is like the FIRST option, except that the GETFIRST option applies to the subset instead of to the entire segment chain.

Using the previous example, imagine that Bob Emery visits the bank with his passbook and you want to post all of the unposted transactions. Because subset pointer 1 was previously set to the first unposted transaction, your program can use the following command to retrieve that transaction:
EXEC DLI GU SEGMENT(A) WHERE(AKEY = 'A1')
     SEGMENT(B) INTO(BAREA) GETFIRST('1');
As shown in following figure, this command retrieves segment B5. To continue processing segments in the chain, you can issue Get Next commands, as you would if you were not using subset pointers.
Figure 3. Retrieving the first segment in a chain of segments
Begin figure description. Seven consecutive boxes represent a chain of segment occurrences labeled B1 through B7. An arrow labelled P1, points to B5 (the fifth box) to retrieve segment B5. The arrow, P1 represents a subset pointer. End figure description.

If the subset does not exist (subset pointer 1 has been set to zero), IMS returns a GE status code, and your position in the database immediately follows the last segment in the chain. Using the passbook example, the GE status code indicates that no unposted transactions exist.

You can specify only one GETFIRST option per qualification statement; if you use more than one GETFIRST in a qualification statement, IMS returns an AJ status code to your program. The rules for using the GETFIRST option are:

  1. You can use GETFIRST with all options except:
    • FIRST
    • LOCKCLASS
    • LOCKED
  2. Other options take effect after the GETFIRST option has, and position has been established on the first segment in the subset.
  3. If you use GETFIRST with LAST, the last segment in the segment chain is retrieved.
  4. If the subset pointer specified with GETFIRST is not set, IMS returns a GE status code, not the last segment in the segment chain.
  5. Do not use GETFIRST with FIRST. This causes you to receive an AJ status code.
  6. GETFIRST overrides all insert rules, including LAST.

SETZERO, MOVENEXT, SET, and SETCOND options: setting the subset pointers

The SETZERO, MOVENEXT, SET, and SETCOND options allow you to redefine subsets by modifying the subset pointers. Before your program can set a subset pointer, it must establish a position in the database. A command must be fully satisfied before a subset pointer is set. The segment a pointer is set to depends on your current position at the completion of the command. If a command to retrieve a segment is not completely satisfied, and a position is not established, the subset pointers remain as they were before the command was issued.

  • Setting the subset pointer to zero: SETZERO

    The SETZERO option sets the value of the subset pointer to zero. After your program issues a command with the SETZERO option, the pointer is no longer set to a segment; the subset defined by that pointer no longer exists. (IMS returns a status code of GE to your program if you try to use a subset pointer having a value of zero.)

    Using the previous example, say that you used the GETFIRST option to retrieve the first unposted transaction. You would then process the chain of segments, posting the transactions. After posting the transactions and inserting any new ones into the chain, you would use the SETZERO option to set the subset pointer to zero as shown in the following command:
    EXEC DLI ISRT SEGMENT(A) WHERE(AKEY = 'A1')
         SEGMENT(B) FROM(BAREA) SETZERO('1');

    After this command, subset pointer 1 would be set to zero, indicating to a program updating the database later on that no unposted transactions exist.

  • Moving the subset pointer forward to the next segment after your current position: MOVENEXT
    To move the subset pointer forward to the next segment after your current position, your program issues a command with the MOVENEXT option. Using the previous example, say that you wanted to post some of the transactions, but not all, and that you wanted the subset pointer to be set to the first unposted transaction. The following command sets subset pointer 1 to segment B6.
    EXEC DLI GU SEGMENT(A) WHERE(AKEY = 'A1')
         SEGMENT(B) INTO(BAREA) GETFIRST('1') MOVENEXT('1');

    The process of moving the subset pointer with this command is shown in the following figure. If the current segment is the last in the chain, and you use a MOVENEXT option, IMS sets the pointer to zero.

    Figure 4. Moving the subset pointer to the next segment after your current position
    Begin figure description. Seven consecutive boxes represent a chain of segment occurrences labelled B1 through B7. Before the command, an arrow representing subset pointer P1 points to the fifth box representing segment B5. After the command, the arrow representing subset pointer P1 points to the sixth box representing segment B6. End figure description.
  • Setting the subset pointer unconditionally: SET

    You use the SET option to set a subset pointer. The SET option sets a subset pointer unconditionally, regardless of whether or not it is already set. When your program issues a command that includes the SET option, IMS sets the pointer to your current position.

    For example, to retrieve the first B segment occurrence in the subset defined by subset pointer 1, and to reset pointer 1 at the next B segment occurrence, you would issue the following commands:
    EXEC DLI GU SEGMENT(A) WHERE(AKEY = 'A1')
         SEGMENT(B) INTO(BAREA) GETFIRST('1');
    EXEC DLI GN SEGMENT(B) INTO(BAREA) SET('1');

    After you have issued these commands, instead of pointing to segment B5, subset pointer 1 points to segment B6, as shown in the following figure.

    Figure 5. Unconditionally setting the subset pointer to your current position
    Begin figure description. Seven consecutive boxes represent a chain of segment occurrences labelled B1 through B7. Before the command, an arrow representing subset pointer P1 points to the 5th box, segment B5. After the command, the arrow representing subset pointer P1 points to the 6th box, segment B6. End figure description.
  • Setting the subset pointer conditionally: SETCOND

    Your program uses the SETCOND option to conditionally set the subset pointer. The SETCOND option is similar to the SET option; the only difference is that, with the SETCOND option, IMS updates the subset pointer only if the subset pointer is not already set to a segment.

    Using the passbook example, say that Bob Emery visits the bank and forgets to bring his passbook; you add the unposted transactions to the database. You want to set the pointer to the first unposted transaction so that when you post the transactions later, you can immediately access the first one. The following command sets the subset pointer to the transaction you are inserting, if it is the first unposted one:
    EXEC DLI ISRT SEGMENT(A) WHERE(AKEY = 'A1')
         SEGMENT(B) FROM(BAREA) SETCOND('1');

    As shown by the following figure, this command sets subset pointer 1 to segment B5. If unposted transactions already existed, the subset pointer is not changed.

    Figure 6. Conditionally setting the subset pointer to your current position
    Begin figure description. Before the command, a series of four boxes labelled B1 through B4 that represent segments are shown. After the command a series of five boxes labelled B1 through B5 that represent segments appear. An arrow that represents the subset pointer points to the fifth box that represents inserted segment B5. End figure description.

Inserting segments in a subset

When you use the GETFIRST option to insert an unkeyed segment in a subset, the new segment is inserted before the first segment occurrence in the subset. However, the subset pointer is not automatically set to the new segment occurrence. For example, the following command inserts a new B segment occurrence in front of segment B5, but does not set subset pointer 1 to point to the new B segment occurrence:
EXEC DLI ISRT SEGMENT(A) WHERE(AKEY = 'A1')
     SEGMENT(B) FROM(BAREA) GETFIRST('1');
To set subset pointer 1 to the new segment, you use the SET option along with the GETFIRST option, as shown in the following example:
EXEC DLI ISRT SEGMENT(A) WHERE(AKEY = 'A1')
     SEGMENT(B) FROM(BAREA) GETFIRST('1') SET ('1');

If the subset does not exist (subset pointer 1 has been set to zero), the segment is added to the end of the segment chain.

Deleting the segment pointed to by a subset pointer

If you delete the segment pointed to by a subset pointer, the subset pointer points to the next segment occurrence in the chain. If the segment you delete is the last in the chain, the subset pointer is set to zero.

Combining options

You can use the SET, MOVENEXT, and SETCOND options with other options, and you can combine subset pointer options with each other, provided they do not conflict. For example, you can use GETFIRST and SET together, but you cannot use SET and SETZERO together because their functions conflict. If you combine options that conflict, IMS returns an AJ status code to your program.

You can use one GETFIRST option per qualification statement, and one update option (SETZERO, MOVENEXT, SET, or SETCOND) for each subset pointer.