DATA Step Statement Extensions

Overview of DATA Step Extensions

In a DATA step, the SAS/ACCESS interface to IMS uses special extensions of standard SAS INFILE and FILE statements to access DL/I resources. These extended statements are referred to as the DL/I INFILE and DL/I FILE statements, and their corresponding INPUT and PUT statements are referred to as DL/I INPUT and DL/I PUT statements.
DL/I INFILE and DL/I INPUT statements work together to issue DL/I get calls. The DL/I INFILE, DL/I FILE, and DL/I PUT statements work together to issue DL/I update calls.
The DL/I INFILE statement tells SAS where to find the parameters needed to build DL/I calls. Special DL/I INFILE statement extensions perform the following tasks:
  • Name the PSB.
  • Specify a SAS variable or a number that selects the appropriate PCB in the PSB.
  • Specify a SAS variable that contains DL/I call functions (for example, GN or REPL).
  • Specify SAS variables that contain SSAs for the DL/I call.
  • Name SAS variables to contain information returned by the call, such as the status code and retrieved segment name.
The DL/I INFILE statement is necessary to identify the parameters for a call. However, the call is not actually formatted and issued until a DL/I INPUT statement is executed for get calls or DL/I FILE and DL/I PUT statements are executed for update calls.
The DL/I INFILE statement is required in any DATA step that accesses a DL/I database because the special extensions of the DL/I INFILE statement specify variables that set up the DL/I calls. When a DL/I INFILE statement is used with a DL/I INPUT statement, get calls are issued. When a DL/I INFILE statement is used with DL/I FILE and DL/I PUT statements, update calls are issued. Both get and update calls can be issued in one DATA step.
The syntax and use of the DL/I INFILE, DL/I FILE, DL/I INPUT, and DL/I PUT statements are described in detail later in this section.

DL/I Input and Output Buffers

Two separate buffers are allocated by SAS as I/O areas for data transfer. The input buffer is for DL/I segments retrieved by get calls. The output buffer is for data written by an update call. The length of each buffer is specified by the LRECL= option in the DL/I INFILE statement. The default length for each buffer is 1,000 bytes.
The input buffer is formatted by DL/I in the same way an I/O area for any DL/I program is formatted. If a fixed-length segment is retrieved, the fixed-length segment begins in column 1 of the input buffer. If a segment of varying length is retrieved, the length field (LL field) in IB2. format (half-word binary) begins in column 1 and the varying-length segment data follows immediately. If a path of segments is retrieved, the buffer contains the concatenated segments.
The format of the output buffer is like of the input buffer. If a fixed-length segment is written, the fixed-length segment begins in column 1 of the output buffer. If a varying-length segment is written, the length field in IB2. format (half-word binary) begins in column 1. The varying-length segment data immediately follows the length field. If a path of segments is written, the buffer contains the concatenated segments.
The segment data format in the output buffer is determined by the DL/I PUT statement and must match the original segment data format. See Using the DL/I PUT Statement for more information about how to format segment data in the output buffer.
The format of the data in a segment is determined by the application program that wrote the data segment originally, just as the data format in any other record is determined by the program that writes the record. When you write an IMS DATA step program you must know the segment's format in order to read data from the segment with a DL/I INPUT statement or to write data to the segment with a DL/I PUT statement.
In most cases, you are probably not the person who originally determined the segment data format. Segment data format information is stored in different ways at different installations. For example, the information can be obtained from a data dictionary, COBOL or Assembler copy libraries, source programs, a SAS macro library, or other documentation sources. DBA staff at your installation can help you find the segment data formats you need.

An Introductory Example of a DATA Step Program

The following example is a simple IMS DATA step program that reads segments from a DL/I database and creates a SAS data set from data in the retrieved segments. Next, the program processes the SAS data set with PROC SORT and PROC PRINT.
The example accesses the AcctDBD database with a PSB called ACCTSAM. ACCTSAM contains five PCBs; the second PCB contains a view of the AcctDBD database in which the CUSTOMER segment is the only sensitive segment. See Example Data for information about the databases, PSBs, segments, and fields used in this example and other examples in this document. This example uses the DLI option of the INFILE statement, which tells SAS that the INFILE statement refers to a DL/I database. Other nondefault region and execution parameters in effect include these:
  • The second PCB in the specified PSB is used.
  • Status codes are examined.
Defaults for other region and execution parameters in this example include these:
  • A DL/I region is used.
  • The DL/I calls issued are all GN (get-next) calls.
  • No SSAs are used.
  • Program access is sequential.
  • PCB feedback mask data is not examined.
If you do not want to use these defaults, the special statement and product options that you can specify for IMS are described later in this section.
The numbered comments following this program correspond to the numbered statements in the program:
1  data work.custlist;
2     infile acctsam dli status=st pcbno=2;
3     input @1   soc_sec_number $char11.
           @12  customer_name   $char40.
           @52  addr_line_1     $char30.
           @82  addr_line_2     $char30.
           @112 city            $char28.
           @140 state           $char2.
           @142 country         $char20.
           @162 zip_code        $char10.
           @172 home_phone      $char12.
           @184 office_phone    $char12.;
4    if st ¬= '  ' then
       do;
          file log;
          put _all_;
          abort;
       end;
    run;
5    proc sort data=work.custlist;
       by customer_name;
6    options linesize=132;
    proc print data=work.custlist;
       var home_phone office_phone;
       id customer_name;
       title2 'Customer Phone List';
7    proc print data=work.custlist;
       var addr_line_1 addr_line_2 city 
           state country zip_code;
       id customer_name;
       title2 'Customer Address List';
    run;
1 The DATA statement references a temporary SAS data set called CustList, which is to be opened for output.
2 The INFILE statement tells SAS to use a PSB called ACCTSAM. The DLI option tells SAS that ACCTSAM is a DL/I PSB instead of a fileref. The statement also tells the IMS interface to use the second PCB and to return the DL/I STATUS code in the ST variable.
3 The INPUT statement causes a GN (get-next) call to be issued. The PCB being used is sensitive only to the CUSTOMER segment, so the get-next calls retrieve only CUSTOMER segments. When the INPUT statement executes, data is retrieved from a CUSTOMER segment and placed in the input buffer. The data is then moved to the specified SAS variables in the program data vector (SOC_SEC_NUMBER, CUSTOMER_NAME, and so on).
As the DATA step executes, CUSTOMER segments are retrieved from AcctDBD, and SAS observations that contain the CUSTOMER data are written to the CustList data set. Because program access is sequential, the DATA step stops executing when the DL/I STATUS code indicates an end-of-file condition.
4 The status code is checked for non-blank values. For any non-blank status code except GB, all values from the program data vector are written to the SAS log, and the DATA step is canceled. If the status code variable value is GB, the DATA step terminates with an end-of-file condition if the processing was sequential (using non-qualified SSAs). Since this example uses no SSA, the database is processed sequentially and no check for a status code of GB is required.
5 The SORT procedure sorts the CustList data set alphabetically by customer name.
6 The PRINT procedure first prints a Customer Phone List.
7 The procedure is invoked again to print a Customer Address List.
The following output shows the SAS log for this example.
SAS LOG for Introductory IMS DATA Step Example
12         data work.custlist;
13           infile acctsam dli status=st pcbno=2;
14           input @1   soc_sec_number $char11.
15                 @12  customer_name  $char40.
16                 @52  addr_line_1    $char30.
17                 @82  addr_line_2    $char30.
18                 @112 city           $char28.
19                 @140 state          $char2.
20                 @142 country        $char20.
21                 @162 zip_code       $char10.
22                 @172 home_phone     $char12.
23                 @184 office_phone   $char12.;
24           if st ^= '  ' then
25             do;
26               file log;
27               put _all_;
28               abort;
29             end;
30         

NOTE: The infile ACCTSAM is:
      (system-specific pathname), 
      (system-specific file attributes)

NOTE: GB -End of database encountered
NOTE: 10 records were read from the infile (system-specific pathname).
      The minimum record length was 225.
      The maximum record length was 225.
NOTE: The data set WORK.CUSTLIST has 10 observations and 10 variables.

31         proc sort data=work.custlist;
32           by customer_name;
33         
34         options linesize=132;

NOTE: The data set WORK.CUSTLIST has 10 observations and 10 variables.

35         proc print data=work.custlist;
36           var home_phone office_phone;
37           id customer_name;
38           title2 'Customer Phone List';
39         

NOTE: The PROCEDURE PRINT printed page 1.

40         proc print data=work.custlist;
41           var addr_line_1 addr_line_2 city state country zip_code;
42           id customer_name;
43           title2 'Customer Address List';
44         run;

NOTE: The PROCEDURE PRINT printed page 2.
The following two outputs show the results of this example.
Customer Phone List — Results of Introductory Example
                        Customer Phone List

             customer_name             home_phone     office_phone  
             
             BARNHARDT, PAMELA S.     803-345-4346    803-355-2543
             BOOKER, APRIL M.         803-657-1346                
             COHEN, ABRAHAM           803-657-7435    803-645-4234
             LITTLE, NANCY M.         803-657-3566                
             O'CONNOR, JOSEPH         803-657-5656    803-623-4257
             PATTILLO, RODRIGUES      803-657-1346    803-657-1345
             SMITH, JAMES MARTIN      803-657-3437                
             SUMMERS, MARY T.         803-657-1687                
             WALLS, HOOPER J.         803-657-3098    803-645-4418
             WIKOWSKI, JONATHAN S.    803-467-4587    803-654-7238
Customer Address List — Results of Introductory Example
                                               Customer Address List

                                addr_
       customer_name            line_1    addr_line_2             city              state    country     zip_code
       
       BARNHARDT, PAMELA S.               RT 2 BOX 324           CHARLOTTESVILLE     VA        USA      25804-0997
       BOOKER, APRIL M.                   9712 WALLINGFORD PL.    GORDONSVILLE       VA        USA      26001-0670
       COHEN, ABRAHAM                     2345 DUKE ST.          CHARLOTTESVILLE     VA        USA      25804-0997
       LITTLE, NANCY M.                   4543 ELGIN AVE.         RICHMOND           VA        USA      26502-3317
       O'CONNOR, JOSEPH                   235 MAIN ST.            ORANGE             VA        USA      26042-1650
       PATTILLO, RODRIGUES                9712 COOK RD.           ORANGE             VA        USA      26042-1650
       SMITH, JAMES MARTIN                133 TOWNSEND ST.        GORDONSVILLE       VA        USA      26001-0670
       SUMMERS, MARY T.                   4322 LEON ST.           GORDONSVILLE       VA        USA      26001-0670
       WALLS, HOOPER J.                   4525 CLARENDON RD       RAPIDAN            VA        USA      22215-5600
       WIKOWSKI, JONATHAN S.              4356 CAMPUS DRIVE       RICHMOND           VA        USA      26502-5317