BookmarkSubscribeRSS Feed
HeatherNewton
Quartz | Level 8

 

DATA SDATA.LATEST_INSTALLMENT;
   SET _CURR_INSTALLMENT;
   DO UNTIL(_IORC_=%SYSRC(_DSENOM));
      MODIFY SDATA.LATEST_INSTALLMENT KEY=I_CREDIT_CARD_NO;
         SELECT(_IORC_);
             WHEN (%SUSRC(_SOK)) DO;
                IF EFF_TO_DATE= . THEN DO;
                   EFF_TO_DATE = T_EFF_TO_DATE;
                END;
                REPLACE SDATA.LATEST_INSTALLMENT;
              END;
              WHEN(%SYSRC(_DSENOM)) DP;
                _ERROR_=0;
              END;
          OTHERWISE;
      END;
   END;
RUN;

what is this program doing? I have looked up some key command like _IORC_, _DENOM, __SOK, am guessing it is checking if some conditions are fulfilled..

2 REPLIES 2
Kurt_Bremser
Super User

What this program does?

  • it hurts my eyes (all uppercase)
  • it's hard to read (inconsistent indentation)
  • it throws a syntax ERROR (there is no data step statement DP)
  • it will complain about an unresolved macro reference (%SUSRC)

Other than that, it seems to modify dataset latest_installment with values from _curr_installment.

 

For a deeper understanding, I suggest you study the documentation of

%SYSRC Autocall Macro 

MODIFY Statement (particularly the KEY= option)

s_lassen
Meteorite | Level 14

As @Kurt_Bremser correctly remarked, the program calls an unknown and probably non-existing macro called %SUSRC. This is probably a spelling error, my guess is that the call should have been to %SYSRC, like the other two macro calls.

 

What the %SYSCR macro does: It takes a relatively cryptic word token and returns a number, which matches the code in the _IORC_ automatic variable for that token. The meaning of the word tokens can be found here.

 

The meaning of the token _SOK is that the read went OK. The meaning of the token _DSENOM is "No matching observation was found in MASTER data set", meaning that that all the records (if any) for that key have now been read.

 

So the program reads a record from the transaction table (_CURR_INSTALLMENT). It then looks up all the matching records in the master table (SDATA.LATEST_INSTALLMENT). If the EFF_TO_DATE is missing, it is then set to the value of T_EFF_TO_DATE, which presumably (but not necessarily) comes from the transaction table. If the two tables have any other variables in common, the values in the master table are replaced by the values from the transaction table, and the record is written back to the master table (the REPLACE statement).

 

Apart from the fact that the program is all uppercase, which does make some people uncomfortable (I am old enough to remember the times when we used punch-cards, and all the stuff was uppercase, so it does not bother me that much), there is one dangerous error: If something goes wrong when reading the master table (for instance if another user has a lock on the table), the program is caught in an endless loop, and will probably keep writing the same error message until the disk runs full, or the CPU limit for the program is reached (if this is running in batch on a mainframe), or the user presses <CTRL-BREAK>. 

 

I would change the program to something like this:

DATA SDATA.LATEST_INSTALLMENT;
   SET _CURR_INSTALLMENT;
   DO UNTIL(0); /* do forever, we will break out with LEAVE or STOP */
      MODIFY SDATA.LATEST_INSTALLMENT KEY=I_CREDIT_CARD_NO;
         SELECT(_IORC_);
             WHEN (%SYSRC(_SOK)) DO;
                IF EFF_TO_DATE= . THEN DO;
                   EFF_TO_DATE = T_EFF_TO_DATE;
                END;
                REPLACE SDATA.LATEST_INSTALLMENT;
              END;
              WHEN(%SYSRC(_DSENOM)) DP DO;
                _ERROR_=0;
                LEAVE;
              END;
          OTHERWISE DO;
              ERROR_MESSAGE=SYSRC(); /* catch the error message as text */
              STOP; /* halt the data step */
            END;
      END;
   END;
RUN;

Why did I change the LOOP to DO UNTIL(0) (with a LEAVE or STOP statement to break out)? Because it is more efficient, CPU-wise. Then you only check the _IORC_ variable once in each read, not twice, as the original program does.

 

If this data step is part of a larger program, you may want to change the STOP statement to e.g. ABORT CANCEL FILE, so that the following steps are not executed.

 

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 282 views
  • 3 likes
  • 3 in conversation