SAS Error codes/variables

SAS codes (SYSCC, SYSRC, and SYSERR) indicate different log results when SAS programs run in UNIX or PC SAS.  Which is the best or most efficient way to use these codes?

This is how I use SAS macro exit codes in my SAS:

data _null_;
   X "echo &syscc > progerr.txt";

%put syserr= &syserr syscc = &syscc sysrc = &sysrc;

Open in new window

I would like to hear how the rest of you handle SAS exit/return codes?
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Hi there : labradorchik,

The whole point of error codes is to allow conditional processing under program control.

As an example of using various SAS return codes, the following macro
{% DefineLib(ref, path)  }
allocates a library to a defined location.

Essentially it does a
libname ref "path";
but under script control so that it ensures that any calling script won't proceed if the library cannot be allocated for any reason eg network drive not allocated, the folder location deleted, .... Note that it produces a LOG message and returns without failing if the libname already is allocated to a library.  You could easily change this behavior.

It runs in an environment of enterprise guide which does ODS output to HTML. Hence the possible error report is generated into the output stream as HTML.

It is set up as an autocall sas macro which puts a one line note in the log when it is defined (on first use).

/* */
Define a library, if not already defined

%macro DefineLib(ref, path);
%local RC;			%* Return code from SysFunc ;
%local SYSMSGtext;		%* message generayed by SysFunc ;

%* Establish if the library does not exist or cannot be accessed;
%let RC = %sysfunc(libref(&ref));  %* 0 -> assigned, 7006 -> not assigned *;
%let SYSMSGtext = %sysfunc(sysmsg());
%* put &RC &ref &SYSMSGtext;

%if (&RC = 0) %then
	%put NOTE: libname &ref is already defined. Use  libname &ref clear%str(;)  before a new definition.;

	%if (%Qsubstr(&path, 1, 1) ^= %str(%")) and
		(%Qsubstr(&path, 1, 1) ^= %str(%() ) %then
		%let path = "&path";

    %* Regardless set up a display value (left justified) AND with all the double quote values etc masked;
	%let displayPath = %qleft(&path);

	libname &ref &path;
	* Now try again;
	%let RC = %sysfunc(libref(&ref));	%* 0 is good return *;
	%let SYSMSGtext = %sysfunc(sysmsg());
	%if (&RC = 0) %then
		%* put Libname &ref has now been assigned to &path;
		%* Cannot allocate the library ;
        libname &ref clear;         *** Get rid of the bad definition ***;
		%let _STPERROR=1;

		data _null_;
			file print;
			** IN following lines if an html tag is not at the start of line **
			** then SAS converts all internal tags to &lt xxx &gt.!!	**

			put "</pre>";			* SAS encloses output in <pre> and </pre> ;
			put "<h1>Library &ref cannot be accessed</h1>";
			put "<p>";
			put "The library";
			put "<strong> &ref </strong>";
			put " is required by this program and";
            put "<br />";
            PUT "could not be accessed at ";
			put "<strong> &displayPath. </strong>";
			put "</p><p>";
			put "The error code and message encountered was:";
			put "</p><p>";
			put "&RC ~ &SYSMSGtext ";
			put "</p><p>";
			put 'Please contact your local SAS guru,';
			put "  Phone 123 456 789  about this problem.";
			put "</p><p>";
			put "Email: ";
			put "<a href=' reference problem on web page'>";
			put "";
			put "</a>";
			put "</p>";

			put "<pre>";			* SAS encloses output in <pre> and </pre> ;

		options OBS=0;
        %put NOTE: library &ref cannot be allocated to &displayPath Script will now stop;
		data _null_; ABORT; run;


%mend DefineLib;
%put macro DefineLib(ref, path) - Conditionally define library - has been defined;

Open in new window

The usefullness of the return codes is to actually use the return code to conditionally do something  in the macro code.  Just printing out the RC value is a bit lame.


labradorchikAuthor Commented:
ShannonEE, thank you very much for your explanations!!
I had to read a few times to grasp the whole idea behind it. :)
I guess the only question I have is which return error code is most efficient to use?
Hi there abradorchik,

The SAS automatic macro variables SYSCC, SYSERR, SYSRC are all concerned with detecting error under program control.  You can of course just display their values but as I said above the real usage in under program control.

SYSCC is the error code that SAS returns to the OS when SAS completes.  You could set it to be an indicator of how many steps in the your SAS script that were completed successfully, or just a 0 / 1 for OK / not OK.  To be any use you will need to set SYSCC. One safe way is to set it to a value indicating a problem and only resetting it to a value you use as OK at the end of the script.  That way if the script fails for any reason the report will be problem.

SYSERR is the error code that SAS sets each step boundary (eg DATA step, PROC step). 0 indicated no problems, non zero indicates a possible problem.  You can test for non-zero values and take different further action.  Just don't print its value!

SYSRC is the operating system provided value when SAS issues an OS program call using (for instance) the X command or %SYSEXEC macro.  Use this value just like what you would with SYSERR but in this case after the X command or %SYSEXEC macro.

The methods you would use is something like the following at the point in the script that we know there was missing addresses for some customers, but otherwise the update succeeded.

* This SAS update job finished but there is some concern   *
* that the customer update process may not be absolutely   *
* correct as at least 1 customer did not have an addresses *
* Set the return code for OS detection of this "warning"   *
%let SYSCC = 4;

Open in new window

The above code will run both inside and outside of a macro;

proc glm data = survey;
     class     agegroup;
     model  weight = agegroup height / solution clparm alpha=0.99;
     lsmeans agegroup / out=agestats;
%if (&SYSERR > 0) and
      (&catchErrors = 1) %then
        %put NOTE: Detected problem in the regression analysis of the survey data.;
        %put NOTE: After the listing of the survey dataset further process will cease;
        proc print data =survey noobs;

        data _NULL_;
        abort;    *** STOP further processing ***;

* Here we know that the regression *
* worked, we can follow on with    *
* our use of the coefficients.     *

Open in new window

The above code uses %if so that it must be a part of a macro. Note that I have used a macro variable catchErrors which you would set to 0 or 1 depending on your need to catch errors.

Hope this helps.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
labradorchikAuthor Commented:
Hi ShannonEE,
Sorry for the late response but I had to do some testing in order to understand this process fully. Everything now makes sense to me. Thank you very much for all your explanations! I really appreciate your help!!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Unix OS

From novice to tech pro — start learning today.