Strange error due to misuse of %sysrput in SAS - sas

I am using AIX 6.1 with SAS 9.1.3
I have a program running in PC SAS 9.1
The program will rsubmit to unix.
Now, I convert the program to be totally running in AIX 6.1
The program fails very strangely.
After investigation, it is due to the %sysrput
Here is a simplified version of the program:
options mPrint mLogic symbolGen ;
%macro combine( startdate= , fullprefix= );
data _null_ ;
call symput( 'plength',compress(length(compress("&fullprefix."))));
run;
data _null_ ;
length balance 8. ;
balance= 1 + &plength.;
run;
%mEnd;
data _null_ ;
call symput( 'refdate', put(today(),date9.));
run;
%put &refdate.;
* -- If I forget to comment out the sysrput, the plength cannot be resolved -- ;
%sysrput refdate=&refdate.;
%put &refdate.;
%combine( startdate= "&refdate."d, fullprefix=a_filename_prefix );
(Sorry that the wordings are not meaningful, I just want to do a demo.)
Actually, in AIX, I should not use %sysrput
I just forget to comment it out.
But, if I forget this, there would be error in the plength macro variable in the balance= statement. This is very strange.
To solve, simply comment out the %sysrput is ok.
But, does anyone know why the %sysrput will cause failure in a macro variable in the macro ?
Alvin SIU

It's hard to tell from your simplified version of your question, but if you are asking why the macro variable plength is not present after your macro executes, it is because you must define it as global in your macro code itself. In other words:
%macro combine( startdate= , fullprefix= );
%global plength;
...
%mend;
And yes, if you use the %SYSRPUT command from a SAS session not under control of SAS/CONNECT, you will get a SAS ERROR; and getting a SAS error will put your non-interactive session into "syntax-check" mode, in which case the remaining statements in your program will not execute completely.
This last bit is a common misunderstanding when converting code from a SAS/CONNECT environment to "plain old SAS". When you use SAS/CONNECT, the "server" side of the connection is started with the "-NOSYNTAXCHECK" option.

After investigation with some little testing. maybe this is the answer.
Actually, I will use OPTIONS ERRORABEND in all batch SAS program to stop the SAS in case of error. This works for many errors and functions just perfectly.
The %SYSRPUT statement do give out error message saying ... options DMR ...
But the program does not abend stop here.
It does not give any message saying ... OBS=0 ...
It just go on.
So, I just 'think' that this is some minor error just like LIBNAME a non-exist directory and SAS will continue 'normally'.
(BTW, I think that the SYSRPUT error has turn on SYNTAX CHECK mode silently, without any notification nor hint.)
The next %PUT statement is normal, same value as previous one.
This mislead me that the program is running normally.
The next statements are also normal. There are many SYMBOLGEN, MPRINT and MLOGIC messages.
So, this further mislead me that the program is running very very normally.
After the call symput plength statement, there is a NOTE: Numeric values have been converted ...
This further mislead me the program is running normally.
Until now (after so many look-like normal messages), there is a NOTE saying SAS set option OBS=0 ...
(Maybe this NOTE will appear only after the RUN statement.)
This OBS=0 message is actually the hints which tell SAS is using SYNTAX CHECK mode.
Maybe this OBS=0 is caused by the SYSRPUT error. But, because there are so many look-like normal messages after the SYSRPUT error, I just overlook this OBS=0 message.
Actually, the call symput is so simply and should not cause any error.
This just further complicate the situation.
As SAS is in SYNTAX CHECK mode, this is why causing the look-like error in the plength variable in the balance statement.
This is the whole story.
Anyway, in order to prevent to enter into this complicated and misleading situation, just remember to comment out all the %SYSRPUT will do.

Related

Why is TIMEOUT= argument not recognized within SAS PROC HTTP?

I'm trying to account for missing files at a specific URL. For example, running PROC HTTP to get the following Excel file https://www2.census.gov/programs-surveys/cps/tables/time-series/historical-poverty-thresholds/thresh17.xls runs without timing out, eventually returning a 304 code. The SAS documentation clearly lists TIMEOUT= as an optional argument, but when I try to use it I get a syntax error:
ERROR 22-322: Syntax error, expecting one of the following: ;, AUTH_ANY, AUTH_BASIC, AUTH_NEGOTIATE, AUTH_NONE, AUTH_NTLM, CLEAR_CACHE, CLEAR_CONN_CACHE, CLEAR_COOKIES, CT, EXPECT_100_CONTINUE,
FOLLOWLOC, HEADERIN, HEADEROUT, HEADEROUT_OVERWRITE, HTTP_TOKENAUTH, IN, METHOD, NOFOLLOW, NOFOLLOWLOC, NO_CONN_CACHE, NO_COOKIES, OUT, PROXYHOST, PROXYPASSWORD, PROXYPORT,
PROXYUSERNAME, PROXY_AUTH_BASIC, PROXY_AUTH_NEGOTIATE, PROXY_AUTH_NONE, PROXY_AUTH_NTLM, URL, VERBOSE, WEBAUTHDOMAIN, WEBPASSWORD, WEBUSERNAME.
ERROR 202-322: The option or parameter is not recognized and will be ignored.
Here is my code:
filename resp "C:\response";
proc http
url="https://www2.census.gov/programs-surveys/cps/tables/time-series/historical-poverty-thresholds/thresh17.xls";
method="GET"
out=resp
TIMEOUT=5;
run;
Is there a different way to account for timeout issues within SAS?
Most likely you are not running SAS version 9.4M5.
The 9.4 What's new documentation states in 9.4M5 (September 2017)
PROC HTTP adds a DEBUG statement, the OAUTH_BEARER= procedure option and TIMEOUT= procedure option, and response status macro variables.

SAS SYSCC Macro Variable Behaviour

It is my understanding that if a SAS process hits an error that the value of &SYSCC. will not be 0. which is the success return code. I am writing said variable to a text file to act as a go/no go signal to a Python script that I am using to orchestrate some wider processes.
Whilst testing the behaviour of said variable by triggering some simple, deliberate errors I have noticed that it is still returning zero:
%macro test;
sdsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfs
%put &syscc. **********************************;
%mend;
%test;
Have I misunderstood something?
Thanks
This is a timing issue. No error has been generated at the point at which the %put statement executes. The %test macro generates some text (sdsfsdfs..) and writes a valid put statement. The semicolon after the macro invocation ; creates a statement boundary (sdsfsdf...;) which then throws an error.
Order of execution:
1) compile macro
2) execute macro (%test)
3) execute %put statement
4) send sdsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfs to input stack
5) finish executing macro
6) send final semicolon to input stack (;)
7) sdsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfs; is executed, which likely throws an error (it's too long to be a variable name but could be part of a valid %let statement);

Get the filename and filepath of the code running

I need to get the current running SAS program's name and file path into local variables. I accomplished that using the SAS_EXECFILEPATH and SAS_EXECFILEPATH commands. I ran this through windows SAS and it worked.
But when i tried to run this on the server in batch mode, it failed. I then tried the &_SASPROGRAMFILE parameter, which ran fine on SAS EG, but fails when I trigger it on the server in batch mode.
Is there a possible way to accomplish this in batch mode on the server?
You might be looking for %sysfunc(getoption(sysin)) (Usage Note 24301: How to retrieve the program name that is currently running in batch mode or interactively), if you start the program with sas -sysin path/to/file.sas.
I know this is delayed but you could generate a macro that calls on the right code depending on if you are running the program in the editor or in batch mode. Art Carpenter created a great macro that solves this issue.
%macro ExecPrg;
%if %sysfunc(getoption(sysin)) ne %str() %then %do;
/* Batch Execution */
%sysfunc(getoption(sysin))
%end;
%else %do;
/* Interactive Execution */
%sysget(SAS_EXECFILEPATH)
%end;
%mend execprg;

Conditionally terminate SAS

I am trying to stop the processing of a SAS program if a certain condition has been met. I have a macro variable created and if that variable is > 0.5 then I want a hard stop of the program.
Current program looks like
data a1;
set Server.a2;
run;
%macro1(a1);
%macro2(_t1); /* _t1 generated from %macro1.
data _null_;
if %stopit(_t2) > 0.5 then `?????`; /* _t2 generated from %macro2.
run;
%macro3;
%macro4;
If %macro(_t2) > 0.5, I want to stop of whole program without running the rest (%macro3 and %macro4)
Use following statement:
abort abend;
Personally I tend to always use abort cancel; (or %abort cancel;) as it offers flexibility when running in interactive mode and in batch mode.
Interactively it will just cancel the submitted code (but leave your session open).
In batch mode it will stop the entire job.
There are additional options as well. You can find a full list in the documentation here.
There's also the endsas command but I don't like that as it closes the current interactive session (and it's more difficult to execute conditionally).
Here's an example:
%let x = 1;
data _null_;
if &x then abort cancel;
put "This won't print";
run;
%put This won't print either;
The results in the log will show:
ERROR: Execution terminated by an ABORT CANCEL statement at line 4 column 14.
_ERROR_=1 _N_=1

SAS Apparent symbolic reference PWD not resolved

I have SAS code that reads my password from an external .txtfile and establishes connection with odbc . When i run the following code in SAS, it works fine
filename pw "C:/xxxx";
data _NULL_ ;
infile pw ;
input pw : $50. ;
call symputx('pwd',pwd);
run;
libname xxx odbc user=myUser password=&pwd. dsn=myDsn schema=mySchema;
proc sql;
connect to xxx(dsn=myDsn user=myUser password=&pwd.);
However when I create a batch file to run it from Windows task scheduler or run it from SAS Enterprise Guide I get Apparent symbolic reference PWD not resolved
Why is this happening ? How to deal with this issue ?
Because your call symputx is not correctly defining it, at least based on the code you pasted.
data _NULL_ ;
infile pw ;
input pw : $50. ;
call symputx('pwd',pw);
run;
That would be the correct syntax (or change the input statement to read pwd). Look at your datastep's log, it should have a warning pwd was uninitialized.
If you pasted the code properly, I would still look to your data step's log, and see if any rows were processed. mjsqu may be correct in that you may not have visibility to the directory (if this is on a server and you're not accessing a server-visible directory), or some other issue may present as a result of you being in a different environment.
You have a typo. My guess is that your original variable was named pwd and you tested your code and it ran fine and then you renamed it. If you close your sas session and try rerunning it I bet it fails.
Try changing to this:
filename pw "C:/xxxx";
data _NULL_ ;
infile pw ;
input pw : $50. ;
call symputx('pwd',pw);
run;