Date: Wed, 16 Aug 2006 15:14:51 -0400
Reply-To: Joe Whitehurst <joewhitehurst@GMAIL.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Joe Whitehurst <joewhitehurst@GMAIL.COM>
Subject: Re: can SAS be stopped conditionally from executing last part of
a code file in open code ?
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
If I understand what you want correctly, I believe you can achieve
exactly the effect you want with SAS Component Language. You can
conditionally halt executing SAS code without terminating your DMS
session. Every SAS code step (even every word (token) in the SAS
code) can actually be placed in a different SUBMIT--ENDSUBMIT block.
After every SUBMIT--ENDSUBMIT block, control returns to SCL where you
can take any action you wish including conditionally halting the SAS
code. If an error occurs in the SAS code, the log will show your
exactly where it occurred.
On 8/16/06, Dorfman, Paul <email@example.com> wrote:
> I do not know what started it all, but my issue is simple. In batch, I can
> generate the ENDSAS statement conditionally after any of the steps
> and thus terminate the program when needed (for instance, based on &syscc,
> among other things). If I do the same running the same program under DMS,
> the generated ENDSAS will terminate not only the submitted program, but the
> DMS session itself. I would like to have a SAS statement (apparently other
> than ENDSAS) that would do just that. Maybe such command already exists as a
> DM command, I do not know - which is why I was asking was was going behind
> the BREAK button, which Rob Workman has shown but has also shown that it
> would be of no use if put as a DM statement between steps.
> As to whether serious things should be run in batch, I agree but my client
> (and this is not the first one) runs interactive, and that it that. I have
> already mentioned that I can enclose the steps above in macro and achieve
> what I want that way. But if one of the steps is a DATA step having a
> run-time error, I want to see where the error actually occurred instead of
> seeing where the macro was invoked. Then again, I can completely eschew the
> macro-controlled execution by writing code to files and including them
> conditionally, for instance, via CALL EXECUTE, in which case SOURCE2 would
> help me observe the generated code and I would have the pointer to the
> error. Richard has mentioned and showed how to conditionally generate
> comments, etc.
> So, this is not that the problem cannot be circumvented. It is just if I had
> a statement called, say, EXIT (and effective only under &sysenv=FORE), I
> would use it conditionally just like we use ENDSAS, that is all. Actually,
> if SAS had interstep GOTO coupled with interstep labels, I would not need
> EXIT, just like %RETURN in the Macro Language was a nice extra, but not
> really necessary since %GOTO and labels had been there already.
> That having been speculated, methinks the simplest solution (coming from
> Cary) would be to make ENDSAS kill the process in batch but stop the
> execution of submitted statements without killing the process (interactive
> DMS session).
> Alternatively, if the Macro Facility were made able to point in the log to
> the offending line where a run-time error should occur, I could take that
> instead. But AFAIK, it has been asked for for a long time, yet the cart is
> still there.
> Kind regards
> Paul Dorfman
> Jax, FL
> +-----Original Message-----
> +From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On
> +Behalf Of charles.harbour@PEARSON.COM
> +Sent: Tuesday, August 15, 2006 5:47 PM
> +To: SAS-L@LISTSERV.UGA.EDU
> +Subject: Re: can SAS be stopped conditionally from executing
> +last part of a code file in open code ?
> +What's really the issue here? I think the origianl poster was
> +just looking
> +for a way to conditionally execute the remainder of his
> +program, based on
> +the results at a certain point in his code. What the question seems to
> +have morphed to is--does sas have an 'Oh S%&t!' button, where
> +you can kill
> +something cleanly that probably shouldn't have been started in
> +the first
> +place? The answer to the second question is--No, because creating that
> +would be nearly impossible.
> +It's my experience that there is no good way to stop something that
> +shouldn't have been started at all. In databases, it can take several
> +times longer to rollback uncommitted work than it did to put
> +it there in
> +the first place. Likewise, recovery from a datastep--say, one
> +that sorts a
> +dataset in place--is not pretty (your data is just gone--have
> +a good cry
> +and get over it). Memory intensive procs have other pratfalls--keeping
> +track of all of those classes in memory is best left to the
> +normal end-proc
> +cleanup--you're begging for pointers to nowhere.
> +The question should be--what's the worst that can happen here?
> + Am I just
> +wasting a few cpu seconds (and maybe some of my productivity)?
> + Then let it
> +go--go get some coffee and visit with your neighbor for a
> +little bit. If
> +you have the potential to trash a dataset, you might should
> +give some more
> +thought to design (creating backup copies, reading from one place and
> +writing to another, etc.) that will not only help prevent
> +disasters, but
> +gives more places to restart from if you do have a problem.
> +There are a couple of different techniques that I've employed
> +in executing
> +code conditionally that I haven't seen yet--one is to generate
> +the code for
> +a job based on some metadata, so that you only execute the
> +steps you need.
> +This is somewhat less efficient if the metadata is not readily
> +but making a job that does exactly what you want (and doesn't
> +do what you
> +don't want) is a powerful thing. And when the first job is
> +finished, you
> +can have it submit the second job (no waiting for submission).
> +The other conditional execution is using condition codes.
> +This is somewhat
> +more kludgy in that you need to evaluate the cond code at the
> +beginning of
> +every step you want to conditionally execute, but has the
> +potential to give
> +you more information about what actually happened (you set the
> +code based on--well, the condition). This is more easily done
> +on big iron,
> +but can be done on pc as well (and needn't be restricted to
> +just sysrc--you
> +can set up your own set of condition code/flags).
> +Neither of these solutions needs to use macros (though cond
> +codes use macro
> +variables, and at least a symget/put or %let) and can be
> +easily implemented
> +with a little bit of practice. The danger there is handling
> +something that
> +you didn't anticipate--what happens to your code/jobstream
> +then? I would
> +recommend creating some overview report that tells you what
> +happened, how
> +many records you did it on, where you put them when you were
> +done, etc., so
> +that you can review it on a regular basis and know if you had
> +a potential
> +problem or not. Not that any of these methods are bulletproof, but it
> +gives you some sense of a warm fuzzy feeling (or not).
> +So--what was the question again?
> Notice: This e-mail message, together with any attachments, contains information of Merck & Co., Inc. (One Merck Drive, Whitehouse Station, New Jersey, USA 08889), and/or its affiliates (which may be known outside the United States as Merck Frosst, Merck Sharp & Dohme or MSD and in Japan, as Banyu) that may be confidential, proprietary copyrighted and/or legally privileged. It is intended solely for the use of the individual or entity named on this message. If you are not the intended recipient, and have received this message in error, please notify us immediately by reply e-mail and then delete it from your system.