AFHood Group Blog The thoughtless yammerings of marketing junkies..


Add a timestamp to your SAS log

Of all the languages used for programming, I can't think of many that don't include timestamps in their execution logs. The most notable offender is SAS. The lack to timestamps in the log hinders debugging of long running datasteps and proc sql's.

In order to solve this problem, we use this timestamp macro. We place it before and after every significant step in our code.


Timestamp_log macro


%macro Timestamp_log;
%let actual_time=%sysfunc(putn(%sysfunc(datetime()),datetime22.));
%put *----------------------------------*;
%put Timestamp : &actual_time. ;
%put *----------------------------------*;


SAS Conditional programming – If Then

One of the great things about SAS is the use of Macros and conditional programming. The ability to split the code using If - Then processing allows one piece of code to accomplish many things. Here is the basic syntax for If - Then statements in a SAS macro.

%let error1=;

%if %length(&error1) ~=0 %then

%put WARNING: There is an error!;


%put NOTE: There is no error.;

This is the basic example where you want to process one command given a condition. Lets say that you want to process a whole section of code depending on a single condition. See below:

%let error1=;

%if %length(&error1) ~=0 %then %do;

%put WARNING: There is an error!;

<and any other code you want to run here>



%put NOTE: There is no error.;

<and any other code you want to run here>


Note that the %do command allows you to run a whole block of code. Be sure to include the %end statement at the end of the code block. Also, the %else portion of both examples are completely optional.


Check to see if a dataset exists

One of the checks we do many times in automated jobs is to constantly check to see if files and datasets are where we expect them to be. One of the easiest ways to do this is the macro language. We can use an IF statement with a system function. See below..

/*see if file exists*/

%if %sysfunc(exist(libname.dataset1)) %then %do ;

/*if it is here then*/

proc sql;
select some_data from some_table;


%else %do;
/*if the file does not exist then*/

%put WARNING: The file does not exist! ;

%goto exit;


To review, the above macro snippet checks to see if the dataset is there. If the dataset is there, then it runs a proc sql command. If it is not, it returns a WARNING and then exits.

Let us know if you a project that needs consultation or contract work.


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_;


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!" ' ;


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 ". / &";

data _null_;

infile kickoff;


put _infile_;


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.