SAS Rules

Summary of coding rules and checks

The following lists the violations that can be produced by S-Precise while analyzing SAS code. They are broken down below into the categories standards, performance, correctness and other.


Standards

MACRO comments

The comment style

* comment here ;

should not be used in macros.

/* use this style instead */

MVS Line length

Lines longer than 72 characters will not work on MVS.

MACRO start and end

MACRO start and end should match for example:

Deprecated PROC used

A PROC has been used that has been marked as deprecated by SAS.

SAS Code complexity

Cyclomatic complexity
The complexity of SAS code can be measured in much the same way as any other language that provides logical conditions/branches (IF/ELSEIF/ELSE and CASE statements) and loops (FOR/WHILE).
The lower the complexity of a routine the easier it is to test and maintain. A rule of thumb provided by PMD for java is a score of 10 by default.

PROC length
The longer a function or procedure is the more difficult the SAS code is to maintain. A rule of thumb provided by PMD for java is a function length of 100 by default. The higher the cyclomatic complexity the lower this threshold should be. A large function of 200 lines with only one path through the code is very likely to be more maintainable then a function of 100 lines with multiple conditional statements.

Extra long lines

Line length allowed can be set

Missing file header comment

A corporate standard header file can be configured for all SAS source code. This may include author, history or licensing of the source code (proprietary versus opensource).

Unused Macro/Variable/Data

SAS code has been found that appears to be “dead” ie a MACRO, variable or data has been declared that is never or referenced. This could mean that the code has a spelling mistake and that declared variable should have been used, or could indicate old logic and the code may be able to be removed.

Keywords in UPPERCASE

Keywords should be in UPPERCASE to make the code more readable.


Performance

Broad SELECT

Avoid using “SELECT *” from the code as it could result in needlessly large data sets being loaded and affect performance and scalability.


Correctness

DO LOOP without a change in the exit condition

Helps protect against infinite loops.

RANDOM function parameters

Check that the parameters to the RANDOM function are consistent.

Code following a QUIT

Code following a QUIT statement may or may not run and is ambiguous.

PROC plot;
plot can2*can1=spec_no;
QUIT;

PROC plot;
plot can3*can1=spec_no2;

RUN; is not last line of program/file

If RUN; is not the last line of the file, then the last few lines of code may not be executed.

PROC aceclus data=sashelp.iris out=ace p=.02 outstats=score;
var SepalLength SepalWidth PetalLength PetalWidth ;
run

PROC parameters not valid

In built procs have a limited set of allowed parameters.
When parameters are incorrect the program may not be doing what was planned.

PROC aceclus datas=sashelp.iris out=ace p=.02 outstats=score;
var SepalLength SepalWidth PetalLength PetalWidth ;
run;

PROC without RUN

When a RUN doesn’t follow a PROC the code may not be executed.

PROC freq;
tables cluster*species;

PROC freq;
tables cluster*other_species;

JDBC Table/Column not defined

SAS code that makes use of an INSERT/SELECT/UPDATE or DELETE has been found but no matching table has been found in the database schema provided. This code may fail at run-time.