Chapter Contents |
Previous |
Next |
SAS/ACCESS Interface to IMS-DL/I Software |
Most non-database calls can be used only in particular DL/I region types. An exception is the basic CHKP call, which is supported in all DL/I region types that can be accessed through OS/390. The basic CHKP call is described in the next section.
Most of the other DL/I calls in this section require an I/O PCB or TP PCBs, so descriptions of the I/O and TP PCBs follow the section on the basic CHKP call. Following that section is a section on calls that can be issued by all OS/390 DL/I region types. Finally, calls that can be executed only from an IMS/ESA BMP region are described.
Basic CHKP Call |
The basic CHKP call can be issued in batch DL/I regions as well as in online DL/I regions. This call establishes a program synchronization point.(footnote 1) (Synchronization points are described in General Considerations for Sharing Resources.)
The following example shows SAS programming statements that issue a CHKP call. The example is run using the SAS system option IMSREGTP=DLI:
data _null_; retain chkpnum 0; infile acctsam dli call=func pcb=pcbindex status=st; file acctsam dli; func = 'CHKP'; pcbindex = 1; chkpnum = chkpnum +1; put @1 'SAS' @4 chkpnum z5.; if st = ' ' then return; file log; put _all_; abort; run;
The PCB= variable, PCBINDEX, has a value of 1. This indicates that the first eligible PCB is used for the CHKP call. A CHKP call requires the I/O PCB that is the first PCB in the PSB (see I/O PCBs).
Note: An I/O PCB is always generated for PSBs in a BMP
region. If you are going to issue a CHKP call under DL/I, you must use the CMPAT=YES option in the PSBGEN statement
for batch regions DLI and DBB. If an I/O PCB is not present, you get the message that the call is invalid for a DB PCB.
The CHKP call is successful if
_ERROR_=0 and the STATUS= variable (ST) is blank. Otherwise, the STATUS= variable contains a status code that indicates the cause of the failure. In particular, an
XD
status code in an IMS/ESA BMP region indicates that the IMS/ESA control region is being shut down.
You cannot read from the output buffer in a DATA step, but you can access the message segments that are placed in the output buffer. You format a GU call that uses the I/O PCB. When the DL/I INPUT statement executes, the SAS/ACCESS interface remembers that the output buffer contains data from a previous CHKP call. Instead of issuing the GU call, the SAS/ACCESS interface moves the segment from the output buffer to the input buffer, where it can be read. Therefore, in a BMP transaction-processing program, the first call issued after a CHKP call must be a GU that references the I/O PCB.(footnote 2)
Consider the previous example in Basic CHKP Call, which shows SAS statements that issue a CHKP call. If you issue the CHKP call in a BMP transaction-processing program, additional statements are needed. This example issues one CHKP call and optionally moves a message segment to the input buffer.
In this example, change trancode in the OPTIONS statement to a valid transaction code at your site. This example is run using the SAS system options IMSREGTP=BMP and IMSBPIN=trancode:
options imsbpin=trancode; data _null_; retain chkpnum 0; infile acctsam dli call=func pcb=pcbindex status=st; file acctsam dli; func = 'CHKP'; pcbindex = 1; chkpnum = chkpnum +1; put @1 'SAS' @4 chkpnum z5.; if st = ' ' then do; func = 'GU '; input @; if st ¬= ' ' then if st= 'QC' then do; _error_ = 0; stop; end; else link abendit; end; else if st = 'QC' then do; _error_ = 0; stop; end; else link abendit; stop; abendit: file log; put _all_; abort; run; options imsbpin=*;
If DL/I did not return the first segment of the next message automatically after a CHKP call, the GU call would be necessary to retrieve the next message.
I/O PCBs |
If an I/O PCB is present, it is always the first PCB in the PSB. Therefore, be careful in how you specify the DL/I INFILE statement options PCBNO=, PCB=, and DBNAME= when you need the I/O PCB. The value of PCBNO= must be 1. If the DBNAME= option is specified, that variable's value must be set to blanks. Finally, if a PCB= variable is specified, it must have a value of 1.
In all OS/390 DL/I regions, the I/O PCB is used to issue the CHKP and LOG calls. In an IMS/ESA BMP region, the I/O PCB is also used to read transaction messages from the IMS/ESA message queues, to insert response messages to the terminal that originated the transaction, and to communicate certain system calls that are unique to the IMS/ESA DB/DC system.
TP PCBs |
When TP PCBs are present, they follow the I/O PCB (if any) and precede the
DB PCBs. Unless the TP PCB is the first PCB in the PSB, you must use the PCB= option in the DL/I INFILE statement to select the appropriate TP PCB. You cannot use the DBNAME= option because no DBD
name is associated with a TP PCB.
Just as information from DB PCBs is available to the SAS program through the STATUS= and PCBF= variables after a DL/I call, so is information from the I/O and TP PCBs.(footnote 3) The format of the data in the PCBF= variable differs, however, according to the PCB type.
If a DL/I call uses the I/O PCB, the PCBF= variable data are formatted as shown in Format of I/O PCB Feedback Data.
If a DL/I call uses a TP PCB, the data in the PCBF= variable are formatted as shown in Format of TP PCB Feedback Data.
Bytes | Description |
1-8 | These bytes of the PCBF= variable contain the name of the logical terminal (LTERM) that issued the message. |
9-10 | These bytes are reserved for IMS/ESA usage. |
11-12 | These bytes contain the DL/I status code. The status code may also be obtained by specifying the STATUS= option in the DL/I INFILE statement. |
13-16 | These bytes contain the date that the message was queued. The date is in packed decimal, right aligned, Julian date format (YYDDD). |
17-20 | The time that the message was queued is contained in these bytes in packed decimal format (HHMMSS.S). |
21-24 | The input message number assigned by IMS/ESA is contained in these bytes in IB4. (full-word binary) format. |
25-32 | These bytes contain the Message Output Descriptor (MOD) name. An MOD name is connected to this PCB if Message Format Services (MFS) is used. If MFS is not used, there is no MOD, and this field is blank. |
33-40 | These bytes contain the User identification data. The contents vary according to the source of the message |
If a DL/I call uses a TP PCB, the data in the PCBF= variable are formatted as shown in Format of TP PCB Feedback Data.
Bytes | Description |
---|---|
1-8 | These bytes of the PCBF= variable contain the name of the destination associated with the PCB. |
9-10 | These bytes are reserved for IMS/ESA usage. |
11-12 | These bytes contain the DL/I status code. The status code may also be obtained by specifying the STATUS= option in the DL/I INFILE statement. |
OS/390 DL/I System Calls |
Summary of Non-Database Access Calls summarizes the functions and region types for non-database access calls that are supported by the IMS-DL/I DATA step interface.
Function | Purpose | Valid Region Types | Notes |
---|---|---|---|
CHKP | create the synchronization point, recovery purposes | all IMS-DL/I DATA step interface region types | OS/VS option not supported. In transaction-processing BMPs, next call must be GU using I/O PCB. |
CHNG | change destination for messages | IMS/ESA BMP regions | sets the destination for a modifiable TP PCB |
CMD | issue IMS/ESA commands from a program | IMS/ESA BMP regions | when CC status returned, must next issue GU to retrieve response |
DEQ | release a class of segments enqueued with the Q command code | IMS/ESA BMP regions | specify class (A-J) of segments to dequeue |
FLD | access fields in MSDBs | IMS/ESA BMP regions | Fast Path Facility only |
GCMD | retrieve additional response segments to a command if more than one | IMS/ESA BMP regions | functions as a GN to the queue after first response segment retrieved with GU |
GN | retrieve additional segments of a message with more than one segment | IMS/ESA BMP regions | uses I/O PCB |
GU | retrieve the first segment of a message | IMS/ESA BMP regions | uses I/O PCB |
ISRT | format and send message segment to the queue | IMS/ESA BMP regions | uses I/O or TP PCB |
LOG | insert a record to the DL/I system log | MVS DL/I regions | uses I/O PCB |
POS | return position information from DEDBs | IMS/ESA BMP regions | Fast Path Facility only. |
PURG | terminate the current message being inserted; optionally, insert the first segment of the next message | IMS/ESA BMP regions | uses TP PCB |
ROLB | back out database updates since last sync point | IMS/ESA BMP regions and batch DL/I regions in IMS/ESA Release 3 | in BMP regions, also back out messages inserted to the queue since the last synchronization point. Next call must be GU using I/O PCB if ROLB requested return of previous message. |
ROLL | back out database updates since last sync point, and abend | IMS/ESA BMP regions, batch DL/I regions in IMS/ESA Release 3, and CICS/VS shared DL/I regions | in BMP regions also back out messages inserted to the queue since the last synchronization point |
A LOG call inserts user log records in the DL/I log with the I/O PCB (see I/O PCBs). To insert a log record, you must specify
In an IMS-DL/I DATA step program, the LOG call is issued with the DL/I PUT statement. The PUT statement must format the log record
being inserted. The following statements from a sample program insert a log record with a code of
'A0'x
in the IMS log. The example can be run using the SAS system options IMSREGTP=DLI or IMSREGTP=BMP:
data _null_; infile acctsam dli call=func pcb=pcbindex status=st; file acctsam dli; func = 'LOG '; pcbindex = 1; ll = 23; zz = '0000'x; logcode = 'A0'x; logsegm = 'Text of Log Record'; put @1 ll pib2. @3 zz @5 logcode @6 logsegm; if st ¬= ' ' then do; file log; put _all_; abort; end; stop; run;
After the LOG call, you can check the values of the STATUS= variable and _ERROR_ to see whether the call was successful. If _ERROR_=0, the log record was inserted properly. Otherwise, the STATUS= variable contains an error code that indicates why the call was not successful.
If the PSB is generated with LANG=PLI, then the PUT statement must be modified because the LL field has a 4-byte length:
put @1 ll pib4. @5 zz @7 logcode @8 logsegm;
The value of the LL variable does not change.
In an online access region, the ROLL call has two purposes:
The ROLL call performs the same functions in a batch DL/I region if the following conditions are present:
Otherwise, the ROLL call in a batch DL/I region only causes the program to abend with a user 0778 completion code. In this latter case, the database back-out utility must be run with the log data set in order to back out any database updates made since the last program synchronization point.
The following example shows statements that issue a ROLL call. This example is run using the SAS system option IMSREGTP=DLI:
data _null_; infile acctsam dli call=func pcb=pcbindex status=st; file acctsam dli; func = 'ROLL'; pcbindex = 1; put; if st ¬= ' ' then do; file log; put _all_; abort; end; stop; run;
A ROLB call is used in a batch DL/I region to back out any DL/I database updates that have been made since the last program synchronization point. ROLB differs from the ROLL call because it does not cause an 0778 abend. The ROLB call requires use of the I/O PCB (see I/O PCBs).
The ROLB call can be issued in batch DL/I regions if
Otherwise, the ROLB call can be issued only from an IMS/ESA BMP region, as described in IMS/ESA Message Queue Access.
The following sequence of SAS statements issues a ROLB call. This example is run using the SAS system options IMSREGTP=DLI and IMSDLBKO=Y:
options imsdlbko=y; data _null_; infile acctsam dli call=func pcb=pcbindex status=st; file acctsam dli; func = 'ROLB'; pcbindex = 1; put; if st ¬= ' ' then do; file log; put _all_; abort; end; stop; run;
The ROLB call has been successfully executed if _ERROR_=0 after the call; otherwise, you can check the value of the STATUS= variable to see why the call did not complete successfully.
IMS/ESA BMP System Calls |
data _null_; infile tranpsb dli call=func pcb=pcbindex status=st; file tranpsb dli; func = 'DEQ '; pcbindex = 1; put @1 'A'; if st ¬= ' ' then do; file log; put _all_; abort; end; stop; run;
The call has been successfully executed if _ERROR_=0 after the call. Otherwise, the STATUS= variable contains a status code that indicates the reason for the
failure.
Examples 1 to 3 are run using the SAS system options IMSREGTP=BMP and IMSBPIN=trancode. Example 1 shows a sequence of SAS statements that issue a ROLB call.
options imsbpin=trancode; data _null_; infile acctsam dli call=func pcb=pcbindex status=st; file acctsam dli; func = 'ROLB'; pcbindex = 1; put; if st ¬= ' ' then do; file log; put _all_; abort; end; stop; run;
The call has been successfully executed if _ERROR_=0 after the call. Otherwise, the ST variable contains a status code that indicates the reason for the failure.
If the ROLB call is issued in a BMP transaction processing program and the DL/I PUT statement issuing the call formats non-blank data in columns 1 through 6, the call also returns the first segment of the previous message. Any non-blank data can be written in columns 1 through 6 of the output buffer.
When these conditions are fulfilled, the IMS-DL/I DATA step interface saves the returned message segment. The next call must be a GU that uses the I/O PCB. The DATA step interface intercepts the GU call when the INPUT statement executes, so the call is not actually issued. Instead, the returned segment is moved to the input buffer where it can be read.
Example 2 shows a sequence of SAS statements that issue a ROLB call and then a GU call with the I/O PCB:
/* put a message in the queue */ data _null_; infile tranpsb dli call=func pcb=pcbindex status=st; file tranpsb dli; func = 'ISRT'; pcbindex = 2; ll = 33; zz = '0000'x; msgsegm = 'trancode Message for Example # 2.'; put @1 ll pib2. @3 zz @5 msgsegm; if st ¬= ' ' then do; file log; put _all_; abort; end; stop; run; data _null_; infile acctsam dli call=func pcb=pcbindex status=st; pcbindex = 1; file acctsam dli; func = 'ROLB'; put @1 'SAVEIO'; if st ¬= ' ' then if st = 'QC' then _error_ = 0; else link abendit; func = 'GU '; input @; if st = ' ' then _error_ = 0; else link abendit; stop; abendit: file log; put _all_; abort; run;
Example 3 shows a sequence of SAS statements that issue a ROLB call and with no GU call to the message queue:
data _null_; infile acctsam dli call=func pcb=pcbindex status=st; file acctsam dli; func = 'ROLB'; pcbindex = 1; put @1 'SAVEIO'; if st ¬= ' ' and st ¬= 'QC' then link abendit; return; abendit: file log; put _all_; abort; run; options imsbpin=*;
The message segment has been successfully moved if _ERROR_=0 after the INPUT statement executes.
If the PUT statement above is changed to
PUT;
, the message segment would not be returned by the ROLB call.
A SAS program that executes in a BMP region can insert commands to IMS/ESA with the CMD call if
The CMD call is issued by a PUT statement and uses the I/O PCB.
For example, the following sequence of SAS statements issues the
'/START DB ACCTDBD. '
command. This example is run using the SAS system options IMSREGTP=BMP and IMSBPIN=trancode :
options imsbpin=trancode; data _null_; infile tranpsb dli call=func pcb=pcbindex status=st; file tranpsb dli; func = 'CMD '; pcbindex = 1; ll = 23; zz = '0000'x; put @1 ll pib2. @3 zz @5 '/START DB ACCTDBD. '; if st ¬= ' ' then do; file log; put _all_; abort; end; run; options imsbpin=*;
If _ERROR_=0 after the call, the command was issued properly. If a blank STATUS= code is returned, the command may have completed or it may be in progress, depending on the IMS/ESA command issued.
If a CC status code is returned, the command returned a response message to the output buffer and the IMS-DL/I DATA step interface saved the response. To retrieve the response, the next call must be a GU that uses the I/O PCB, as is done after CHKP and ROLB calls in the IMS-DL/I DATA step interface. If subsequent response segments are queued, a CC status code is returned as a result of the GU call. The program can issue GCMD calls (see GCMD Call) to retrieve the subsequent response segments.
See the IBM publication IMS/ESA: Application Programming: EXEC DLI Commands for CICS and IMS for more information on the CMD call.
If the PSB is generated with LANG=PLI, the format specified for the LL field must be changed to PIB4.:
put @1 ll pib4. @5 zz @7 '/START DB D1MK0001.';
However, the value of the LL variable does not change.
The following sequence of statements issues a GCMD call. This example is run using the SAS system options IMSREGTP=BMP and IMSBPIN=trancode :
data _null_; infile tranpsb dli call=func pcb=pcbindex status=st; func = 'GU '; pcbindex = 1; input @; if st = 'CC' then do; func = 'GCMD'; input @; if st = ' ' or st = 'QD' then do; _error_ = 0; stop; end; else link abendit; end; else if st = 'QC' then do; _error_ = 0; stop; end; else link abendit; return; abendit: file log; put _all_; abort; run; options imsbpin=*;
If _ERROR_=0 after the call, the next response segment is in the input buffer. If a QD status code is returned, there are no more response segments for this response.
IMS/ESA Message Queue Access |
See the IBM publication IMS/ESA: Application Programming: EXEC DLI Commands for CICS and IMS for more information about
IMS/ESA data communications programming. This section describes the use of an IMS-DL/I DATA interface to issue DL/I message queue access calls.
To retrieve message segments for transaction processing, an IMS-DL/I DATA step interface program
To retrieve the first segment of any message, use a GU call. To retrieve subsequent segments of the same transaction message, issue a GN call. You can use the same sequence of SAS statements that issued a GU call for the first segment of a message, but the value of FUNC must be changed to GN. (For more information on GU and GN calls, see Summary of Non-Database Access Calls in OS/390 DL/I System Calls.)
In this example, change trancode in the OPTIONS statement to a valid transaction code at your site. This example is run using the SAS system options IMSREGTP=BMP and IMSBPIN=trancode :
options imsbpin=trancode; data _null_; infile acctsam dli call=func pcb=pcbindex status=st; func = 'GU '; pcbindex = 1; input @; if st = ' ' then do; func = 'GN '; do while (st = ' '); input @; if st ¬= ' ' then if st = 'QD' then do; _error_ = 0; stop; end; else link abendit; end; end; else if st = 'QC' then do; _error_ = 0; stop; end; else link abendit; stop; abendit: file log; put _all_; abort; run; options imsbpin=*;
A transaction message segment has been successfully retrieved if _ERROR_=0 or if the STATUS= variable is blank after the call. If _ERROR_ does not equal 0, check the value of the STATUS= variable. When _ERROR_=1 and ST='QC' or ST='QD', there are no more messages in the queue. To find out if there are more messages in the queue, issue another GU call.
The format of a retrieved message segment in the SAS input buffer differs depending on the language that generated the PSB. If an Assembler PSB is used, the message segment is formatted as shown in Assembler PSB Input Buffer Message Segment Format.
Bytes | Description |
---|---|
1-2 | These bytes of the SAS buffer contain a value that is the length of the segment data plus 4 (2 for the LL field and 2 for the ZZ field) in the PIB2. format. |
3-4 | These bytes contain the ZZ fields and are reserved for IMS usage. |
5-n | The segment data begin at byte 5. If this is the first segment of the message, the transaction code (up to 8 bytes in length) is in the first bytes of the message data. |
If a PL/I PSB is used, the message segment is formatted as shown in PL/I PSB Input Buffer Message Segment Format.
Bytes | Description |
---|---|
1-4 | These bytes of the SAS buffer contain a value that is the length of the segment data plus 4 (2 for the LL field and 2 for the ZZ field) in the PIB4. format. (The length here will be 2 bytes less than the total message segment.) |
5-6 | These bytes contain the ZZ fields and are reserved for IMS usage. |
7-n | The segment data begin at byte 7. If this is the first segment of the message, the transaction code (up to 8 bytes in length) is in the first bytes of the message data. |
The following SAS statements insert a message segment. This example uses the second PCB in the PSB, which is assumed to be a TP PCB. In this example, change trancode in the OPTIONS statement to a valid transaction code at your site. This example is run using the SAS system options IMSREGTP=BMP and IMSBPIN=trancode :
options imsbpin=trancode; data _null_; infile tranpsb dli call=func pcb=pcbindex status=st; file tranpsb dli; func = 'ISRT'; pcbindex = 2; ll = 35; zz = '0000'x; msgsegm = 'trancode Text of Message Segment'; put @1 ll pib2. @3 zz @5 msgsegm; if st ¬= ' ' then do; file log; put _all_; abort; end; stop; run; data _null_; infile acctsam dli call=func pcb=pcbindex status=st; func='GU '; pcbindex= 1; input @; if st ¬= ' ' then if st = 'QC' then do; _error_ = 0; stop; end; else do; file log; put _all_; abort; end; stop; run; options imsbpin=*;
If _ERROR_=0 after the ISRT call, the segment was inserted properly. Otherwise, the STATUS= variable contains a status code that indicates why the call was not successful.
If the PSB is generated with LANG=PLI, the PUT statement must be modified because the length of the LL field is 4 bytes. For example:
put @1 ll pib4. @5 zz @7 msgsegm;
The value of the LL variable does not change.
SSA1='#MODNAME=DFSMO4';
This causes the message to be formatted with the MOD DFSMO4. The
SSA1=' ';
statement should follow the first DL/I PUT so that the MOD is not re-specified on ISRT calls for subsequent message segments.
When you insert more than one message to the same destination, you can use a PURG call to terminate the current message and to insert the first segment of the next message. You issue the PURG call with a PUT statement that formats the first segment of the message to be inserted.
For example, consider the following SAS statements:
data _null_; infile tranpsb dli call=func pcb=pcbindex status=st; file tranpsb dli; func = 'PURG'; pcbindex = 2; ll = 27; zz = '0000'x; msgsegm = 'Text of Message'; put @1 ll pib2. @3 zz @5 msgsegm; if st ¬= ' ' then do; file log; put _all_; abort; end; stop; run;
The PCBNDX variable is set to 2, so that a TP PCB is used. The values of the LL and ZZ fields are set by assignment statements, and then the message segment text is specified. Notice that the PUT statement, which issues the PURG call, formats the output buffer just as if this were an ISRT call. This example is run using the SAS system option IMSREGTP=BMP.
If you want to change the MOD, use an SSA variable, as described in ISRT Calls to Message Queues.
When you insert messages to different destinations with one TP PCB, you cannot use the PURG call to insert the first segment of the next message. Instead, you should
PUT;
CHNG Call to TP PCBs shows an example of this sequence of calls. Remember
that you must use a modifiable TP PCB in order to change destination between calls.
For example, the following SAS statements issue a CHNG call to set the destination of the third PCB in the PSB to destname, where destname must be a valid IMS/ESA transaction code or logical terminal name. This example is run using the SAS system option IMSREGTP=BMP:
data _null_; infile tranpsb dli call=func pcb=pcbindex status=st; file tranpsb dli; func = 'CHNG'; pcbindex = 3; put @1 'destname'; if st ¬= ' ' then do; file log; put _all_; abort; end; stop; run;
The destination has been changed successfully if _ERROR_=0 after the call. Otherwise, the STATUS= variable contains a status code that indicates the reason for the failure.
If a modifiable TP PCB is used to send messages to more than one destination, the PURG call must be used to complete the current message prior to issuing a CHNG call to alter the destination for a new message. The following example shows the PURG, CHNG, and ISRT call sequence. It is run using the SAS system option IMSREGTP=BMP:
data _null_; infile tranpsb dli call=func pcb=pcbindex status=st; file tranpsb dli; func = 'PURG'; pcbindex = 3; put; if st = ' ' then do; func = 'CHNG'; put @1 '<destname>'; if st = ' ' then do; func = 'ISRT'; ll = 27; zz = '0000'x; msgsegm = 'Text of Message Segment'; put @1 ll pib2. @3 zz @5 msgsegm; if st = ' ' then stop; else link abendit; end; else link abendit; end; else link abendit; return; abendit: file log; put _all_; abort; run;
In the above example, the PCBINDEX variable points to the third PCB, which is a modifiable TP PCB. The PURG call is issued by a PUT statement. Because this PURG call only terminates the current message and does not insert a message segment, the PUT statement has no specifications. If _ERROR_=0, the PURG call is successful and the program goes on to issue a CHNG call. The destination specified for the TP PCB is changed.
If the CHNG call is successful, a message segment is built and an ISRT call is issued. The PUT statement issuing the ISRT call formats the output buffer.
FOOTNOTE 2: This is not the call sequence that would be used if programming in PL/I, COBOL, or Assembler, but it is consistent with the actions taken by DL/I after a CHKP call.
FOOTNOTE 3: IMS/ESA: Application Programming: EXEC DLI Commands for CICS and IMS, an IBM publication, describes the PCB mask data.
FOOTNOTE 4: Although a message queue call does not use an SSA, it is provided as a way to specify the MOD.
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.