The stop statement is needed in the following data step:
data _null_;
length mname $ 32;
do mname = 'erase.dat', 'erase2.dat';
infile 'c:\mydir\tmp' memvar=mname end=done;
do while (^done);
input x;
put _all_;
end;
end;
stop;
run;
the stop statement is not needed in another data step as following:
data _null_;
length memname $ 1024;
memname = ' ';
infile 'c:\mydir\tmp' memvar=memname end=done;
put memname=;
do while (^done);
input x;
put _all_;
end;
run;
Why?
Thanks a lot.
A datastep has an implicit loop in it. If it can detect another row in a table it will take in the values from the next row and repeat all of the instructions in the datastep again.
In your first example your implicit loop has been replaced with an explicit while loop. As that is the case we do not want it to use the implicit loop and must forcibly stop it.
In the second example we want it to read in the data line by line and are taking advantage of the implicit loop so we don't use a stop statement.
The key point is, the first data step without stop statement run a dead loop, but the second one does not!
I believe astounding is correct here. I didn't fully read the second datastep.
A short answer:
A longer answer:
A long answer:
Result: Because of #7, every time program control passes from the top to the bottom of the step, it reads something from the input files. Thus, the DATA step never detects the situation whereby a full top-bottom execution results in reading nothing; hence, it never stops the step from executing again. STOP prevents this by ending the step after both files have been processed.
As @Astounding has sagely noted, this behavior should be accompanied by the following note in the log:
NOTE: DATA STEP stopped due to looping.
Yet for whatever reason, it doesn't happen when INFILE auto-reads all files from a directory, though it always happens (and should) when INPUT reads from a single file. Methinks it's a bug.
At any rate:
In particular, this:
data _null_ ;
infile whatever end = done ;
do until (done);
input ;
end ;
run ;
will stop when INPUT has attempted to read from the empty file buffer, and no "DATA step stopped due to looping" note will be issued.
Unlike this:
data _null_ ;
infile whatever end = done ;
do while (^ done);
input ;
end ;
run ;
in which case you WILL receive the log note since when DONE=1, the INPUT statement will not be executed. So, if you prefer WHILE, end the step with STOP - or, better still, always do it when you read the entire file explicitly.
Kind regards
Paul D.
Thanks a lot.
@Steve1964 , it looks like you accidentally marked your "thanks" comment as the correct answer, rather than marking Hashman's answer as correct. You should be able to reverse this. Marking the correct answer results in that answer being displayed first after the question.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.