Did you catch that SAS error?
The use of automated scripts have made it extremely important to understand error conditions in a programmatic way. Here are a couple of the ways you can check for errors in your automated SAS scripts.
SYSERR - This macro variable should have a value of 0 (zero) if the data or proc step completed successfully.
data new_ds;
set old_ds;
put something here;
run;
%put NOTE: This step returned a value of $SYSERR;
SYSCC - This is the value that SAS would return to the operating system if it were to exit at that point. You can use this to see if there were errors in your script up until this point. The value of SYSERR is reset upon each data or proc step. However, SYSCC doesn't reset unless the user resets it within the script. This can be useful if you want to force SAS to exit in a success or fail status.
NOTE - It is important to know that it is well documented that both of these variables have flaws. There are conditions that don't trigger errors that might not be intuitive. If you are relying heavily on these variables for code success, you should take a minute to read the SAS documentation around what does and doesn't constitute an error.
SAS command line parameters (sysparm)
Here is one for all your command line junkies out there. And if you aren't a command line junkie, you should consider it. This one is specifically aimed at Unix users. Often we write automated jobs that become very complex. And as we have discussed in the past, can write shell scripts to manage other jobs. There are times when you need to pass a variable to a SAS session without changing the actual SAS script. When this happens, consider SYSPARM.
Sysparm is used to pass variables to the SAS session from the command line. Here is an example:
unixprompt> /somedir/SAS_9.1/sas some_sas_script.sas -SYSPARM "data"
Based on the example above, you can then retrieve the value of SYSPARM in your script the same way you would any other macro variable.
Creating Dynamic Shell Scripts using SAS
Here is one for your collection. This one is a little out of the "basics" realm and into the wierd and unusual.
Let me begin by explaining what this is and what you may use it for. First, this is SAS's ability to write to a file and then execute that file in SAS or on the command line. For my examples, I will be using SAS on Unix. So we tell SAS to output to a file and then give the commands to execute that file.
So, you might ask, why would I use this? Well, my most recent real world example is a nightly refresh of a very large reporting structure. The architecture is as follows. There are a large number of standard reports/tablse that need to be refreshed. I have a SAS project that retrieves the most recent list of refreshes and builds a shell script for each. The code then executes the scripts 10 at a time until all are done. Each script it builds checks the load on the database to ensure we aren't killing it and that we can get a connection for the next round of reports. As the reports complete, we kick off the next round until all are refreshed. This allows the process to "spawn" processes and manage them in a way that is reasonable to the enterprise and database.
So, lets begin by talking about how you create a shell script in SAS. To do this, we will use a dataset in the following syntax:
data _null_;
file test_file.sh;
put "projects=( &proj_list )" ;
put "DATE=/usr/bin/date" ;
put "for num in ${projects[@]}" ;
put "do" ;
put 'echo "working on project number $num - `$DATE`" ' ;
put "done" ;
put 'echo "all work done!" ' ;
run;
After we have successfully created the file, we can now kick it off to run. On a side note, I like to add the output of the file to the current log.
filename kickoff pipe ". /test_file.sh &";
data _null_;
infile kickoff;
input;
put _infile_;
run;
The leading "." on the filename command tells Unix to execute the script regardless of its permissions. The "&" after the filename tells Unix to execute the command outside of this session or screen.
I hope this overly simplistic example is helpful. You can only imagine how complex this can get very quickly. It has been our experience that many organizations are exploiting this to build production systems with SAS. This functionality separates the SAS experts from the "analysts". Using this functionality makes in extremely important to document your code. As you begin to add variables and "include" statements, things get fuzzy very quickly.
If you have a code base that utilizes this functionality and you need assistance, please don't hesitate to let us know. We are ready to help support your organization.