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..
What this program does?
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
MODIFY Statement (particularly the KEY= option)
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.
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!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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: