Debugging, Testing, and Production Practices
Prerequisites: Macro programs
Debugging the DATA step
- PUTLOG writes to the log from inside a step, without affecting output:
data _null_;
set sashelp.class;
if weight > 130 then putlog 'CHECK: heavy student ' name= weight=;
run;
CHECK: heavy student Name=Philip Weight=150
CHECK: heavy student Name=Ronald Weight=133
putlog _all_;dumps every variable in the PDV, including_N_and_ERROR_— the quickest way to see what a step is really doing.- Test on a small slice first:
options obs=100;limits every step to 100 rows (reset withoptions obs=max;). - SAS Enterprise Guide and SAS Studio in Viya include an interactive DATA step debugger.
Treat the log as a test result
A production program should finish with no errors, no warnings, and no unexpected notes. Watch for these notes in particular:
Missing values were generatedCharacter values have been converted to numeric values(or the reverse)MERGE statement has more than one data set with repeats of BY valuesThe query requires remerging summary statisticsInvalid data for ...
Many teams scan logs automatically for these strings. To stop a batch job
on failure, check &syserr (0 means success) after key steps:
/* illustrative */
%macro check_step;
%if &syserr > 4 %then %do;
%put ERROR: step failed with SYSERR=&syserr - stopping.;
%abort cancel;
%end;
%mend check_step;
Comparing results
PROC COMPARE checks two data sets value by value. In clinical-trial
programming, double programming — two programmers produce the same
output independently, then compare — is standard validation:
proc sort data=sashelp.class out=copy1;
by name;
run;
data copy2;
set copy1;
run;
proc compare base=copy1 compare=copy2;
id name;
run;
Output (abridged):
NOTE: No unequal values were found. All values compared are exactly equal.
When values differ, the report lists each difference by ID value;
criterion= allows small numeric tolerances.
Testing macros and programs
- Write small test data sets with known answers (including missing
values and edge cases) and check results with
PROC COMPAREor%ifassertions. - Keep programs short and single-purpose; call shared code with
%include 'common/setup.sas';or an autocall macro library (options sasautos=('/project/macros' sasautos);). - Use version control (Git) for
.sasfiles — they're plain text, and tools like the Code Diff viewer make reviews easy.
Production habits
- No hard-coded paths or dates in the body — put them in
%letstatements or a setup program at the top. - Explicit librefs on every data set name, so nothing depends on
what happens to be in
WORK. - Declare lengths and formats for new variables.
- Idempotent jobs — rerunning a program should give the same result, not append duplicates.
- Batch runs — schedule with
sas -sysin job.sas -log job.log(or SAS Viya's job scheduler) and archive the logs. - Security — keep database passwords out of programs: use
authentication domains or
PROC PWENCODErather than plain text, and store sensitive data in restricted libraries. - Document — a header comment per program, and comments that explain why.
A final example
/*------------------------------------------------------------
Program : weight_by_sex.sas
Purpose : Mean weight per sex, saved and reported
------------------------------------------------------------*/
%let src = sashelp.class;
proc means data=&src noprint nway;
class sex;
var weight;
output out=work.wt(drop=_type_ rename=(_freq_=n)) mean=mean_wt;
run;
proc print data=work.wt noobs label;
label n = 'Students' mean_wt = 'Mean weight (lb)';
format mean_wt 6.1;
run;
Mean
weight
Sex Students (lb)
F 9 90.1
M 10 109.0
A parameter at the top, explicit names, a saved data set, and labels — small habits that make SAS programs trustworthy.
What's next
Try the Advanced Projects, then read What You Should Know Now — and What's Next for where to go from here.